75 os <<
"The size of *p_grid* ("
77 <<
") is not equal to the number of pages of *massdensity* ("
80 throw runtime_error(os.str() );
86 if ( massdensity.
nrows() != lat_grid.
nelem()) {
89 os <<
"The size of *lat_grid* ("
91 <<
") is not equal to the number of rows of *massdensity* ("
94 throw runtime_error(os.str() );
102 if ( massdensity.
ncols() != lon_grid.
nelem()) {
105 os <<
"The size of *lon_grid* ("
107 <<
") is not equal to the number of columns of *massdensity*"
110 throw runtime_error(os.str() );
120 if ( massdensity(j,k,l) != 0.0) empty_flag =
true;
137 const String& pnd_field_file,
145 for (
Index i = 0; i < pfr_lat_grid.
nelem(); i++ )
147 for (
Index j = 0; j < pfr_lon_grid.
nelem(); j++ )
149 if ( pnd_field_raw.
data(i_p, i, j) != 0. )
154 <<
"The particle number density field contained in the file '"
155 << pnd_field_file <<
"'\nis non-zero outside the cloudbox "
156 <<
"or close the cloudbox boundary at the \n"
157 <<
"following position:\n"
158 <<
"pressure = " << pfr_p_grid[i_p]
159 <<
", p_index = " << i_p <<
"\n"
160 <<
"latitude = " << pfr_lat_grid[i]
161 <<
", lat_index = " << i <<
"\n"
162 <<
"longitude = " << pfr_lon_grid[j]
163 <<
", lon_index = " << j <<
"\n"
183 const String& pnd_field_file,
191 for (
Index i = 0; i < pfr_p_grid.
nelem(); i++ )
193 for (
Index j = 0; j < pfr_lon_grid.
nelem(); j++ )
195 if ( pnd_field_raw.
data(i, i_lat, j) != 0. )
200 <<
"The particle number density field contained in the file '"
201 << pnd_field_file <<
"'\nis non-zero outside the cloudbox "
202 <<
"or close the cloudbox boundary at the \n"
203 <<
"following position:\n"
204 <<
"pressure = " << pfr_p_grid[i] <<
", p_index = "
206 <<
"latitude = " << pfr_lat_grid[i_lat]
207 <<
", lat_index = "<<i_lat<<
"\n"
208 <<
"longitude = " << pfr_lon_grid[j]
209 <<
", lon_index = " << j <<
"\n"
229 const String& pnd_field_file,
237 for (
Index i = 0; i < pfr_p_grid.
nelem(); i++ )
239 for (
Index j = 0; j < pfr_lat_grid.
nelem(); j++ )
241 if ( pnd_field_raw.
data(i, j, i_lon) != 0. )
246 <<
"The particle number density field contained in the file '"
247 << pnd_field_file <<
"'\nis non-zero outside the cloudbox "
248 <<
"or close the cloudbox boundary at the \n"
249 <<
"following position:\n"
250 <<
"pressure = " << pfr_p_grid[i]
251 <<
", p_index = " << i <<
"\n"
252 <<
"latitude = " << pfr_lat_grid[j]
253 <<
", lat_index = " << j <<
"\n"
254 <<
"longitude = " << pfr_lon_grid[i_lon]
285 const String& pnd_field_file,
286 const Index& atmosphere_dim,
303 out3 <<
"Check particle number density file " << pnd_field_file
309 for (i_p = 0; pfr_p_grid[i_p] > p_grid[cloudbox_limits[0]]; i_p++)
315 for (i_p = pfr_p_grid.nelem()-1;
316 pfr_p_grid[i_p] < p_grid[cloudbox_limits[1]]; i_p--)
320 if (atmosphere_dim == 1 && (pfr_lat_grid.
nelem() != 1
321 || pfr_lon_grid.
nelem() != 1) )
324 os <<
"The atmospheric dimension is 1D but the particle "
325 <<
"number density file * " << pnd_field_file
326 <<
" is for a 3D atmosphere. \n";
327 throw runtime_error( os.str() );
331 else if( atmosphere_dim == 3)
333 if(pfr_lat_grid.
nelem() == 1
334 || pfr_lon_grid.
nelem() == 1)
337 os <<
"The atmospheric dimension is 3D but the particle "
338 <<
"number density file * " << pnd_field_file
339 <<
" is for a 1D or a 2D atmosphere. \n";
340 throw runtime_error( os.str() );
347 for (i_lat = 0; pfr_lat_grid[i_lat] >
348 lat_grid[cloudbox_limits[2]]; i_lat++)
355 for (i_lat = pfr_lat_grid.
nelem()-1;
356 pfr_lat_grid[i_lat] < lat_grid[cloudbox_limits[3]];
362 for (i_lon = 0; pfr_lon_grid[i_lon] >
363 lon_grid[cloudbox_limits[4]]; i_lon++)
369 for (i_lon = pfr_lon_grid.
nelem()-1;
370 pfr_lon_grid[i_lon] < lon_grid[cloudbox_limits[5]];
376 out3 <<
"Particle number density data is o.k. \n";
396 const String& pnd_field_file,
397 const Index& atmosphere_dim,
407 for(
Index i = 0; i < pnd_field_raw.
nelem(); i++)
409 out3 <<
"Element in pnd_field_raw_file:" << i <<
"\n";
411 pnd_field_file, atmosphere_dim,
412 p_grid, lat_grid, lon_grid, cloudbox_limits, verbosity);
431 if (scat_data_raw.
nelem() != scat_data_meta_array.
nelem())
434 os <<
"The number of elments in *scat_data_raw*\n"
435 <<
"and *scat_data_meta_array* do not match.\n"
436 <<
"Each SingleScattering file must correspond\n"
437 <<
"to one ScatteringMeta data file.";
438 throw runtime_error( os.str());
455 const String& scat_data_meta_file,
459 out2 <<
" Check scattering meta properties file "<< scat_data_meta_file <<
"\n";
461 if (scat_data_meta.
type !=
"Ice" && scat_data_meta.
type !=
"Water" && scat_data_meta.
type !=
"Aerosol")
464 os <<
"Type in " << scat_data_meta_file <<
" must be 'Ice', 'Water' or 'Aerosol'\n";
465 throw runtime_error( os.str() );
487 const String& scat_data_file,
492 out2 <<
" Check single scattering properties file "<< scat_data_file
495 if (scat_data_raw.
ptype != 10 &&
496 scat_data_raw.
ptype != 20 &&
497 scat_data_raw.
ptype != 30)
500 os <<
"Ptype value in file" << scat_data_file <<
"is wrong."
502 <<
"10 - arbitrary oriented particles \n"
503 <<
"20 - randomly oriented particles or \n"
504 <<
"30 - horizontally aligned particles.\n";
505 throw runtime_error( os.str() );
534 os <<
"The temperature values in " << scat_data_file
535 <<
" are negative or very large. Check whether you have used the "
536 <<
"right unit [Kelvin].";
537 throw runtime_error( os.str() );
540 if (scat_data_raw.
za_grid[0] != 0.)
543 os <<
"The first value of the za grid in the single"
544 <<
" scattering properties datafile "
545 << scat_data_file <<
" must be 0.";
546 throw runtime_error( os.str() );
552 os <<
"The last value of the za grid in the single"
553 <<
" scattering properties datafile "
554 << scat_data_file <<
" must be 180.";
555 throw runtime_error( os.str() );
558 if (scat_data_raw.
ptype == 10 && scat_data_raw.
aa_grid[0] != -180.)
561 os <<
"For ptype = 10 (general orientation) the first value"
562 <<
" of the aa grid in the single scattering"
563 <<
" properties datafile "
564 << scat_data_file <<
"must be -180.";
565 throw runtime_error( os.str() );
568 if (scat_data_raw.
ptype == 30 && scat_data_raw.
aa_grid[0] != 0.)
571 os <<
"For ptype = 30 (horizontal orientation)"
572 <<
" the first value"
573 <<
" of the aa grid in the single scattering"
574 <<
" properties datafile "
575 << scat_data_file <<
"must be 0.";
576 throw runtime_error( os.str() );
582 os <<
"The last value of the aa grid in the single"
583 <<
" scattering properties datafile "
584 << scat_data_file <<
" must be 180.";
585 throw runtime_error( os.str() );
588 ostringstream os_pha_mat;
589 os_pha_mat <<
"pha_mat* in the file *" << scat_data_file;
590 ostringstream os_ext_mat;
591 os_ext_mat <<
"ext_mat* in the file * " << scat_data_file;
592 ostringstream os_abs_vec;
593 os_abs_vec <<
"abs_vec* in the file * " << scat_data_file;
595 switch (scat_data_raw.
ptype){
599 out2 <<
" Datafile is for arbitrarily orientated particles. \n";
620 out2 <<
" Datafile is for randomly oriented particles, i.e., "
621 <<
"macroscopically isotropic and mirror-symmetric scattering "
639 out2 <<
" Datafile is for horizontally aligned particles. \n";
660 "Special case for spherical particles not"
662 "Use p20 (randomly oriented particles) instead."
693 const bool include_boundaries)
699 if (include_boundaries){
700 if( ipos <
double( cloudbox_limits[0] ) ||
701 ipos >
double( cloudbox_limits[1] ) )
707 if( ipos <
double( cloudbox_limits[2] ) ||
708 ipos >
double( cloudbox_limits[3] ) )
715 if( ipos <
double( cloudbox_limits[4] ) ||
716 ipos >
double( cloudbox_limits[5] ) )
723 if( ipos <=
double( cloudbox_limits[0] ) ||
724 ipos >=
double( cloudbox_limits[1] ) )
730 if( ipos <=
double( cloudbox_limits[2] ) ||
731 ipos >=
double( cloudbox_limits[3] ) )
738 if( ipos <=
double( cloudbox_limits[4] ) ||
739 ipos >=
double( cloudbox_limits[5] ) )
766 const bool include_boundaries)
772 ppath_step.
gp_lon[np-1],cloudbox_limits,include_boundaries);
807 Numeric p1 = p * exp(-(-dh)/(R*T/(
M*g)));
849 Numeric IWCs100=
min ( iwc,a*pow ( iwc/IWC0,b1 ) );
857 Numeric alphas100=b2-m*log10 ( IWCs100/IWC0 );
864 Numeric Nm1=Ns100*Dm*exp ( -alphas100*Dm );
886 Numeric mul100=amu+bmu*log10 ( IWCl100/IWC0 );
892 Numeric asigma=aasigma+basigma*T;
893 Numeric bsigma=absigma+bbsigma*T;
894 Numeric sigmal100=asigma+bsigma*log10 ( IWCl100/IWC0 );
898 Numeric a2=pow (
PI,3./2. ) *density*sqrt ( 2 ) *exp ( 3*mul100+9./2.*pow ( sigmal100,2 ) ) *sigmal100*pow ( D0,3 ) *Dm;
899 Numeric Nm2=a1/a2*exp ( -0.5*pow ( ( log ( Dm/D0 )-mul100 ) /sigmal100,2 ) );
909 dN = ( dN1+dN2 ) *1e6;
910 if (isnan(dN)) dN = 0.0;
947 la= 12.13 * exp( -0.055*T );
951 la= 0.83 * exp( -0.103*T );
959 mu= -30.93 - 0.472*T;
964 dN = pow( D, mu ) * exp ( -la * D );
966 if (isnan(dN)) dN = 0.0;
997 Numeric B=(alpha/gam)/pow(rc,gam);
1000 Numeric n=A*(pow(r*1e6,alpha)*exp(-B*pow(r*1e6,gam)))*1e6;
1003 if (isnan(n)) n = 0.0;
1017 Numeric B=(alpha/gam)/pow(rc,gam);
1019 Numeric n=A*(pow(r*1e6,alpha)*exp(-B*pow(r*1e6,gam)))*1e6;
1022 if (isnan(n)) n = 0.0;
1047 throw std::logic_error(
"x and y must be the same size");
1055 w[i] = 0.5*(x[i+1]-x[i])*y[i];
1057 else if (i == x.
nelem()-1)
1059 w[i] = 0.5*(x[i]-x[i-1])*y[i];
1062 w[i] = 0.5*(x[i+1]-x[i-1])*y[i];
1099 x[i] = pnd[i]*density[i]*vol[i];
1105 if ( x.sum() == 0.0 )
1116 os<<
"ERROR: in WSM chk_pndsum in pnd_fieldSetup!\n"
1117 <<
"Given mass density != 0, but calculated mass density == 0.\n"
1118 <<
"Seems, something went wrong in pnd_fieldSetup. Check!\n"
1119 <<
"The problem occured at: p = "<<p<<
", lat = "<<lat<<
", lon = "<<lon<<
".\n";
1120 throw runtime_error ( os.str() );
1124 error = xwc/x.sum();
1128 if ( error > 1.10 || error < 0.90 )
1132 out1<<
"WARNING: in WSM chk_pndsum in pnd_fieldSetup!\n"
1133 <<
"The deviation of the sum of nodes in the particle size distribution\n"
1134 <<
"to the initial input mass density (IWC/LWC) is larger than 10%!\n"
1135 <<
"The deviation of: "<< error-1.0<<
" occured in the atmospheric level: p = "<<p<<
", lat = "<<lat<<
", lon = "<<lon<<
".\n";
1141 out2 <<
"PND scaling factor in atm. level (p = "<<p<<
", lat = "<<lat<<
", lon = "<<lon<<
"): "<< error <<
"\n";
1175 x[i] = pnd[i]*density[i]*vol[i];
1179 if ( x.
sum() == 0.0 )
1189 ratio = xwc/x.
sum();
1208 const String& part_string)
1214 part_string.
split ( strarr,
"-" );
1217 part_type = strarr[0];
1219 if ( part_type !=
"IWC" &&
1220 part_type !=
"Snow" &&
1221 part_type !=
"LWC" &&
1222 part_type !=
"Rain" )
1225 os <<
"First substring in " << part_string <<
" must be rather 'LWC', 'IWC', 'Rain' or 'Snow'\n"
1226 <<
"Ckeck input in *part_species*!\n";
1227 throw runtime_error ( os.str() );
1243 const String& part_string)
1248 part_string.
split ( strarr,
"-" );
1250 psd_param = strarr[1];
1252 if ( psd_param !=
"MH97" && psd_param !=
"liquid" && psd_param !=
"H11" )
1255 os <<
"The chosen PSD parametrisation in " << part_string <<
" can not be handeled in the moment.\n"
1256 <<
"Choose either 'MH97', 'H11' or 'liquid'!\n" ;
1257 throw runtime_error ( os.str() );
1274 const String& part_string)
1279 part_string.
split ( strarr,
"-" );
1283 if ( strarr.
nelem() < 3 || strarr[2] ==
"*" )
1289 istringstream os1 ( strarr[2] );
1293 if ( strarr.
nelem() < 4 || strarr[3] ==
"*" )
1299 istringstream os2 ( strarr[3] );