83 os <<
"The size of *p_grid* ("
85 <<
") is not equal to the number of pages of *massdensity* ("
88 throw runtime_error(os.str() );
94 if ( massdensity.
nrows() != lat_grid.
nelem()) {
97 os <<
"The size of *lat_grid* ("
99 <<
") is not equal to the number of rows of *massdensity* ("
102 throw runtime_error(os.str() );
110 if ( massdensity.
ncols() != lon_grid.
nelem()) {
113 os <<
"The size of *lon_grid* ("
115 <<
") is not equal to the number of columns of *massdensity*"
118 throw runtime_error(os.str() );
128 if ( massdensity(j,k,l) != 0.0) empty_flag =
true;
147 const String& pnd_field_file,
155 for (
Index i = 0; i < pfr_lat_grid.
nelem(); i++ )
157 for (
Index j = 0; j < pfr_lon_grid.
nelem(); j++ )
159 if ( pnd_field_raw.
data(i_p, i, j) != 0. )
164 <<
"The particle number density field contained in the file '"
165 << pnd_field_file <<
"'\nis non-zero outside the cloudbox "
166 <<
"or close the cloudbox boundary at the \n"
167 <<
"following position:\n"
168 <<
"pressure = " << pfr_p_grid[i_p]
169 <<
", p_index = " << i_p <<
"\n"
170 <<
"latitude = " << pfr_lat_grid[i]
171 <<
", lat_index = " << i <<
"\n"
172 <<
"longitude = " << pfr_lon_grid[j]
173 <<
", lon_index = " << j <<
"\n"
195 const String& pnd_field_file,
203 for (
Index i = 0; i < pfr_p_grid.
nelem(); i++ )
205 for (
Index j = 0; j < pfr_lon_grid.
nelem(); j++ )
207 if ( pnd_field_raw.
data(i, i_lat, j) != 0. )
212 <<
"The particle number density field contained in the file '"
213 << pnd_field_file <<
"'\nis non-zero outside the cloudbox "
214 <<
"or close the cloudbox boundary at the \n"
215 <<
"following position:\n"
216 <<
"pressure = " << pfr_p_grid[i] <<
", p_index = "
218 <<
"latitude = " << pfr_lat_grid[i_lat]
219 <<
", lat_index = "<<i_lat<<
"\n"
220 <<
"longitude = " << pfr_lon_grid[j]
221 <<
", lon_index = " << j <<
"\n"
243 const String& pnd_field_file,
251 for (
Index i = 0; i < pfr_p_grid.
nelem(); i++ )
253 for (
Index j = 0; j < pfr_lat_grid.
nelem(); j++ )
255 if ( pnd_field_raw.
data(i, j, i_lon) != 0. )
260 <<
"The particle number density field contained in the file '"
261 << pnd_field_file <<
"'\nis non-zero outside the cloudbox "
262 <<
"or close the cloudbox boundary at the \n"
263 <<
"following position:\n"
264 <<
"pressure = " << pfr_p_grid[i]
265 <<
", p_index = " << i <<
"\n"
266 <<
"latitude = " << pfr_lat_grid[j]
267 <<
", lat_index = " << j <<
"\n"
268 <<
"longitude = " << pfr_lon_grid[i_lon]
296 const String& pnd_field_file,
297 const Index& atmosphere_dim,
310 out3 <<
"Check particle number density file " << pnd_field_file
313 if (atmosphere_dim == 1 && (pfr_lat_grid.
nelem() != 1
314 || pfr_lon_grid.
nelem() != 1) )
317 os <<
"The atmospheric dimension is 1D but the particle "
318 <<
"number density file * " << pnd_field_file
319 <<
" is for a 3D atmosphere. \n";
320 throw runtime_error( os.str() );
324 else if( atmosphere_dim == 3)
326 if(pfr_lat_grid.
nelem() == 1
327 || pfr_lon_grid.
nelem() == 1)
330 os <<
"The atmospheric dimension is 3D but the particle "
331 <<
"number density file * " << pnd_field_file
332 <<
" is for a 1D or a 2D atmosphere. \n";
333 throw runtime_error( os.str() );
337 out3 <<
"Particle number density data is o.k. \n";
354 const String& pnd_field_file,
355 const Index& atmosphere_dim,
361 for(
Index i = 0; i < pnd_field_raw.
nelem(); i++)
363 out3 <<
"Element in pnd_field_raw_file:" << i <<
"\n";
365 pnd_field_file, atmosphere_dim,
399 Index n, p_i, lat_i, lon_i;
401 for (n=0; n < pnd_field_raw.
nelem(); n++) {
402 for (p_i=0; p_i < pnd_field_raw[n].data.npages(); p_i++) {
403 for (lat_i=0; lat_i < pnd_field_raw[n].data.nrows(); lat_i++) {
404 for (lon_i=0; lon_i < pnd_field_raw[n].data.ncols(); lon_i++) {
405 v = pnd_field_raw[n].data(p_i, lat_i, lon_i);
411 if ( (p <= p_grid[cloudbox_limits[1]]) ||
412 ( (p >= p_grid[cloudbox_limits[0]]) &&
413 (cloudbox_limits[0]!=0)) ) {
415 os <<
"Found non-zero pnd outside cloudbox. "
416 <<
"Cloudbox extends from p="
417 << p_grid[cloudbox_limits[0]]
419 << p_grid[cloudbox_limits[1]]
420 <<
" Pa, but found pnd=" << v
421 <<
"/m³ at p=" << p <<
" Pa for particle #" << n
423 throw runtime_error(os.str());
428 if (!((lat > lat_grid[cloudbox_limits[2]]) &
429 (lat < lat_grid[cloudbox_limits[3]]))) {
431 os <<
"Found non-zero pnd outside cloudbox. "
432 <<
"Cloudbox extends from lat="
433 << lat_grid[cloudbox_limits[2]]
435 << lat_grid[cloudbox_limits[3]]
436 <<
"°, but found pnd=" << v
437 <<
"/m³ at lat=" << lat <<
"° for particle #" << n
439 throw runtime_error(os.str());
445 if (!((lon > lon_grid[cloudbox_limits[4]]) &
446 (lon < lon_grid[cloudbox_limits[5]]))) {
448 os <<
"Found non-zero pnd outside cloudbox. "
449 <<
"Cloudbox extends from lon="
450 << lon_grid[cloudbox_limits[4]]
452 << lon_grid[cloudbox_limits[5]]
453 <<
"°, but found pnd=" << v
454 <<
"/m³ at lon=" << lon <<
"° for particle #" << n
456 throw runtime_error(os.str());
488 for (
Index k=0; k<part_species.
nelem(); k++ )
490 part_species[k].split ( strarr, delim );
491 if ( strarr.
nelem() > 5 )
494 os <<
"Individual strings in part_species can only contain up to 5\n"
495 <<
"elements, but entry #" << k <<
" contains the following "
496 << strarr.
nelem() <<
":\n" << strarr <<
"\n";
497 throw runtime_error ( os.str() );
500 if ( strarr.
nelem() > 3 && strarr[3] !=
"*" )
502 istringstream os1 ( strarr[3] );
507 os <<
"Sizemin specification can only be a number or wildcard ('*')"
508 <<
", but is '" << strarr[3] <<
"'\n";
509 throw runtime_error ( os.str() );
513 if ( strarr.
nelem() > 4 && strarr[4] !=
"*" )
515 istringstream os1 ( strarr[4] );
520 os <<
"Sizemax specification can only be a number or wildcard ('*')"
521 <<
", but is '" << strarr[4] <<
"'\n";
522 throw runtime_error ( os.str() );
545 if (scat_data_array.
nelem() != scat_meta_array.
nelem())
548 os <<
"The number of elments in *scat_data_array*\n"
549 <<
"and *scat_meta_array* do not match.\n"
550 <<
"Each SingleScattering file must correspond\n"
551 <<
"to one ScatteringMeta data file.";
552 throw runtime_error( os.str());
568 const String& scat_meta_file,
572 out2 <<
" Check scattering meta properties file "<< scat_meta_file <<
"\n";
606 const String& scat_data_file,
611 out2 <<
" Check single scattering properties file "<< scat_data_file
619 os <<
"Particle type value in file" << scat_data_file <<
"is wrong."
621 <<
"10 - arbitrary oriented particles \n"
622 <<
"20 - randomly oriented particles or \n"
623 <<
"30 - horizontally aligned particles.\n";
624 throw runtime_error( os.str() );
650 if (!(0. < scat_data_array.
T_grid[0] &&
last(scat_data_array.
T_grid) < 1001.))
653 os <<
"The temperature values in " << scat_data_file
654 <<
" are negative or very large. Check whether you have used the "
655 <<
"right unit [Kelvin].";
656 throw runtime_error( os.str() );
659 if (scat_data_array.
za_grid[0] != 0.)
662 os <<
"The first value of the za grid in the single"
663 <<
" scattering properties datafile "
664 << scat_data_file <<
" must be 0.";
665 throw runtime_error( os.str() );
671 os <<
"The last value of the za grid in the single"
672 <<
" scattering properties datafile "
673 << scat_data_file <<
" must be 180.";
674 throw runtime_error( os.str() );
680 os <<
"For particle_type = 10 (general orientation) the first value"
681 <<
" of the aa grid in the single scattering"
682 <<
" properties datafile "
683 << scat_data_file <<
"must be -180.";
684 throw runtime_error( os.str() );
690 os <<
"For particle_type = 30 (horizontal orientation)"
691 <<
" the first value"
692 <<
" of the aa grid in the single scattering"
693 <<
" properties datafile "
694 << scat_data_file <<
"must be 0.";
695 throw runtime_error( os.str() );
701 os <<
"The last value of the aa grid in the single"
702 <<
" scattering properties datafile "
703 << scat_data_file <<
" must be 180.";
704 throw runtime_error( os.str() );
707 ostringstream os_pha_mat;
708 os_pha_mat <<
"pha_mat* in the file *" << scat_data_file;
709 ostringstream os_ext_mat;
710 os_ext_mat <<
"ext_mat* in the file * " << scat_data_file;
711 ostringstream os_abs_vec;
712 os_abs_vec <<
"abs_vec* in the file * " << scat_data_file;
718 out2 <<
" Datafile is for arbitrarily orientated particles. \n";
739 out2 <<
" Datafile is for randomly oriented particles, i.e., "
740 <<
"macroscopically isotropic and mirror-symmetric scattering "
758 out2 <<
" Datafile is for horizontally aligned particles. \n";
779 "Special case for spherical particles not"
781 "Use p20 (randomly oriented particles) instead."
813 const bool& include_boundaries,
814 const Index& atmosphere_dim )
817 if (include_boundaries)
821 if( ipos <
double( cloudbox_limits[0] ) ||
822 ipos >
double( cloudbox_limits[1] ) )
825 else if( atmosphere_dim >= 2 )
829 if( ipos <
double( cloudbox_limits[2] ) ||
830 ipos >
double( cloudbox_limits[3] ) )
833 else if( atmosphere_dim == 3 )
837 if( ipos <
double( cloudbox_limits[4] ) ||
838 ipos >
double( cloudbox_limits[5] ) )
848 if( ipos <=
double( cloudbox_limits[0] ) ||
849 ipos >=
double( cloudbox_limits[1] ) )
852 else if( atmosphere_dim >= 2 )
856 if( ipos <=
double( cloudbox_limits[2] ) ||
857 ipos >=
double( cloudbox_limits[3] ) )
860 else if( atmosphere_dim == 3 )
864 if( ipos <=
double( cloudbox_limits[4] ) ||
865 ipos >=
double( cloudbox_limits[5] ) )
894 const bool include_boundaries)
897 assert( cloudbox_limits.
nelem() == 6 );
901 ppath_step.
gp_lon[np-1],cloudbox_limits,include_boundaries);
929 const Index& scat_data_start,
931 const String& part_string,
937 Vector vol_unsorted ( npart, 0.0 );
938 Vector vol ( npart, 0.0 );
940 Vector rho ( npart, 0.0 );
941 Vector pnd ( npart, 0.0 );
951 bool noisy = (psd_param ==
"MH97n");
953 for (
Index i=0; i < npart; i++ )
954 vol_unsorted[i] = ( scat_meta_array[i+scat_data_start].volume );
958 for (
Index i=0; i< npart; i++ )
960 pos = intarr[i]+scat_data_start;
962 vol[i] = ( scat_meta_array[pos].volume );
965 ( scat_meta_array[pos].volume *6./
PI ),
968 rho[i] = scat_meta_array[pos].density;
977 for (
Index p=limits[0]; p<limits[1]; p++ )
979 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
981 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
984 if (IWC_field ( p, lat, lon ) > 0.)
992 dm[i], t_field ( p, lat, lon ),
1004 chk_pndsum ( pnd, IWC_field ( p,lat,lon ), vol, rho,
1005 p, lat, lon, partfield_name, verbosity );
1008 for (
Index i = 0; i< npart; i++ )
1010 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1011 lat-limits[2], lon-limits[4] ) = pnd[i];
1015 for (
Index i = 0; i< npart; i++ )
1017 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1018 lat-limits[2], lon-limits[4] ) = 0.;
1050 const Index& scat_data_start,
1052 const String& part_string,
1058 Vector dmax_unsorted ( npart, 0.0 );
1059 Vector vol ( npart, 0.0 );
1060 Vector dm ( npart, 0.0 );
1061 Vector rho ( npart, 0.0 );
1062 Vector pnd ( npart, 0.0 );
1063 Vector dN ( npart, 0.0 );
1069 for (
Index i=0; i < npart; i++ )
1070 dmax_unsorted[i] = ( scat_meta_array[i+scat_data_start].diameter_max );
1074 for (
Index i=0; i< npart; i++ )
1076 pos = intarr[i]+scat_data_start;
1078 vol[i]= scat_meta_array[pos].volume;
1080 dm[i] = scat_meta_array[pos].diameter_max;
1082 rho[i] = scat_meta_array[pos].density;
1091 for (
Index p=limits[0]; p<limits[1]; p++ )
1093 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
1095 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
1098 if (IWC_field ( p, lat, lon ) > 0.)
1105 dN[i] =
IWCtopnd_H11 ( dm[i], t_field ( p, lat, lon ) );
1122 chk_pndsum ( pnd, IWC_field ( p,lat,lon ), vol, rho,
1123 p, lat, lon, partfield_name, verbosity );
1126 for (
Index i =0; i< npart; i++ )
1128 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1129 lat-limits[2], lon-limits[4] ) = pnd[i];
1134 for (
Index i = 0; i< npart; i++ )
1136 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1137 lat-limits[2], lon-limits[4] ) = 0.;
1170 const Index& scat_data_start,
1172 const String& part_string,
1178 Vector dmax_unsorted ( npart, 0.0 );
1179 Vector vol ( npart, 0.0 );
1180 Vector dm ( npart, 0.0 );
1181 Vector rho ( npart, 0.0 );
1182 Vector pnd ( npart, 0.0 );
1183 Vector dN ( npart, 0.0 );
1190 for (
Index i=0; i < npart; i++ )
1191 dmax_unsorted[i] = ( scat_meta_array[i+scat_data_start].diameter_max );
1195 for (
Index i=0; i< npart; i++ )
1197 pos = intarr[i]+scat_data_start;
1199 vol[i]= scat_meta_array[pos].volume;
1201 dm[i] = scat_meta_array[pos].diameter_max;
1203 rho[i] = scat_meta_array[pos].density;
1230 for (
Index p=limits[0]; p<limits[1]; p++ )
1232 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
1234 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
1237 if (IWC_field ( p, lat, lon ) > 0.)
1244 dN[i] =
IWCtopnd_H13 ( dm[i], t_field ( p, lat, lon ) );
1261 chk_pndsum ( pnd, IWC_field ( p,lat,lon ), vol, rho,
1262 p, lat, lon, partfield_name, verbosity );
1265 for (
Index i =0; i< npart; i++ )
1267 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1268 lat-limits[2], lon-limits[4] ) = pnd[i];
1273 for (
Index i = 0; i< npart; i++ )
1275 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1276 lat-limits[2], lon-limits[4] ) = 0.;
1308 const Index& scat_data_start,
1310 const String& part_string,
1318 Vector dmax_unsorted ( npart, 0.0 );
1319 Vector vol ( npart, 0.0 );
1320 Vector dm ( npart, 0.0 );
1321 Vector rho ( npart, 0.0 );
1322 Vector pnd ( npart, 0.0 );
1323 Vector ar ( npart, 0.0 );
1329 for (
Index i=0; i < npart; i++ )
1330 dmax_unsorted[i] = ( scat_meta_array[i+scat_data_start].diameter_max );
1334 for (
Index i=0; i< npart; i++ )
1336 pos = intarr[i]+scat_data_start;
1338 vol[i]= scat_meta_array[pos].volume;
1340 dm[i] = scat_meta_array[pos].diameter_max;
1342 rho[i] = scat_meta_array[pos].density;
1344 ar[i] = scat_meta_array[pos].aspect_ratio;
1347 vector<Numeric> dm_in;
1349 if (find(dm_in.begin(), dm_in.end(), *it) == dm_in.end())
1350 dm_in.push_back(*it);
1353 vector<Numeric> ar_in;
1355 if (find(ar_in.begin(), ar_in.end(), *it) == ar_in.end())
1356 ar_in.push_back(*it);
1367 os <<
"The *H13Shape* parametrization is only valid for particles with\n"
1368 "a maximum diameter >= to 77 um, the smallest value of *diameter_max* in\n"
1369 "this simulation is " << dm[0] <<
" um and thus to large. Set a new *diameter_max_grid*!\n";
1370 throw runtime_error(os.str());
1373 if (ar_input.
nelem()==1)
1375 out1 <<
"WARNING! Only one unique aspect ratio is used. The parametrization\n"
1376 <<
"*H13* will generate the same result but with less computations\n"
1377 <<
"and thus on a sorter time\n";
1380 if (ar_input[ar_input.
nelem()-1] >= 1)
1383 os <<
"H13Shape is only valid for prolate speheroids\n"
1384 "and cylinders at the moment, i.e for aspect ratios smaller\n"
1385 "than one. The maximum aspect ratio chosen is " << ar_input[ar_input.
nelem()-1] <<
".\n"
1386 "Set a new *aspect_ratio_grid";
1387 throw runtime_error( os.str() );
1399 if (dm_input.
nelem() > 0)
1404 for (
Index p=limits[0]; p<limits[1]; p++ )
1406 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
1408 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
1411 if (IWC_field ( p, lat, lon ) > 0.)
1421 Ar[i] =
area_ratioH13 (dm_input[i], t_field (p, lat, lon ) );
1428 if (dm_input.
nelem() > 1)
1440 for (
Index k=0, j=0; j<pnd_temp.
nelem(); k+=l,j++ )
1442 diff = ar[
Range(k,l)];
1446 Numeric minval = std::numeric_limits<Numeric>::infinity();
1451 if (
abs(diff[i]) < minval)
1453 minval =
abs(diff[i]);
1458 pnd[minpos+k]=pnd_temp[j];
1472 chk_pndsum ( pnd, IWC_field ( p,lat,lon ), vol, rho,
1473 p, lat, lon, partfield_name, verbosity );
1477 for (
Index i =0; i< npart; i++ )
1479 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1480 lat-limits[2], lon-limits[4] ) = pnd[i];
1485 for (
Index i = 0; i< npart; i++ )
1487 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1488 lat-limits[2], lon-limits[4] ) = 0.;
1522 const Index& scat_data_start,
1524 const String& part_string,
1530 Vector dmax_unsorted ( npart, 0.0 );
1531 Vector vol ( npart, 0.0 );
1533 Vector rho ( npart, 0.0 );
1534 Vector pnd ( npart, 0.0 );
1535 Vector dN ( npart, 0.0 );
1539 Vector log_m( npart, 0.0 );
1540 Vector log_D( npart, 0.0 );
1551 for (
Index i=0; i < npart; i++ )
1552 dmax_unsorted[i] = ( scat_meta_array[i+scat_data_start].diameter_max );
1556 for (
Index i=0; i< npart; i++ )
1558 pos = intarr[i]+scat_data_start;
1560 vol[i]= scat_meta_array[pos].volume;
1562 dmax[i] = scat_meta_array[pos].diameter_max;
1567 rho[i] = scat_meta_array[pos].density;
1571 log_D[i]=log(
dmax[i]/D0);
1581 log_m[i]=log(vol[i]*rho[i]);
1594 out2<<
"Mass-dimension relationship m=alpha*(dmax/D0)^beta:\n"
1595 <<
"alpha = "<<alpha<<
" kg \n"
1596 <<
"beta = "<<
beta<<
"\n";
1600 if (
dmax.nelem() > 0)
1605 for (
Index p=limits[0]; p<limits[1]; p++ )
1607 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
1609 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
1612 if (SWC_field ( p, lat, lon ) > 0.)
1620 SWC_field ( p, lat, lon ), alpha,
beta);
1623 if (
dmax.nelem() > 1)
1630 chk_pndsum ( pnd, SWC_field ( p,lat,lon ), vol, rho,
1631 p, lat, lon, partfield_name, verbosity );
1634 for (
Index i =0; i< npart; i++ )
1636 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1637 lat-limits[2], lon-limits[4] ) = pnd[i];
1642 for (
Index i = 0; i< npart; i++ )
1644 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1645 lat-limits[2], lon-limits[4] ) = 0.;
1679 const Index& scat_data_start,
1681 const String& part_string,
1687 Vector dmax_unsorted ( npart, 0.0 );
1688 Vector vol ( npart, 0.0 );
1690 Vector rho ( npart, 0.0 );
1691 Vector pnd ( npart, 0.0 );
1692 Vector dN ( npart, 0.0 );
1696 Vector log_m( npart, 0.0 );
1697 Vector log_D( npart, 0.0 );
1708 for (
Index i=0; i < npart; i++ )
1709 dmax_unsorted[i] = ( scat_meta_array[i+scat_data_start].diameter_max );
1713 for (
Index i=0; i< npart; i++ )
1715 pos = intarr[i]+scat_data_start;
1717 vol[i]= scat_meta_array[pos].volume;
1719 dmax[i] = scat_meta_array[pos].diameter_max;
1721 rho[i] = scat_meta_array[pos].density;
1725 log_D[i]=log(
dmax[i]/D0);
1729 log_m[i]=log(vol[i]*rho[i]);
1741 out2<<
"Mass-dimension relationship m=alpha*(dmax/D0)^beta:\n"
1742 <<
"alpha = "<<alpha<<
" kg \n"
1743 <<
"beta = "<<
beta<<
"\n";
1747 if (
dmax.nelem() > 0)
1752 for (
Index p=limits[0]; p<limits[1]; p++ )
1754 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
1756 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
1759 if (SWC_field ( p, lat, lon ) > 0.)
1767 SWC_field ( p, lat, lon ), alpha,
beta);
1770 if (
dmax.nelem() > 1)
1777 chk_pndsum ( pnd, SWC_field ( p,lat,lon ), vol, rho,
1778 p, lat, lon, partfield_name, verbosity );
1781 for (
Index i =0; i< npart; i++ )
1783 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1784 lat-limits[2], lon-limits[4] ) = pnd[i];
1789 for (
Index i = 0; i< npart; i++ )
1791 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1792 lat-limits[2], lon-limits[4] ) = 0.;
1825 const Index& scat_data_start,
1827 const String& part_string,
1833 Vector dmax_unsorted ( npart, 0.0 );
1834 Vector vol ( npart, 0.0 );
1835 Vector deq ( npart, 0.0 );
1836 Vector rho ( npart, 0.0 );
1837 Vector pnd ( npart, 0.0 );
1838 Vector dN ( npart, 0.0 );
1850 for (
Index i=0; i < npart; i++ )
1851 dmax_unsorted[i] = ( scat_meta_array[i+scat_data_start].diameter_max );
1855 for (
Index i=0; i< npart; i++ )
1857 pos = intarr[i]+scat_data_start;
1859 vol[i]= scat_meta_array[pos].volume;
1861 deq[i] = pow( (6*vol[i]/
PI),(1./3.));
1863 out1<<
"deq["<<i<<
"] = "<<deq[i] <<
"\n";
1869 rho[i] = scat_meta_array[pos].density;
1880 delta_rho=(max_rho-
min(rho))/max_rho;
1882 if (delta_rho >= 0.1)
1885 os <<
"MGD_LWC is valid only for particles with the same\n"
1886 "at least almost the same density. The difference between\n"
1887 " maximum and minimum density must be lower than 10 percent.\n"
1888 "Your difference is " << delta_rho <<
".\n"
1889 "Check your scattering particles";
1890 throw runtime_error( os.str() );
1894 if (deq.
nelem() > 0)
1899 for (
Index p=limits[0]; p<limits[1]; p++ )
1902 out1<<
"p="<<p <<
"\n";
1905 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
1907 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
1910 if (LWC_field ( p, lat, lon ) > 0.)
1917 LWC_field ( p, lat, lon ));
1920 if (deq.
nelem() > 1)
1927 chk_pndsum ( pnd, LWC_field ( p,lat,lon ), vol, rho,
1928 p, lat, lon, partfield_name, verbosity );
1931 for (
Index i =0; i< npart; i++ )
1933 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1934 lat-limits[2], lon-limits[4] ) = pnd[i];
1939 for (
Index i = 0; i< npart; i++ )
1941 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
1942 lat-limits[2], lon-limits[4] ) = 0.;
1974 const Index& scat_data_start,
1976 const String& part_string,
1982 Vector dmax_unsorted ( npart, 0.0 );
1983 Vector vol ( npart, 0.0 );
1984 Vector deq ( npart, 0.0 );
1985 Vector rho ( npart, 0.0 );
1986 Vector pnd ( npart, 0.0 );
1987 Vector dN ( npart, 0.0 );
1998 for (
Index i=0; i < npart; i++ )
1999 dmax_unsorted[i] = ( scat_meta_array[i+scat_data_start].diameter_max );
2003 for (
Index i=0; i< npart; i++ )
2005 pos = intarr[i]+scat_data_start;
2007 vol[i]= scat_meta_array[pos].volume;
2009 deq[i] = pow( (6*vol[i]/
PI),(1./3.));
2013 rho[i] = scat_meta_array[pos].density;
2023 delta_rho=(max_rho-
min(rho))/max_rho;
2025 if (delta_rho >= 0.1)
2028 os <<
"MGD_IWC is valid only for particles with the same\n"
2029 "at least almost the same density. The difference between\n"
2030 " maximum and minimum density must be lower than 10 percent.\n"
2031 "Your difference is " << delta_rho <<
".\n"
2032 "Check your scattering particles";
2033 throw runtime_error( os.str() );
2038 if (deq.
nelem() > 0)
2043 for (
Index p=limits[0]; p<limits[1]; p++ )
2045 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
2047 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
2050 if (IWC_field ( p, lat, lon ) > 0.)
2057 IWC_field ( p, lat, lon ));
2060 if (deq.
nelem() > 1)
2067 chk_pndsum ( pnd, IWC_field ( p,lat,lon ), vol, rho,
2068 p, lat, lon, partfield_name, verbosity );
2071 for (
Index i =0; i< npart; i++ )
2073 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
2074 lat-limits[2], lon-limits[4] ) = pnd[i];
2079 for (
Index i = 0; i< npart; i++ )
2081 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
2082 lat-limits[2], lon-limits[4] ) = 0.;
2114 const Index& scat_data_start,
2116 const String& part_string,
2122 Vector vol_unsorted ( npart, 0.0 );
2123 Vector vol ( npart, 0.0 );
2124 Vector vol_me ( npart, 0.0 );
2125 Vector dve ( npart, 0.0 );
2126 Vector dme ( npart, 0.0 );
2127 Vector rho_snow ( npart, 0.0 );
2128 Vector pnd ( npart, 0.0 );
2129 Vector dN ( npart, 0.0 );
2134 const Numeric rho_water=1000.;
2139 for (
Index i=0; i < npart; i++ )
2140 vol_unsorted[i] = ( scat_meta_array[i+scat_data_start].volume );
2146 for (
Index i=0; i< npart; i++ )
2148 pos = intarr[i]+scat_data_start;
2150 vol[i] = ( scat_meta_array[pos].volume );
2154 ( scat_meta_array[pos].volume *6./
PI ),
2157 rho_snow[i] = scat_meta_array[pos].density;
2160 dme[i] =pow( ( rho_snow[i]/rho_water ),( 1./3. ) )*dve[i];
2163 vol_me=( rho_snow[i]/rho_water )*vol[i];
2179 const Numeric lambda_fac = 25.5*1e2;
2180 const Numeric lambda_exp = -0.48;
2182 const Numeric N0_fac=0.038*1e8;
2186 if (dve.
nelem() > 0)
2191 for (
Index p=limits[0]; p<limits[1]; p++ )
2193 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
2195 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
2198 if (PR_field ( p, lat, lon ) > 0.)
2201 fac = convfac/rho_water;
2204 tPR = PR_field ( p, lat, lon ) *
fac;
2208 N0 = pow(tPR,N0_exp)*N0_fac;
2211 lambda = lambda_fac * pow(tPR,lambda_exp);
2217 dN[i] = N0 * exp(-lambda*dme[i]);
2222 if (dme.
nelem() > 1)
2231 assert(!isnan(lambda));
2234 PWC = rho_water*
PI*N0 / pow(lambda,4.);
2236 p, lat, lon, partfield_name, verbosity );
2240 for (
Index i = 0; i< npart; i++ )
2242 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
2243 lat-limits[2], lon-limits[4] ) = pnd[i];
2247 for (
Index i = 0; i< npart; i++ )
2249 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
2250 lat-limits[2], lon-limits[4] ) = 0.;
2282 const Index& scat_data_start,
2284 const String& part_string,
2290 Vector vol_unsorted ( npart, 0.0 );
2291 Vector vol ( npart, 0.0 );
2293 Vector dve ( npart, 0.0 );
2294 Vector dme ( npart, 0.0 );
2295 Vector rho_snow ( npart, 0.0 );
2296 Vector pnd ( npart, 0.0 );
2297 Vector pnd_old ( npart, 0.0 );
2298 Vector dN ( npart, 0.0 );
2306 const Numeric rho_water=1000.;
2311 for (
Index i=0; i < npart; i++ )
2312 vol_unsorted[i] = ( scat_meta_array[i+scat_data_start].volume );
2318 for (
Index i=0; i< npart; i++ )
2320 pos = intarr[i]+scat_data_start;
2322 vol[i] = ( scat_meta_array[pos].volume );
2326 ( scat_meta_array[pos].volume *6./
PI ),
2330 rho_snow[i] = scat_meta_array[pos].density;
2333 dme[i] =pow( ( rho_snow[i]/rho_water ),( 1./3. ) )*dve[i];
2349 const Numeric lambda_fac = 22.9*1e2;
2350 const Numeric lambda_exp = -0.45;
2352 const Numeric N0_fac=0.025*1e8;
2356 if (dve.
nelem() > 0)
2361 for (
Index p=limits[0]; p<limits[1]; p++ )
2363 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
2365 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
2368 if (PR_field ( p, lat, lon ) > 0.)
2371 fac = convfac/rho_water;
2374 tPR = PR_field ( p, lat, lon ) *
fac;
2379 N0 = pow(tPR,N0_exp)*N0_fac;
2382 lambda = lambda_fac * pow(tPR,lambda_exp);
2387 dN[i] = N0 * exp(-lambda*dme[i]);
2392 if (dme.
nelem() > 1)
2400 assert(!isnan(lambda));
2405 PWC = rho_water*
PI*N0 / pow(lambda,4.);
2407 p, lat, lon, partfield_name, verbosity );
2411 for (
Index i = 0; i< npart; i++ )
2416 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
2417 lat-limits[2], lon-limits[4] ) = pnd[i];
2422 for (
Index i = 0; i< npart; i++ )
2424 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
2425 lat-limits[2], lon-limits[4] ) = 0.;
2453 const Index& scat_data_start,
2455 const String& part_string,
2461 Vector vol_unsorted ( npart, 0.0 );
2462 Vector vol ( npart, 0.0 );
2464 Vector rho ( npart, 0.0 );
2465 Vector pnd ( npart, 0.0 );
2466 Vector pnd_old ( npart, 0.0 );
2467 Vector dN ( npart, 0.0 );
2474 for (
Index i=0; i < npart; i++ )
2475 vol_unsorted[i] = ( scat_meta_array[i+scat_data_start].volume );
2479 for (
Index i=0; i< npart; i++ )
2481 pos = intarr[i]+scat_data_start;
2483 vol[i] = ( scat_meta_array[pos].volume );
2486 ( scat_meta_array[pos].volume *6./
PI ),
2489 rho[i] = scat_meta_array[pos].density;
2505 Numeric fac, rho_mean, vol_total, mass_total, tPR;
2510 const Numeric lambda_fac = 41.*1e2;
2511 const Numeric lambda_exp = -0.21;
2519 for (
Index p=limits[0]; p<limits[1]; p++ )
2521 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
2523 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
2526 if (PR_field ( p, lat, lon ) > 0.)
2535 while (
abs( rho_mean/(mass_total/vol_total)-1.)>1e-2)
2541 os<<
"ERROR: Bulk mean density for MP48 distribution is"
2542 <<
" not converging.\n"
2543 <<
"fractional change: "
2544 <<
abs( rho_mean/(mass_total/vol_total)-1.) <<
"\n"
2545 <<
"at p: " << p <<
" lat: " << lat <<
" lon" << lon
2546 <<
" for PR=" << PR_field ( p, lat, lon ) <<
"\n";
2547 throw runtime_error ( os.str() );
2549 rho_mean = mass_total/vol_total;
2550 fac = convfac/rho_mean;
2553 tPR = PR_field ( p, lat, lon ) *
fac;
2555 lambda = lambda_fac * pow(tPR,lambda_exp);
2565 dN[i] = N0 * exp(-lambda*d[i]);
2577 mass_total = vol_total = 0.;
2580 mass_total += vol[i]*rho[i]*pnd[i];
2581 vol_total += vol[i]*pnd[i];
2591 assert(!isnan(lambda));
2595 PWC = rho_mean*
PI*N0 / pow(lambda,4.);
2597 p, lat, lon, partfield_name, verbosity );
2600 for (
Index i = 0; i< npart; i++ )
2602 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
2603 lat-limits[2], lon-limits[4] ) = pnd[i];
2607 for (
Index i = 0; i< npart; i++ )
2609 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
2610 lat-limits[2], lon-limits[4] ) = 0.;
2642 const Index& scat_data_start,
2644 const String& part_string,
2650 Vector vol_unsorted ( npart, 0.0 );
2651 Vector vol ( npart, 0.0 );
2653 Vector rho ( npart, 0.0 );
2654 Vector pnd ( npart, 0.0 );
2655 Vector dN ( npart, 0.0 );
2662 for (
Index i=0; i < npart; i++ )
2663 vol_unsorted[i] = ( scat_meta_array[i+scat_data_start].volume );
2667 for (
Index i=0; i< npart; i++ )
2669 pos = intarr[i]+scat_data_start;
2671 vol[i]= scat_meta_array[pos].volume;
2674 ( 6*scat_meta_array[pos].volume/
PI ), ( 1./3. ) );
2676 rho[i] = scat_meta_array[pos].density;
2684 for (
Index p=limits[0]; p<limits[1]; p++ )
2686 for (
Index lat=limits[2]; lat<limits[3]; lat++ )
2688 for (
Index lon=limits[4]; lon<limits[5]; lon++ )
2690 if (LWC_field ( p,lat,lon )>0.)
2697 dN[i] =
LWCtopnd ( LWC_field ( p,lat,lon ), rho[i], r[i] );
2709 chk_pndsum ( pnd, LWC_field ( p,lat,lon ), vol, rho,
2710 p, lat, lon, partfield_name, verbosity );
2713 for (
Index i =0; i< npart; i++ )
2715 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
2716 lat-limits[2], lon-limits[4] ) = pnd[i];
2722 for (
Index i = 0; i< npart; i++ )
2724 pnd_field ( intarr[i]+scat_data_start, p-limits[0],
2725 lat-limits[2], lon-limits[4] ) = 0.;
2769 Numeric cdensity = density*1e3;
2771 Numeric sig_a=0.068, sig_b1=0.054;
2772 Numeric sig_b2=5.5e-3, sig_m=0.0029;
2773 Numeric sig_aamu=0.02, sig_bamu=0.0005;
2774 Numeric sig_abmu=0.023, sig_bbmu=0.5e-3;
2775 Numeric sig_aasigma=0.02, sig_basigma=0.5e-3;
2776 Numeric sig_absigma=0.023, sig_bbsigma=4.7e-4;
2782 mc_seed = (
Index)time(NULL);
2800 sig_a=0., sig_b1=0.;
2801 sig_b2=0., sig_m=0.;
2802 sig_aamu=0., sig_bamu=0.;
2803 sig_abmu=0., sig_bbmu=0.;
2804 sig_aasigma=0., sig_basigma=0;
2805 sig_absigma=0., sig_bbsigma=0.;
2821 Numeric IWCs100=
min ( ciwc,a*pow ( ciwc,b1 ) );
2829 Numeric alphas100=b2-m*log10 ( IWCs100 );
2835 Numeric Ns100 = 6*IWCs100 * pow ( alphas100,5. ) /
2837 Numeric Nm1 = Ns100*Dm*exp ( -alphas100*Dm );
2858 Numeric bbmu=-1.2e-3+sig_bbmu;
2861 Numeric mul100=amu+bmu*log10 ( IWCl100 );
2863 Numeric aasigma=0.47+sig_aasigma;
2864 Numeric basigma=2.1e-3+sig_basigma;
2865 Numeric absigma=0.018+sig_absigma;
2866 Numeric bbsigma=-2.1e-4+sig_bbsigma;
2867 Numeric asigma=aasigma+basigma*T;
2868 Numeric bsigma=absigma+bbsigma*T;
2869 Numeric sigmal100=asigma+bsigma*log10 ( IWCl100 );
2871 if ( (mul100>0.) & (sigmal100>0.) )
2874 Numeric a2 = pow (
PI,3./2. ) * cdensity*sqrt(2) *
2875 exp( 3*mul100+9./2. * pow ( sigmal100,2 ) ) *
2876 sigmal100 * pow ( 1.,3 ) * Dm;
2878 exp ( -0.5 * pow ( ( log ( Dm )-mul100 ) /sigmal100,2 ) );
2901 dN = ( dN1+dN2 ) *1e6;
2902 if (isnan(dN)) dN = 0.0;
2934 la= 12.13 * exp( -0.055*T );
2938 la= 0.83 * exp( -0.103*T );
2942 mu= -0.57 - 0.028*T;
2946 mu= -30.93 - 0.472*T;
2951 dN = pow( D, mu ) * exp ( -la * D );
2953 if (isnan(dN)) dN = 0.0;
2987 la= 9.88 * exp( -0.060*T );
2991 la= 0.75 * exp( -0.1057*T );
2995 mu= -0.59 - 0.030*T;
2999 mu= -14.09 - 0.248*T;
3004 dN = pow( D, mu ) * exp ( -la * D );
3006 if (isnan(dN)) dN = 0.0;
3040 la= 9.88 * exp( -0.060*T );
3044 la= 0.75 * exp( -0.1057*T );
3048 mu= -0.59 - 0.030*T;
3052 mu= -14.09 - 0.248*T;
3057 dN = pow( D, mu ) * exp ( -la * D );
3059 if (isnan(dN)) dN = 0.0;
3092 alpha = 0.25*exp(0.0161*T);
3094 beta = -0.25+0.0033*T;
3098 Ar = alpha*pow(D,
beta);
3100 if (isnan(Ar)) Ar = 0.0;
3164 An=exp(Aq[0]+Aq[1]*
beta+Aq[2]*pow(
beta,2));
3165 Bn=Bq[0]+Bq[1]*
beta+Bq[2]*pow(
beta,2);
3166 Cn=Cq[0]+Cq[1]*
beta+Cq[2]*pow(
beta,2);
3168 base=Mbeta*exp(-Bn*Tc)/An;
3178 An=exp(Aq[0]+Aq[1]*n+Aq[2]*pow(n,2));
3179 Bn=Bq[0]+Bq[1]*n+Bq[2]*pow(n,2);
3180 Cn=Cq[0]+Cq[1]*n+Cq[2]*pow(n,2);
3183 Mn=An*exp(Bn*Tc)*pow(M2,Cn);
3189 phi23 =
q[0]*exp(
q[1]*x)+
q[2]*pow(x,
q[3])*exp(
q[4]*x);
3192 dN=phi23*pow(M2,4.)/pow(Mn,3.);
3194 if (isnan(dN)) dN = 0.0;
3255 An=exp(Aq[0]+Aq[1]*
beta+Aq[2]*pow(
beta,2));
3256 Bn=Bq[0]+Bq[1]*
beta+Bq[2]*pow(
beta,2);
3257 Cn=Cq[0]+Cq[1]*
beta+Cq[2]*pow(
beta,2);
3259 base=Mbeta*exp(-Bn*Tc)/An;
3269 An=exp(Aq[0]+Aq[1]*n+Aq[2]*pow(n,2));
3270 Bn=Bq[0]+Bq[1]*n+Bq[2]*pow(n,2);
3271 Cn=Cq[0]+Cq[1]*n+Cq[2]*pow(n,2);
3274 Mn=An*exp(Bn*Tc)*pow(M2,Cn);
3280 phi23 =
q[0]*exp(
q[1]*x)+
q[2]*pow(x,
q[3])*exp(
q[4]*x);
3283 dN=phi23*pow(M2,4.)/pow(Mn,3.);
3285 if (isnan(dN)) dN = 0.0;
3320 Numeric B = (alpha/gam) / pow(rc,gam);
3321 Numeric A = 0.75/
PI * lwc/density * gam * pow(B,a4g) /
3323 Numeric n = A * (pow(r,alpha) * exp(-B*pow(r,gam)));
3326 if (isnan(n)) n = 0.0;
3339 Numeric B=(alpha/gam)/pow(rc,gam);
3341 Numeric n=A*(pow(r*1e6,alpha)*exp(-B*pow(r*1e6,gam)))*1e6;
3344 if (isnan(n)) n = 0.0;
3380 dN=N0*pow(d ,mu)*exp(-lambda*pow(d,gamma));
3382 if (isnan(dN)) dN = 0.0;
3418 dN=N0*pow(d ,mu)*exp(-lambda*pow(d,gamma));
3420 if (isnan(dN)) dN = 0.0;
3448 Numeric lambda = 41.*1e2*pow(R,-0.21);
3450 Numeric n = N0*exp(-lambda*D);
3476 throw std::logic_error(
"x and y must be the same size");
3485 w[i] = 0.5*(x[i+1]-x[i])*y[i];
3487 else if (i == x.
nelem()-1)
3489 w[i] = 0.5*(x[i]-x[i-1])*y[i];
3493 w[i] = 0.5*(x[i+1]-x[i-1])*y[i];
3524 const String& partfield_name,
3538 x[i] = pnd[i]*density[i]*vol[i];
3546 if ( x.
sum() == 0.0 )
3557 os<<
"ERROR: in WSM chk_pndsum in pnd_fieldSetup!\n"
3558 <<
"Given mass density != 0, but calculated mass density == 0.\n"
3559 <<
"Seems, something went wrong in pnd_fieldSetup. Check!\n"
3560 <<
"The problem occured for profile '"<< partfield_name <<
"' at: "
3561 <<
"p = "<<p<<
", lat = "<<lat<<
", lon = "<<lon<<
".\n";
3562 throw runtime_error ( os.str() );
3566 error = xwc/x.
sum();
3570 if ( error > 1.10 || error < 0.90 )
3574 out1<<
"WARNING: in WSM chk_pndsum in pnd_fieldSetup!\n"
3575 <<
"The deviation of the sum of nodes in the particle size distribution\n"
3576 <<
"to the initial input mass density (IWC/LWC) is larger than 10%!\n"
3577 <<
"The deviation of: "<< error-1.0<<
" occured in the atmospheric level: "
3578 <<
"p = "<<p<<
", lat = "<<lat<<
", lon = "<<lon<<
".\n";
3584 out2 <<
"PND scaling factor in atm. level "
3585 <<
"(p = "<<p<<
", lat = "<<lat<<
", lon = "<<lon<<
"): "<< error <<
"\n";
3621 x[i] = pnd[i]*density[i]*vol[i];
3625 if ( x.
sum() == 0.0 )
3669 x[i] = pnd[i]*density[i]*vol[i];
3673 if ( x.
sum() == 0.0 )
3703 const String& part_string,
3709 part_string.
split ( strarr, delim );
3712 if (strarr.size()>0 && part_string[0]!=delim[0])
3714 partfield_name = strarr[0];
3719 os <<
"No information on particle field name in '" << part_string <<
"'\n";
3720 throw runtime_error ( os.str() );
3752 const String& part_string,
3758 part_string.
split ( strarr, delim );
3762 if (strarr.size()>1)
3763 psd_param = strarr[1];
3796 const String& part_string,
3802 part_string.
split ( strarr, delim );
3806 if (strarr.size()>2)
3808 part_material = strarr[2];
3813 os <<
"No information on particle type in '" << part_string <<
"'\n";
3814 throw runtime_error ( os.str() );
3834 const String& part_string,
3840 part_string.
split ( strarr, delim );
3844 if ( strarr.
nelem() < 4 || strarr[3] ==
"*" )
3850 istringstream os1 ( strarr[3] );
3854 if ( strarr.
nelem() < 5 || strarr[4] ==
"*" )
3860 istringstream os2 ( strarr[4] );