ARTS 2.5.11 (git: 725533f0)
cloudbox.cc
Go to the documentation of this file.
1
9#include "cloudbox.h"
10#include "gridded_fields.h"
11
15
16/*===========================================================================
17 === External declarations
18 ===========================================================================*/
19#include <algorithm>
20#include <cmath>
21#include <ctime>
22#include <limits>
23#include <stdexcept>
24
25#include "arts.h"
26#include "check_input.h"
27#include "lin_alg.h"
28#include "logic.h"
29#include "math_funcs.h"
30#include "mc_antenna.h"
31#include "messages.h"
32#include "physics_funcs.h"
33#include "ppath.h"
34#include "rng.h"
35#include "sorting.h"
36
38
50void chk_pnd_data(const GriddedField3& pnd_field_raw,
51 const String& pnd_field_file,
52 const Index& atmosphere_dim,
53 const Verbosity& verbosity) {
55
56 const Vector& pfr_lat_grid =
57 pnd_field_raw.get_numeric_grid(GFIELD3_LAT_GRID);
58 const Vector& pfr_lon_grid =
59 pnd_field_raw.get_numeric_grid(GFIELD3_LON_GRID);
60
61 // The consistency of the dimensions is checked in the reading routine.
62 // Here we have to check whether the atmospheric dimension is correct and whether
63 // the particle number density is 0 on the cloudbox boundary and outside the cloudbox.
64
65 out3 << "Check particle number density file " << pnd_field_file << "\n";
66
67 ARTS_USER_ERROR_IF (atmosphere_dim == 1 &&
68 (pfr_lat_grid.nelem() != 1 || pfr_lon_grid.nelem() != 1),
69 "The atmospheric dimension is 1D but the particle "
70 "number density file * ", pnd_field_file,
71 " is for a 3D atmosphere. \n")
72
73 if (atmosphere_dim == 3) {
74 ARTS_USER_ERROR_IF (pfr_lat_grid.nelem() == 1 || pfr_lon_grid.nelem() == 1,
75 "The atmospheric dimension is 3D but the particle "
76 "number density file * ", pnd_field_file,
77 " is for a 1D or a 2D atmosphere. \n")
78 }
79
80 out3 << "Particle number density data is o.k. \n";
81}
82
84
93void chk_pnd_raw_data(const ArrayOfGriddedField3& pnd_field_raw,
94 const String& pnd_field_file,
95 const Index& atmosphere_dim,
96 const Verbosity& verbosity) {
98
99 for (Index i = 0; i < pnd_field_raw.nelem(); i++) {
100 out3 << "Element in pnd_field_raw_file:" << i << "\n";
101 chk_pnd_data(pnd_field_raw[i], pnd_field_file, atmosphere_dim, verbosity);
102 }
103}
104
106
124 const Index& dim,
125 const ArrayOfGriddedField3& pnd_field_raw,
126 ConstVectorView p_grid,
127 ConstVectorView lat_grid,
128 ConstVectorView lon_grid,
129 const ArrayOfIndex& cloudbox_limits) {
130 Numeric p, lat, lon, v;
131 Index n, p_i, lat_i, lon_i;
132 // For any non-zero point, verify we're outside the cloudbox
133 for (n = 0; n < pnd_field_raw.nelem(); n++) {
134 for (p_i = 0; p_i < pnd_field_raw[n].data.npages(); p_i++) {
135 for (lat_i = 0; lat_i < pnd_field_raw[n].data.nrows(); lat_i++) {
136 for (lon_i = 0; lon_i < pnd_field_raw[n].data.ncols(); lon_i++) {
137 v = pnd_field_raw[n].data(p_i, lat_i, lon_i);
138 if (v != 0) {
139 // Verify pressure is between cloudbox limits
140 p = pnd_field_raw[n].get_numeric_grid(GFIELD3_P_GRID)[p_i];
141 // if (!((p <= p_grid[cloudbox_limits[0]]) &
142 // (p >= p_grid[cloudbox_limits[1]]))) {
143 ARTS_USER_ERROR_IF ((p <= p_grid[cloudbox_limits[1]]) ||
144 ((p >= p_grid[cloudbox_limits[0]]) &&
145 (cloudbox_limits[0] != 0)),
146 "Found non-zero pnd outside cloudbox. "
147 "Cloudbox extends from p=", p_grid[cloudbox_limits[0]],
148 " Pa to p=", p_grid[cloudbox_limits[1]],
149 " Pa, but found pnd=", v, "/m³ at p=", p,
150 " Pa for scattering "
151 "element #", n, ".")
152 // Verify latitude is too
153 if (dim > 1) {
154 lat = pnd_field_raw[n].get_numeric_grid(GFIELD3_LAT_GRID)[lat_i];
155 ARTS_USER_ERROR_IF (!((lat > lat_grid[cloudbox_limits[2]]) and
156 (lat < lat_grid[cloudbox_limits[3]])),
157 "Found non-zero pnd outside cloudbox. "
158 "Cloudbox extends from lat=",
159 lat_grid[cloudbox_limits[2]],
160 "° to lat=", lat_grid[cloudbox_limits[3]],
161 "°, but found pnd=", v, "/m³ at lat=", lat,
162 "° for scattering "
163 "element #", n, ".")
164 }
165 // Etc. for longitude
166 if (dim > 2) {
167 lon = pnd_field_raw[n].get_numeric_grid(GFIELD3_LON_GRID)[lon_i];
168 ARTS_USER_ERROR_IF (!((lon > lon_grid[cloudbox_limits[4]]) and
169 (lon < lon_grid[cloudbox_limits[5]])),
170 "Found non-zero pnd outside cloudbox. "
171 "Cloudbox extends from lon=",
172 lon_grid[cloudbox_limits[4]],
173 "° to lat=", lon_grid[cloudbox_limits[5]],
174 "°, but found pnd=", v, "/m³ at lon=", lon,
175 "° for scattering "
176 "element #", n, ".")
177 }
178 }
179 }
180 }
181 }
182 }
183}
184
186
198void chk_scat_species(const ArrayOfString& scat_species, const String& delim) {
199 ArrayOfString strarr;
200 Index nelem = 2;
201
202 for (Index k = 0; k < scat_species.nelem(); k++) {
203 scat_species[k].split(strarr, delim);
204 ARTS_USER_ERROR_IF (strarr.nelem() < nelem,
205 "Individual strings in scat_species must contain at least ", nelem,
206 " elements,\n"
207 "but entry #", k, " contains only the following ",
208 strarr.nelem(), ":\n",
209 strarr, "\n")
210 }
211}
212
214
225 const ArrayOfScatteringMetaData& scat_meta,
226 const Verbosity&) {
227 ARTS_USER_ERROR_IF (scat_data.nelem() != scat_meta.nelem(),
228 "The number of elements in in current scat_species' *scat_data* and "
229 "*scat_meta* do not match.\n"
230 "Each *scat_data* entry must correspond to one entry in *scat_meta*.")
231}
232
234
244 const String& scat_meta_file,
245 const Verbosity& verbosity) {
247 out3 << " Check scattering meta data file " << scat_meta_file << "\n";
248
249 /* this check is outdated. type now is free from!
250 however, we might want to have other things checked here!?
251 - which parameters at least are needed? -> radius, ...?
252 - ...
253 if (scat_meta_single.type != "Ice" && scat_meta_single.type != "Water" && scat_meta_single.type != "Aerosol")
254 {
255 ostringstream os;
256 os << "Type in " << scat_meta_file << " must be 'Ice', 'Water' or 'Aerosol'\n";
257 throw runtime_error( os.str() );
258 }
259*/
260 //(more) checks need to be included
261}
262
264
275void chk_scat_data(const SingleScatteringData& scat_data_single,
276 const Verbosity& verbosity) {
278
279 ARTS_ASSERT(scat_data_single.ptype == PTYPE_GENERAL ||
280 scat_data_single.ptype == PTYPE_TOTAL_RND ||
281 scat_data_single.ptype == PTYPE_AZIMUTH_RND);
282
283 ARTS_USER_ERROR_IF (scat_data_single.za_grid[0] != 0.,
284 "The first value of the zenith angle grid in the single"
285 " scattering properties data must be 0.")
286
287 ARTS_USER_ERROR_IF (last(scat_data_single.za_grid) != 180.,
288 "The last value of the zenith angle grid in the single"
289 " scattering properties data must be 180.")
290
291 ARTS_USER_ERROR_IF (scat_data_single.ptype == PTYPE_GENERAL &&
292 scat_data_single.aa_grid[0] != -180.,
293 "For ptype = \"general\" the first value"
294 " of the azimuth angle grid in the single scattering"
295 " properties data must be -180.")
296
297 ARTS_USER_ERROR_IF (scat_data_single.ptype == PTYPE_AZIMUTH_RND &&
298 scat_data_single.aa_grid[0] != 0.,
299 "For ptype = \"azimuthally_random\""
300 " the first value"
301 " of the azimuth angle grid in the single scattering"
302 " properties data must be 0.")
303
304 ARTS_USER_ERROR_IF (scat_data_single.ptype != PTYPE_TOTAL_RND &&
305 last(scat_data_single.aa_grid) != 180.,
306 "For ptypes = \"azimuthally_random\" and \"general\""
307 " the last value of the azimuth angle grid in the single"
308 " scattering properties data must be 180.")
309
310 ostringstream os_pha_mat;
311 os_pha_mat << "pha_mat ";
312 ostringstream os_ext_mat;
313 os_ext_mat << "ext_mat ";
314 ostringstream os_abs_vec;
315 os_abs_vec << "abs_vec ";
316
317 switch (scat_data_single.ptype) {
318 case PTYPE_GENERAL:
319
320 out3 << " Data is for arbitrarily orientated particles. \n";
321
322 chk_size(os_pha_mat.str(),
323 scat_data_single.pha_mat_data,
324 scat_data_single.f_grid.nelem(),
325 scat_data_single.T_grid.nelem(),
326 scat_data_single.za_grid.nelem(),
327 scat_data_single.aa_grid.nelem(),
328 scat_data_single.za_grid.nelem(),
329 scat_data_single.aa_grid.nelem(),
330 16);
331
332 chk_size(os_ext_mat.str(),
333 scat_data_single.ext_mat_data,
334 scat_data_single.f_grid.nelem(),
335 scat_data_single.T_grid.nelem(),
336 scat_data_single.za_grid.nelem(),
337 scat_data_single.aa_grid.nelem(),
338 7);
339
340 chk_size(os_abs_vec.str(),
341 scat_data_single.abs_vec_data,
342 scat_data_single.f_grid.nelem(),
343 scat_data_single.T_grid.nelem(),
344 scat_data_single.za_grid.nelem(),
345 scat_data_single.aa_grid.nelem(),
346 4);
347 break;
348
349 case PTYPE_TOTAL_RND:
350
351 out3 << " Data is for macroscopically isotropic and mirror-symmetric "
352 << "scattering media, i.e. for totally randomly oriented particles "
353 << "with at least one plane of symmetry. \n";
354
355 chk_size(os_pha_mat.str(),
356 scat_data_single.pha_mat_data,
357 scat_data_single.f_grid.nelem(),
358 scat_data_single.T_grid.nelem(),
359 scat_data_single.za_grid.nelem(),
360 1,
361 1,
362 1,
363 6);
364
365 chk_size(os_ext_mat.str(),
366 scat_data_single.ext_mat_data,
367 scat_data_single.f_grid.nelem(),
368 scat_data_single.T_grid.nelem(),
369 1,
370 1,
371 1);
372
373 chk_size(os_abs_vec.str(),
374 scat_data_single.abs_vec_data,
375 scat_data_single.f_grid.nelem(),
376 scat_data_single.T_grid.nelem(),
377 1,
378 1,
379 1);
380 break;
381
383
384 out3 << " Data is for azimuthally randomly oriented particles. \n";
385
386 chk_size(os_pha_mat.str(),
387 scat_data_single.pha_mat_data,
388 scat_data_single.f_grid.nelem(),
389 scat_data_single.T_grid.nelem(),
390 scat_data_single.za_grid.nelem(),
391 scat_data_single.aa_grid.nelem(),
392 scat_data_single.za_grid.nelem(),
393 1,
394 16);
395
396 chk_size(os_ext_mat.str(),
397 scat_data_single.ext_mat_data,
398 scat_data_single.f_grid.nelem(),
399 scat_data_single.T_grid.nelem(),
400 scat_data_single.za_grid.nelem(),
401 1,
402 3);
403
404 chk_size(os_abs_vec.str(),
405 scat_data_single.abs_vec_data,
406 scat_data_single.f_grid.nelem(),
407 scat_data_single.T_grid.nelem(),
408 scat_data_single.za_grid.nelem(),
409 1,
410 2);
411 break;
412 }
413
414 // Here we only check whether the temperature grid is of the unit K, not
415 // whether it corresponds to the required values in t_field. The second
416 // option is not trivial since here one has to look whether the pnd_field
417 // is non-zero for the corresponding temperature. This check is done in the
418 // functions where the multiplication with the particle number density is
419 // done.
420 ARTS_USER_ERROR_IF (scat_data_single.T_grid[0] < 0. ||
421 last(scat_data_single.T_grid) > 1001.,
422 "The temperature values in the single scattering data"
423 " are negative or very large. Check whether you use the "
424 "right unit [Kelvin].")
425}
426
444 const GridPos& gp_lat,
445 const GridPos& gp_lon,
446 const ArrayOfIndex& cloudbox_limits,
447 const bool& include_boundaries,
448 const Index& atmosphere_dim)
449
450{
451 if (include_boundaries) {
452 // Pressure dimension
453 double ipos = fractional_gp(gp_p);
454 if (ipos < double(cloudbox_limits[0]) ||
455 ipos > double(cloudbox_limits[1])) {
456 return false;
457 }
458
459 else if (atmosphere_dim >= 2) {
460 // Latitude dimension
461 ipos = fractional_gp(gp_lat);
462 if (ipos < double(cloudbox_limits[2]) ||
463 ipos > double(cloudbox_limits[3])) {
464 return false;
465 }
466
467 else if (atmosphere_dim == 3) {
468 // Longitude dimension
469 ipos = fractional_gp(gp_lon);
470 if (ipos < double(cloudbox_limits[4]) ||
471 ipos > double(cloudbox_limits[5])) {
472 return false;
473 }
474 }
475 }
476 return true;
477 } else {
478 // Pressure dimension
479 double ipos = fractional_gp(gp_p);
480 if (ipos <= double(cloudbox_limits[0]) ||
481 ipos >= double(cloudbox_limits[1])) {
482 return false;
483 }
484
485 else if (atmosphere_dim >= 2) {
486 // Latitude dimension
487 ipos = fractional_gp(gp_lat);
488 if (ipos <= double(cloudbox_limits[2]) ||
489 ipos >= double(cloudbox_limits[3])) {
490 return false;
491 }
492
493 else if (atmosphere_dim == 3) {
494 // Longitude dimension
495 ipos = fractional_gp(gp_lon);
496 if (ipos <= double(cloudbox_limits[4]) ||
497 ipos >= double(cloudbox_limits[5])) {
498 return false;
499 }
500 }
501 }
502 return true;
503 }
504}
505
523bool is_inside_cloudbox(const Ppath& ppath_step,
524 const ArrayOfIndex& cloudbox_limits,
525 const bool include_boundaries)
526
527{
528 ARTS_ASSERT(cloudbox_limits.nelem() == 6);
529 const Index np = ppath_step.np;
530
531 return is_gp_inside_cloudbox(ppath_step.gp_p[np - 1],
532 ppath_step.gp_lat[np - 1],
533 ppath_step.gp_lon[np - 1],
534 cloudbox_limits,
535 include_boundaries);
536}
537
555void bin_quadweights(Vector& w, const Vector& x, const Index& order) {
556 Index nx = x.nelem();
557
558 ARTS_ASSERT(nx > 1);
559 ARTS_ASSERT(is_increasing(x));
560
561 if (order == 0) {
562 w[0] = min(x[1] - x[0],
563 0.5 * (x[1] + x[0])); // the latter is the half distance
564 // from x0 to x1 plus the distance
565 // to 0, ie 0.5(x1-x0)+x0.
566 w[nx - 1] = x[nx - 1] - x[nx - 2];
567 } else {
568 w[0] = 0.5 * (x[1] - x[0]);
569 w[nx - 1] = 0.5 * (x[nx - 1] - x[nx - 2]);
570 }
571 for (Index i = 1; i < nx - 1; i++) {
572 w[i] = 0.5 * (x[i + 1] - x[i - 1]);
573 }
574}
575
577
590void chk_scat_species_field(bool& empty_flag,
591 const Tensor3& scat_species_field,
592 const String& fieldname,
593 const Index& dim,
594 const Vector& p_grid,
595 const Vector& lat_grid,
596 const Vector& lon_grid) {
597 // check p
598 ARTS_USER_ERROR_IF (scat_species_field.npages() != p_grid.nelem(),
599 "The size of *p_grid* (", p_grid.nelem(),
600 ") is unequal the number of pages of *", fieldname, "* (",
601 scat_species_field.npages(), ").")
602
603 // check lat
604 if (dim >= 2) {
605 ARTS_USER_ERROR_IF (scat_species_field.nrows() != lat_grid.nelem(),
606 "The size of *lat_grid* (", lat_grid.nelem(),
607 ") is unequal the number of rows of *", fieldname, "* (",
608 scat_species_field.nrows(), ").")
609 }
610
611 // check lon
612 if (dim == 3) {
613 ARTS_USER_ERROR_IF (scat_species_field.ncols() != lon_grid.nelem(),
614 "The size of *lon_grid* (", lon_grid.nelem(),
615 ") is unequal the number of columns of *", fieldname, "* (",
616 scat_species_field.ncols(), ").")
617 }
618
619 empty_flag = false;
620 // set empty_flag to true if a single value of hydromet_field is unequal zero
621 for (Index j = 0; j < scat_species_field.npages(); j++) {
622 for (Index k = 0; k < scat_species_field.nrows(); k++) {
623 for (Index l = 0; l < scat_species_field.ncols(); l++) {
624 if (scat_species_field(j, k, l) != 0.0 &&
625 !std::isnan(scat_species_field(j, k, l)))
626 empty_flag = true;
627 // if ( scat_species_field(j,k,l) != 0.0 ) empty_flag = true;
628 }
629 }
630 }
631}
632
634
649void find_cloudlimits(Index& lower,
650 Index& upper,
651 const Tensor3& scat_species_field,
652 const Index& atmosphere_dim,
653 const Numeric& cloudbox_margin) {
654 if (atmosphere_dim == 1) {
655 // scattering species profiles
656 ConstVectorView ss_prof = scat_species_field(joker, 0, 0);
657
658 Index i = 0;
659
660 // find lower cloudbox_limit to surface if margin != -1 (cloudbox not
661 // forced to reach down to surface)
662 if (cloudbox_margin != -1) {
663 // find index of first pressure level where hydromet_field is
664 // unequal 0, starting from the surface
665 for (i = 0; i < lower; i++) {
666 //cout << "for lower limit checking level #" << i << "\n";
667
668 // if any of the scat species fields contains a non-zero, non-NaN
669 // value at this atm level we found a potential lower limit value
670 if (ss_prof[i] != 0.0 && !std::isnan(ss_prof[i])) {
671 //cout << "found particles\n";
672
673 // check if lower is the lowest index in all selected
674 // scattering species fields
675 if (lower > i) {
676 lower = i;
677 //cout << "new lower limit at level #" << lower << "\n";
678 }
679 break;
680 }
681 }
682 }
683
684 // find index of highest pressure level, where scat_species_mass_density_field is
685 // unequal 0, starting from top of the atmosphere
686 for (Index j = scat_species_field.npages() - 1; j >= max(i, upper); j--) {
687 //cout << "for upper limit checking level #" << j << "\n";
688
689 // if any of the scat species fields contains a non-zero, non-NaN
690 // value at this atm level we found a potential lower limit value
691 if (ss_prof[j] != 0.0 && !std::isnan(ss_prof[j])) {
692 //cout << "found particles\n";
693
694 // check if upper is the highest index in all selected
695 // scattering species fields
696 if (upper < j) {
697 upper = j;
698 //cout << "new upper limit at level #" << upper << "\n";
699 }
700 break;
701 }
702 }
703 }
704
705 else {
706 ARTS_USER_ERROR ("Not yet available for 2D and 3D cases.")
707 }
708
709 /* //NOT WORKING YET
710 // Latitude limits
711 else if ( atmosphere_dim == 2 )
712 {
713 MatrixView hydro_lat = hydromet_field ( nhyd, joker, joker, 0 );
714
715 for ( i=0; i<hydro_lat.nrows(); i++ )
716 {
717 for ( j=0; j<hydro_lat.ncols(); j++ )
718 {
719 if ( hydro_lat[i,j] != 0.0 )
720 {
721
722 if ( lat1 <= j ) lat1 =j;
723 //cloudbox_limits[2] = lat1;
724 //break;
725 }
726
727 }
728 if ( lower <= i ) lower = i;
729 }
730
731 for ( k=hydro_lat.nelem()-1; k>=i; k-- )
732 {
733 if ( hydro_lat[k] != 0.0 )
734 {
735 lat2 = k;
736 cloudbox_limits[3] = lat2;
737 break;
738
739 }
740
741 }
742 }
743
744 // Longitude limits
745 if ( atmosphere_dim == 3 )
746 {
747 Tensor3View hydro_lon = hydromet_field ( nhyd, joker, joker, joker );
748
749 for ( i=0; i<hydro_lon.nelem(); i++ )
750 {
751 if ( hydro_lon[i] != 0.0 )
752 {
753 lon1 = i;
754 cloudbox_limits[4] = lon1;
755 break;
756 }
757
758 }
759 for ( j=hydro_lon.nelem()-1; j>=i; j-- )
760 {
761 if ( hydro_lon[j] != 0.0 )
762 {
763 lon2 = j;
764 cloudbox_limits[5] = lon2;
765 break;
766
767 }
768}*/
769}
770
782 String& species_type,
783 // WS Input:
784 const String& field_name,
785 const String& delim) {
786 ArrayOfString strarr;
787
788 // split field_name string at '-' and write to ArrayOfString
789 field_name.split(strarr, delim);
790
791 // first entry is species type
792 // (i.e. "abs_species" or "scat_species". or "T" or "z", which are ignored.)
793 if (strarr.size() > 0 && field_name[0] != '-') {
794 species_type = strarr[0];
795 } else {
797 "No information on field species type found in '",
798 field_name, "'\n")
799 }
800}
801
813 String& species_name,
814 // WS Input:
815 const String& field_name,
816 const String& delim) {
817 ArrayOfString strarr;
818
819 // split field_name string at '-' and write to ArrayOfString
820 field_name.split(strarr, delim);
821
822 // second entry is species name
823 // (e.g. "H2O, "O3" etc. for abs_species or "IWC", "LWC" etc. for scat_species)
824 if (strarr.size() > 1) {
825 species_name = strarr[1];
826 } else {
828 "No information on field species name found in '",
829 field_name, "'\n")
830 }
831}
832
844 String& scat_type,
845 // WS Input:
846 const String& field_name,
847 const String& delim) {
848 ArrayOfString strarr;
849
850 // split field_name string at '-' and write to ArrayOfString
851 field_name.split(strarr, delim);
852
853 // third entry is type of scat_species field
854 // (e.g. "mass_density", "mass_flux", "number_density")
855 if (strarr.size() > 2) {
856 scat_type = strarr[2];
857 } else {
859 "No information on type of scat_species field found in '",
860 field_name, "'\n")
861 }
862}
863
874void parse_partfield_name( //WS Output:
875 String& partfield_name,
876 // WS Input:
877 const String& part_string,
878 const String& delim) {
879 ArrayOfString strarr;
880
881 // split scat_species string at delim and write to ArrayOfString
882 part_string.split(strarr, delim);
883
884 //first entry is scattering species field name (e.g. "IWC", "LWC" etc.)
885 if (strarr.size() > 0 && part_string[0] != delim[0]) {
886 partfield_name = strarr[0];
887 } else {
888 ARTS_USER_ERROR ("No information on scattering species field name in '",
889 part_string, "'\n")
890 }
891}
892
base max(const Array< base > &x)
Max function.
Definition array.h:128
base min(const Array< base > &x)
Min function.
Definition array.h:144
The global header file for ARTS.
void chk_size(const String &x_name, ConstVectorView x, const Index &c)
Runtime check for size of Vector.
This can be used to make arrays out of anything.
Definition array.h:31
Index nelem() const ARTS_NOEXCEPT
Definition array.h:75
const Vector & get_numeric_grid(Index i) const
Get a numeric grid.
void split(Array< my_basic_string< charT > > &aos, const my_basic_string< charT > &delim) const
Definition mystring.h:112
void parse_atmcompact_speciesname(String &species_name, const String &field_name, const String &delim)
Definition cloudbox.cc:812
void chk_scat_species(const ArrayOfString &scat_species, const String &delim)
Check validity of scat_species setting.
Definition cloudbox.cc:198
void chk_scat_species_field(bool &empty_flag, const Tensor3 &scat_species_field, const String &fieldname, const Index &dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid)
Check whether field of a specific scattering species zero everywhere.
Definition cloudbox.cc:590
void chk_scattering_meta_data(const ScatteringMetaData &scat_meta_single, const String &scat_meta_file, const Verbosity &verbosity)
Check scattering data meta.
Definition cloudbox.cc:243
void find_cloudlimits(Index &lower, Index &upper, const Tensor3 &scat_species_field, const Index &atmosphere_dim, const Numeric &cloudbox_margin)
Adjust uppermost and lowermost cloudy level for one scat_species_*_*_field.
Definition cloudbox.cc:649
void chk_pnd_field_raw_only_in_cloudbox(const Index &dim, const ArrayOfGriddedField3 &pnd_field_raw, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, const ArrayOfIndex &cloudbox_limits)
chk_pnd_field_raw_only_in_cloudbox
Definition cloudbox.cc:123
void parse_partfield_name(String &partfield_name, const String &part_string, const String &delim)
Definition cloudbox.cc:874
void chk_pnd_raw_data(const ArrayOfGriddedField3 &pnd_field_raw, const String &pnd_field_file, const Index &atmosphere_dim, const Verbosity &verbosity)
Check particle number density files (pnd_field_raw)
Definition cloudbox.cc:93
void parse_atmcompact_speciestype(String &species_type, const String &field_name, const String &delim)
Definition cloudbox.cc:781
bool is_inside_cloudbox(const Ppath &ppath_step, const ArrayOfIndex &cloudbox_limits, const bool include_boundaries)
Definition cloudbox.cc:523
void parse_atmcompact_scattype(String &scat_type, const String &field_name, const String &delim)
Definition cloudbox.cc:843
void chk_scat_data(const SingleScatteringData &scat_data_single, const Verbosity &verbosity)
Check single scattering data.
Definition cloudbox.cc:275
void chk_scattering_data(const ArrayOfSingleScatteringData &scat_data, const ArrayOfScatteringMetaData &scat_meta, const Verbosity &)
Check scattering data general.
Definition cloudbox.cc:224
void chk_pnd_data(const GriddedField3 &pnd_field_raw, const String &pnd_field_file, const Index &atmosphere_dim, const Verbosity &verbosity)
Check particle number density files.
Definition cloudbox.cc:50
void bin_quadweights(Vector &w, const Vector &x, const Index &order)
Definition cloudbox.cc:555
bool is_gp_inside_cloudbox(const GridPos &gp_p, const GridPos &gp_lat, const GridPos &gp_lon, const ArrayOfIndex &cloudbox_limits, const bool &include_boundaries, const Index &atmosphere_dim)
Definition cloudbox.cc:443
Internal cloudbox functions.
#define _U_
Definition config.h:177
#define ARTS_ASSERT(condition,...)
Definition debug.h:86
#define ARTS_USER_ERROR(...)
Definition debug.h:153
#define ARTS_USER_ERROR_IF(condition,...)
Definition debug.h:137
Implementation of gridded fields.
Numeric fractional_gp(const GridPos &gp)
fractional_gp
Numeric last(ConstVectorView x)
last
Workspace functions for the solution of cloud-box radiative transfer by Monte Carlo methods....
Declarations having to do with the four output streams.
#define CREATE_OUT3
Definition messages.h:189
constexpr Index GFIELD3_LON_GRID
Global constant, Index of the longitude grid in GriddedField3.
constexpr Index GFIELD3_P_GRID
Global constant, Index of the pressure grid in GriddedField3.
constexpr Index GFIELD3_LAT_GRID
Global constant, Index of the latitude grid in GriddedField3.
@ PTYPE_GENERAL
@ PTYPE_AZIMUTH_RND
@ PTYPE_TOTAL_RND
This file contains declerations of functions of physical character.
Propagation path structure and functions.
Contains sorting routines.
Structure to store a grid position.
The structure to describe a propagation path and releated quantities.
ArrayOfGridPos gp_lon
Index position with respect to the longitude grid.
Index np
Number of points describing the ppath.
ArrayOfGridPos gp_lat
Index position with respect to the latitude grid.
ArrayOfGridPos gp_p
Index position with respect to the pressure grid.
#define v
#define w