Go to the documentation of this file.
83 if (std::isnan(
scat_meta[i_ss][i_se].mass) ||
86 os <<
"A presumably incorrect value found for "
87 <<
"scat_meta[" << i_ss <<
"][" << i_se <<
"].mass.\n"
88 <<
"The value is " <<
scat_meta[i_ss][i_se].mass;
89 throw std::runtime_error(os.str());
92 if (
scat_meta[i_ss][i_se].diameter_volume_equ <= 0 ||
93 scat_meta[i_ss][i_se].diameter_volume_equ > 0.5) {
95 os <<
"A presumably incorrect value found for "
96 <<
"scat_meta[" << i_ss <<
"][" << i_se <<
"].diameter_volume_equ.\n"
97 <<
"The value is " <<
scat_meta[i_ss][i_se].diameter_volume_equ;
98 throw std::runtime_error(os.str());
123 scat_meta[i_ss][i_se].diameter_volume_equ;
136 const Index& quad_order,
147 "The method requires that length of *psd_size_grid* is >= 2.");
150 "So far, the method requires that *psd_size_grid* and "
151 "*pnd_size_grid* have same length.");
152 for (
Index i = 0; i < ng; i++) {
155 "So far, the method requires that *psd_size_grid* and "
156 "*pnd_size_grid* are identical.");
160 "Number of columns in *psd_data* and length of "
161 "*psd_size_grid* must match.");
167 "Number of columns in *dpsd_data_dx* and length of "
168 "*psd_size_grid* must match.");
178 Vector psd_size_grid_sorted(ng);
180 for (
Index i = 0; i < ng; i++)
184 throw std::runtime_error(
185 "*psd_size_grid* is not allowed to contain "
186 "duplicate values.");
192 for (
Index i = 0; i < ng; i++) {
193 for (
Index ip = 0; ip < np; ip++) {
198 for (
Index ip = 0; ip < np; ip++) {
199 for (
Index ix = 0; ix < ndx; ix++) {
218 const Index& quad_order,
219 const Index& scat_index,
233 "The method requires that length of *psd_size_grid* is >= 3.");
236 "So far, the method requires that *psd_size_grid* and"
237 " *pnd_size_grid* have the same length.");
238 for (
Index i = 0; i < ng; i++) {
241 "So far, the method requires that *psd_size_grid* and"
242 " *pnd_size_grid* are identical.");
246 "Number of columns in *psd_data* and length of"
247 " *psd_size_grid* must match.");
253 "Number of columns in *dpsd_data_dx* and length of"
254 " *psd_size_grid* must match.");
263 "*scat_data* must have passed a consistency check"
264 " (scat_data_checked=1).\n"
265 "Alternatively, use *pndFromPsdBasic*.");
268 "*scat_index* exceeds the number of available"
269 " scattering species.");
272 "Number of scattering elements in this scattering"
273 " species (*scat_index*) inconsistent with length of"
274 " *pnd_size_grid*.");
279 Vector psd_size_grid_sorted(ng);
281 for (
Index i = 0; i < ng; i++)
285 throw std::runtime_error(
286 "*psd_size_grid* is not allowed to contain "
287 "duplicate values.");
293 for (
Index i = 0; i < ng;
296 for (
Index ip = 0; ip < np; ip++)
302 for (
Index ip = 0; ip < np; ip++) {
303 for (
Index ix = 0; ix < ndx; ix++) {
314 Matrix bulkext(np, nf, 0.);
315 Vector ext(nf), ext_s0(nf), ext_s1(nf), ext_l0(nf), ext_l1(nf);
359 for (
Index ise = 0; ise < ng;
362 if (sds[intarr[ise]].ext_mat_data.nshelves() > 1)
363 ext = sds[intarr[ise]].ext_mat_data(
joker, 0, 0, 0, 0);
365 ext = sds[intarr[ise]].ext_mat_data(0, 0, 0, 0, 0);
372 else if (ise == ng - 2)
374 else if (ise == ng - 1)
377 for (
Index ip = 0; ip < np; ip++)
379 for (
Index f = fstart; f < (fstart + nf); f++)
380 bulkext(ip, f) +=
pnd_data(ip, intarr[ise]) * ext[f];
384 for (
Index ip = 0; ip < np; ip++)
391 for (
Index ip = 0; ip < np; ip++)
394 for (
Index f = fstart; f < (fstart + nf); f++) {
410 if (
abs(bulkext(ip, f)) > 1e-2 * threshold_bext) {
415 os <<
" Bin-width normalized extinction (ext*psd) not decreasing"
416 <<
" at small size edge\n"
417 <<
" at atm level #" << ip <<
" and freq point #" << f <<
".\n"
418 <<
" ext_s0=" << ext_s0[f]
420 <<
", ext_s0*psd_s0=" << ext_s0[f] *
abs(
psd_data(ip, intarr[0]))
421 <<
"\n LARGER EQUAL\n"
422 <<
" ext_s1=" << ext_s1[f]
424 <<
", ext_s1*psd_s1=" << ext_s1[f] *
abs(
psd_data(ip, intarr[1]))
426 <<
" Total bulk ext = " <<
abs(bulkext(ip, f)) <<
"\n"
427 <<
" Need to add smaller sized particles!\n";
428 throw runtime_error(os.str());
435 os <<
"Bin-width normalized extinction (ext*psd) not decreasing"
436 <<
" at large size edge\n"
437 <<
"at atm level #" << ip <<
" and freq point #" << f <<
".\n"
438 <<
" ext_l0=" << ext_l0[f]
439 <<
", psd_l0=" <<
abs(
psd_data(ip, intarr[ng - 1]))
440 <<
", ext_l0*psd_l0="
442 <<
"\n LARGER EQUAL\n"
443 <<
" ext_l1=" << ext_l1[f]
444 <<
", psd_l1=" <<
abs(
psd_data(ip, intarr[ng - 2]))
445 <<
", ext_l1*psd_l1="
446 << ext_l1[f] *
abs(
psd_data(ip, intarr[ng - 2])) <<
"\n"
447 <<
" Total bulk ext = " <<
abs(bulkext(ip, f)) <<
"\n"
448 <<
" Need to add larger sized particles!\n";
449 throw runtime_error(os.str());
455 if (
abs(bulkext(ip, f)) > threshold_bext) {
456 if (
abs(
pnd_data(ip, intarr[0])) > threshold_rpnd * max0) {
463 threshold_rsec *
abs(bulkext(ip, f))) {
465 os <<
"Contribution of edge bin to total extinction too high"
466 <<
" (" << contrib * 1e2 <<
"% of " <<
abs(bulkext(ip, f))
467 <<
") at small size edge\n"
468 <<
"at atm level #" << ip <<
" and freq point #" << f <<
".\n"
469 <<
" Need to add smaller sized particles or refine the size"
470 <<
" grid on the small size edge!\n";
471 throw runtime_error(os.str());
474 if (
abs(
pnd_data(ip, intarr[ng - 1])) > threshold_rpnd * max1) {
475 contrib =
abs(
pnd_data(ip, intarr[ng - 1])) * ext_l0[f] /
480 if (
abs(
pnd_data(ip, intarr[ng - 1])) * ext_l0[f] >
481 threshold_rsec *
abs(bulkext(ip, f))) {
483 os <<
"Contribution of edge bin to total extinction too high"
484 <<
" (" << contrib * 1e2 <<
"% of " <<
abs(bulkext(ip, f))
485 <<
") at large size edge\n"
486 <<
"at atm level #" << ip <<
" and freq point #" << f <<
".\n"
487 <<
" Need to add larger sized particles or refine the size"
488 <<
" grid on the large size edge!\n";
489 throw runtime_error(os.str());
526 throw runtime_error(
"*particle_bulkprop_field* is empty.");
546 "Number of fields in *particle_bulkprop_field*"
547 " inconsistent with number of names in"
548 " *particle_bulkprop_names*.");
552 "At least one field per scattering species required"
553 " in *particle_bulkprop_field*.");
558 "Length of *cloudbox_limits* incorrect with respect "
559 "to *atmosphere_dim*.");
562 throw runtime_error(
"Invalid data in pressure part of *cloudbox_limits*.");
567 "Invalid data in latitude part of *cloudbox_limits*.");
572 "Invalid data in longitude part of *cloudbox_limits*.");
576 if (nss < 1)
throw runtime_error(
"*scat_data* is empty!.");
579 "*scat_data* and *scat_species* are inconsistent in size.");
582 "*scat_data* and *scat_meta* are inconsistent in size.");
585 "*scat_data* and *pnd_agenda_array* are inconsistent "
589 "*scat_data* and *pnd_agenda_array_input_names* are "
590 "inconsistent in size.");
597 Index ilat_offset = 0;
603 Index ilon_offset = 0;
612 "*particle_bulkprop_field* allowed to contain"
613 " non-zero values only inside the cloudbox.";
615 Index dp_start, dp_end;
621 throw runtime_error(estring);
626 const Index np_above =
p_grid.nelem() + 1 - (np + ip_offset);
631 throw runtime_error(estring);
639 for (
Index i = 0; i < nss; i++) {
642 "*scat_data* and *scat_meta* have inconsistent sizes.");
643 ncumse[i + 1] = ncumse[i] +
scat_data[i].nelem();
648 pnd_field.resize(ncumse[nss], np, nlat, nlon);
660 scatspecies_to_jq.resize(nss);
662 for (
Index iq = 0; iq < nq; iq++) {
668 os <<
"Jacobian quantity with index " << iq <<
" refers to\n"
670 <<
"\nbut this species could not be found in *scat_species*.";
671 throw runtime_error(os.str());
673 scatspecies_to_jq[ihit].push_back(iq);
681 for (
Index is = 0; is < nss; is++) {
683 Range se_range(ncumse[is], ncumse[is + 1] - ncumse[is]);
690 for (
Index i = 0; i < nin; i++) {
693 if (i_pbulkprop[i] < 0) {
695 os <<
"Pnd-agenda with index " << is <<
" is set to require \""
697 <<
"could not found in *particle_bulkprop_names*.\n"
698 <<
"(Note that temperature must be written as \"Temperature\")";
699 throw runtime_error(os.str());
709 ndx = scatspecies_to_jq[is].
nelem();
711 for (
Index ix = 0; ix < ndx; ix++) {
718 for (
Index ilon = 0; ilon < nlon; ilon++) {
719 for (
Index ilat = 0; ilat < nlat; ilat++) {
723 if ((nlat > 1 && (ilat == 0 || ilat == nlat - 1)) ||
724 (nlon > 1 && (ilon == 0 || ilon == nlon - 1))) {
732 for (
Index i = 0; i < nin; i++) {
733 for (
Index ip = 0; ip < np; ip++) {
744 for (
Index ip = 0; ip < np; ip++) {
746 t_field(ip_offset + ip, ilat_offset + ilat, ilon_offset + ilon);
764 for (
Index ip = 0; ip < np; ip++) {
767 for (
Index ix = 0; ix < ndx; ix++) {
768 for (
Index ip = dp_start; ip < dp_end; ip++) {
769 dpnd_field_dx[scatspecies_to_jq[is][ix]](se_range, ip, ilat, ilon) =
783 const Index& species_index,
787 const Index& do_only_x,
791 if (nss == 0)
throw runtime_error(
"*scat_meta* is empty!");
792 if (nss < species_index + 1) {
794 os <<
"Selected scattering species index is " << species_index
796 <<
"is not allowed since *scat_meta* has only " << nss <<
" elements.";
797 throw runtime_error(os.str());
803 "The scattering species must have at least two "
804 "elements to use this method.");
810 for (
Index i = 0; i < nse; i++) {
811 mass[i] =
scat_meta[species_index][i].mass;
818 if (x_unit ==
"dveq") {
819 for (
Index i = 0; i < nse; i++) {
835 else if (x_unit ==
"dmax") {
836 for (
Index i = 0; i < nse; i++) {
852 else if (x_unit ==
"area") {
853 for (
Index i = 0; i < nse; i++) {
855 scat_meta[species_index][i].diameter_area_equ_aerodynamical;
870 else if (x_unit ==
"mass") {
879 os <<
"You have selected the x_unit: " << x_unit
880 <<
"while accepted choices are: \"dveq\", \"dmax\", \"mass\" and \"area\"";
881 throw runtime_error(os.str());
Index atmosphere_dim(Workspace &ws) noexcept
ArrayOfArrayOfScatteringMetaData scat_meta(Workspace &ws) noexcept
Numeric scat_species_a(Workspace &ws) noexcept
ArrayOfRetrievalQuantity jacobian_quantities(Workspace &ws) noexcept
void pndFromPsdBasic(Matrix &pnd_data, Tensor3 &dpnd_data_dx, const Vector &pnd_size_grid, const Matrix &psd_data, const Vector &psd_size_grid, const Tensor3 &dpsd_data_dx, const Index &quad_order, const Verbosity &)
WORKSPACE METHOD: pndFromPsdBasic.
const String SCATSPECIES_MAINTAG
Vector lat_grid(Workspace &ws) noexcept
Header file for interpolation.cc.
Tensor4 pnd_field(Workspace &ws) noexcept
void particle_massesFromMetaData(Matrix &particle_masses, const ArrayOfArrayOfScatteringMetaData &scat_meta, const Verbosity &)
WORKSPACE METHOD: particle_massesFromMetaData.
Vector psd_size_grid(Workspace &ws) noexcept
void bin_quadweights(Vector &w, const Vector &x, const Index &order)
ArrayOfIndex cloudbox_limits(Workspace &ws) noexcept
Index jacobian_do(Workspace &ws) noexcept
Index TotalNumberOfElements(const Array< Array< base > > &aa)
Determine total number of elements in an ArrayOfArray.
This file contains the definition of Array.
void derive_scat_species_a_and_b(Numeric &a, Numeric &b, const Vector &x, const Vector &mass, const Numeric &x_fit_start, const Numeric &x_fit_end)
ArrayOfString dpnd_data_dx_names(Workspace &ws) noexcept
ArrayOfString particle_bulkprop_names(Workspace &ws) noexcept
Internal functions for microphysics calculations (size distributions etc.)
This can be used to make arrays out of anything.
Tensor3 dpsd_data_dx(Workspace &ws) noexcept
Index nelem(const Lines &l)
Number of lines.
void get_sorted_indexes(ArrayOfIndex &sorted, const T &data)
get_sorted_indexes
Matrix pnd_data(Workspace &ws) noexcept
void particle_massesFromMetaDataSingleCategory(Matrix &particle_masses, const ArrayOfArrayOfScatteringMetaData &scat_meta, const Verbosity &)
WORKSPACE METHOD: particle_massesFromMetaDataSingleCategory.
Declarations having to do with the four output streams.
ArrayOfAgenda pnd_agenda_array(Workspace &ws) noexcept
Matrix particle_masses(Workspace &ws) noexcept
This file contains declerations of functions of physical character.
Vector p_grid(Workspace &ws) noexcept
Scattering database structure and functions.
NUMERIC Numeric
The type to use for all floating point numbers.
Linear algebra functions.
Vector f_grid(Workspace &ws) noexcept
Vector scat_species_x(Workspace &ws) noexcept
ArrayOfArrayOfSingleScatteringData scat_data(Workspace &ws) noexcept
void pnd_fieldCalcFromParticleBulkProps(Workspace &ws, Tensor4 &pnd_field, ArrayOfTensor4 &dpnd_field_dx, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &t_field, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const ArrayOfString &scat_species, const ArrayOfArrayOfSingleScatteringData &scat_data, const ArrayOfArrayOfScatteringMetaData &scat_meta, const Tensor4 &particle_bulkprop_field, const ArrayOfString &particle_bulkprop_names, const ArrayOfAgenda &pnd_agenda_array, const ArrayOfArrayOfString &pnd_agenda_array_input_names, const Index &jacobian_do, const ArrayOfRetrievalQuantity &jacobian_quantities, const Verbosity &)
WORKSPACE METHOD: pnd_fieldCalcFromParticleBulkProps.
This file contains header information for the dealing with command line parameters.
Vector lon_grid(Workspace &ws) noexcept
ArrayOfTensor4 dpnd_field_dx(Workspace &ws) noexcept
Internal cloudbox functions.
Internal functions associated with size distributions.
Numeric scat_species_b(Workspace &ws) noexcept
Index scat_data_checked(Workspace &ws) noexcept
void ScatSpeciesSizeMassInfo(Vector &scat_species_x, Numeric &scat_species_a, Numeric &scat_species_b, const ArrayOfArrayOfScatteringMetaData &scat_meta, const Index &species_index, const String &x_unit, const Numeric &x_fit_start, const Numeric &x_fit_end, const Index &do_only_x, const Verbosity &)
WORKSPACE METHOD: ScatSpeciesSizeMassInfo.
void pndFromPsd(Matrix &pnd_data, Tensor3 &dpnd_data_dx, const Vector &pnd_size_grid, const Matrix &psd_data, const Vector &psd_size_grid, const Tensor3 &dpsd_data_dx, const ArrayOfArrayOfSingleScatteringData &scat_data, const Vector &f_grid, const Index &scat_data_checked, const Index &quad_order, const Index &scat_index, const Numeric &threshold_rsec, const Numeric &threshold_bext, const Numeric &threshold_rpnd, const Verbosity &)
WORKSPACE METHOD: pndFromPsd.
bool is_increasing(ConstVectorView x)
Checks if a vector is sorted and strictly increasing.
Header file for logic.cc.
Tensor4 particle_bulkprop_field(Workspace &ws) noexcept
Declaration of functions in rte.cc.
Tensor3 t_field(Workspace &ws) noexcept
Header file for special_interp.cc.
Tensor3 dpnd_data_dx(Workspace &ws) noexcept
Vector pnd_agenda_input_t(Workspace &ws) noexcept
void pnd_agenda_arrayExecute(Workspace &ws, Matrix &pnd_data, Tensor3 &dpnd_data_dx, const Index agenda_array_index, const Vector &pnd_agenda_input_t, const Matrix &pnd_agenda_input, const ArrayOfString &pnd_agenda_input_names, const ArrayOfString &dpnd_data_dx_names, const ArrayOfAgenda &input_agenda_array)
This file contains basic functions to handle ASCII files.
INDEX Index
The type to use for all integer numbers and indices.
ArrayOfString scat_species(Workspace &ws) noexcept
Index find_first(const Array< base > &x, const base &w)
Find first occurance.
Contains sorting routines.
Index nelem() const
Number of elements.
Matrix pnd_agenda_input(Workspace &ws) noexcept
Vector pnd_size_grid(Workspace &ws) noexcept
ArrayOfArrayOfString pnd_agenda_array_input_names(Workspace &ws) noexcept
Matrix psd_data(Workspace &ws) noexcept
The global header file for ARTS.
Index cloudbox_on(Workspace &ws) noexcept
This file contains basic functions to handle XML data files.