71 Index& doit_za_grid_size,
75 const Index& N_za_grid,
76 const Index& N_aa_grid,
77 const String& za_grid_opt_file,
83 else if (N_aa_grid < 1) {
85 os <<
"N_aa_grid must be > 0 (even for 1D / DISORT cases).";
86 throw runtime_error(os.
str());
96 os <<
"N_za_grid must be >= 0.";
97 throw runtime_error(os.
str());
99 doit_za_grid_size = N_za_grid;
101 if (za_grid_opt_file ==
"")
104 else if (N_za_grid == 1) {
106 os <<
"N_za_grid must be >1 or =0 (the latter only allowed for RT4).";
107 throw runtime_error(os.
str());
116 Index& doit_conv_flag,
117 Index& doit_iteration_counter,
120 const Tensor6& cloudbox_field_mono_old,
123 const Index& max_iterations,
124 const Index& throw_nonconv_error,
130 if (doit_conv_flag != 0)
132 "Convergence flag is non-zero, which means that this\n" 133 "WSM is not used correctly. *doit_conv_flagAbs* should\n" 134 "be used only in *doit_conv_test_agenda*\n");
140 const Index N_aa = cloudbox_field_mono.
nrows();
141 const Index stokes_dim = cloudbox_field_mono.
ncols();
144 if (epsilon.
nelem() != stokes_dim)
146 "You have to specify limiting values for the " 147 "convergence test for each Stokes component " 148 "separately. That means that *epsilon* must " 149 "have *stokes_dim* elements!");
153 cloudbox_field_mono_old, N_p, N_lat, N_lon, N_za, N_aa, stokes_dim))
155 "The fields (Tensor6) *cloudbox_field* and \n" 156 "*cloudbox_field_old* which are compared in the \n" 157 "convergence test do not have the same size.\n");
161 doit_iteration_counter += 1;
162 out2 <<
" Number of DOIT iteration: " << doit_iteration_counter <<
"\n";
164 if (doit_iteration_counter > max_iterations) {
166 out <<
"Method does not converge (number of iterations \n" 167 <<
"is > " << max_iterations <<
"). Either the cloud " 168 <<
"particle number density \n" 169 <<
"is too large or the numerical setup for the DOIT \n" 170 <<
"calculation is not correct. In case of limb \n" 171 <<
"simulations please make sure that you use an \n" 172 <<
"optimized zenith angle grid. \n" 173 <<
"*cloudbox_field* might be wrong.\n";
174 if (throw_nonconv_error != 0) {
180 out1 <<
"Warning in DOIT calculation (output set to NaN):\n" << out.
str();
181 cloudbox_field_mono = NAN;
184 out1 <<
"Warning in DOIT calculation (output equals current status):\n" 189 for (
Index p_index = 0; p_index < N_p; p_index++) {
190 for (
Index lat_index = 0; lat_index < N_lat; lat_index++) {
191 for (
Index lon_index = 0; lon_index < N_lon; lon_index++) {
192 for (
Index za_index = 0; za_index < N_za; za_index++) {
193 for (
Index aa_index = 0; aa_index < N_aa; aa_index++) {
194 for (
Index stokes_index = 0; stokes_index < stokes_dim;
196 Numeric diff = (cloudbox_field_mono(p_index,
202 cloudbox_field_mono_old(p_index,
213 if (
abs(diff) > epsilon[stokes_index]) {
214 out1 <<
"difference: " << diff <<
"\n";
232 Index& doit_conv_flag,
233 Index& doit_iteration_counter,
236 const Tensor6& cloudbox_field_mono_old,
238 const Index& f_index,
241 const Index& max_iterations,
242 const Index& throw_nonconv_error,
249 if (doit_conv_flag != 0)
251 "Convergence flag is non-zero, which means that this \n" 252 "WSM is not used correctly. *doit_conv_flagAbs* should\n" 253 "be used only in *doit_conv_test_agenda*\n");
259 const Index N_aa = cloudbox_field_mono.
nrows();
260 const Index stokes_dim = cloudbox_field_mono.
ncols();
263 if (epsilon.
nelem() != stokes_dim)
265 "You have to specify limiting values for the " 266 "convergence test for each Stokes component " 267 "separately. That means that *epsilon* must " 268 "have *stokes_dim* elements!");
272 cloudbox_field_mono_old, N_p, N_lat, N_lon, N_za, N_aa, stokes_dim))
274 "The fields (Tensor6) *cloudbox_field* and \n" 275 "*cloudbox_field_old* which are compared in the \n" 276 "convergence test do not have the same size.\n");
280 if (f_grid.
empty())
throw runtime_error(
"The frequency grid is empty.");
284 if (f_index >= f_grid.
nelem())
286 "*f_index* is greater than number of elements in the\n" 287 "frequency grid.\n");
291 doit_iteration_counter += 1;
292 out2 <<
" Number of DOIT iteration: " << doit_iteration_counter <<
"\n";
295 if (doit_iteration_counter > max_iterations) {
297 out <<
"At frequency " << f_grid[f_index] <<
" GHz \n" 298 <<
"method does not converge (number of iterations \n" 299 <<
"is > " << max_iterations <<
"). Either the particle" 300 <<
" number density \n" 301 <<
"is too large or the numerical setup for the DOIT \n" 302 <<
"calculation is not correct. In case of limb \n" 303 <<
"simulations please make sure that you use an \n" 304 <<
"optimized zenith angle grid. \n" 305 <<
"*cloudbox_field* might be wrong.\n";
306 if (throw_nonconv_error != 0) {
312 out1 <<
"Warning in DOIT calculation (output set to NaN):\n" << out.
str();
313 cloudbox_field_mono = NAN;
316 out1 <<
"Warning in DOIT calculation (output equals current status):\n" 321 for (
Index p_index = 0; p_index < N_p; p_index++) {
322 for (
Index lat_index = 0; lat_index < N_lat; lat_index++) {
323 for (
Index lon_index = 0; lon_index < N_lon; lon_index++) {
324 for (
Index za_index = 0; za_index < N_za; za_index++) {
325 for (
Index aa_index = 0; aa_index < N_aa; aa_index++) {
326 for (
Index stokes_index = 0; stokes_index < stokes_dim;
328 Numeric diff = cloudbox_field_mono(p_index,
334 cloudbox_field_mono_old(p_index,
347 if (
abs(diff_bt) > epsilon[stokes_index]) {
348 out1 <<
"BT difference: " << diff_bt <<
" in stokes dim " 349 << stokes_index <<
"\n";
371 Index& doit_conv_flag,
372 Index& doit_iteration_counter,
375 const Tensor6& cloudbox_field_mono_old,
377 const Index& f_index,
380 const Index& max_iterations,
381 const Index& throw_nonconv_error,
388 if (doit_conv_flag != 0)
390 "Convergence flag is non-zero, which means that this \n" 391 "WSM is not used correctly. *doit_conv_flagAbs* should\n" 392 "be used only in *doit_conv_test_agenda*\n");
398 const Index N_aa = cloudbox_field_mono.
nrows();
399 const Index stokes_dim = cloudbox_field_mono.
ncols();
402 if (epsilon.
nelem() != stokes_dim)
404 "You have to specify limiting values for the " 405 "convergence test for each Stokes component " 406 "separately. That means that *epsilon* must " 407 "have *stokes_dim* elements!");
411 cloudbox_field_mono_old, N_p, N_lat, N_lon, N_za, N_aa, stokes_dim))
413 "The fields (Tensor6) *cloudbox_field* and \n" 414 "*cloudbox_field_old* which are compared in the \n" 415 "convergence test do not have the same size.\n");
419 if (f_grid.
empty())
throw runtime_error(
"The frequency grid is empty.");
423 if (f_index >= f_grid.
nelem())
425 "*f_index* is greater than number of elements in the\n" 426 "frequency grid.\n");
430 doit_iteration_counter += 1;
431 out2 <<
" Number of DOIT iteration: " << doit_iteration_counter <<
"\n";
433 if (doit_iteration_counter > max_iterations) {
435 out <<
"Method does not converge (number of iterations \n" 436 <<
"is > " << max_iterations <<
"). Either the" 437 <<
" particle number density \n" 438 <<
"is too large or the numerical setup for the DOIT \n" 439 <<
"calculation is not correct. In case of limb \n" 440 <<
"simulations please make sure that you use an \n" 441 <<
"optimized zenith angle grid. \n";
442 if (throw_nonconv_error != 0) {
448 out1 <<
"Warning in DOIT calculation (output set to NaN):\n" << out.
str();
449 cloudbox_field_mono = NAN;
452 out1 <<
"Warning in DOIT calculation (output equals current status):\n" 462 for (
Index p_index = 0; p_index < N_p; p_index++) {
463 for (
Index lat_index = 0; lat_index < N_lat; lat_index++) {
464 for (
Index lon_index = 0; lon_index < N_lon; lon_index++) {
465 for (
Index za_index = 0; za_index < N_za; za_index++) {
466 for (
Index aa_index = 0; aa_index < N_aa; aa_index++) {
469 p_index, lat_index, lon_index, za_index, aa_index,
i) -
470 cloudbox_field_mono_old(p_index,
484 lqs[i] /= (
Numeric)(N_p * N_lat * N_lon * N_za * N_aa);
489 if (lqs[i] >= epsilon[i]) doit_conv_flag = 0;
492 out1 <<
"lqs [I]: " << lqs[0] <<
"\n";
502 const Agenda& doit_scat_field_agenda,
503 const Agenda& doit_rte_agenda,
504 const Agenda& doit_conv_test_agenda,
505 const Index& accelerated,
512 chk_not_empty(
"doit_scat_field_agenda", doit_scat_field_agenda);
514 chk_not_empty(
"doit_conv_test_agenda", doit_conv_test_agenda);
518 for (
Index b = 0; b < cloudbox_field_mono.
nbooks(); b++)
519 for (
Index p = 0; p < cloudbox_field_mono.
npages(); p++)
521 for (
Index c = 0; c < cloudbox_field_mono.
ncols(); c++)
522 if (std::isnan(cloudbox_field_mono(v, s, b, p,
r, c)))
523 throw std::runtime_error(
524 "*cloudbox_field_mono* contains at least one NaN value.\n" 525 "This indicates an improper initialization of *cloudbox_field*.");
532 Tensor6 cloudbox_field_mono_old_local;
533 Index doit_conv_flag_local;
534 Index doit_iteration_counter_local;
540 cloudbox_field_mono.
nbooks(),
541 cloudbox_field_mono.
npages(),
542 cloudbox_field_mono.
nrows(),
543 cloudbox_field_mono.
ncols(),
546 doit_conv_flag_local = 0;
547 doit_iteration_counter_local = 0;
551 acceleration_input.resize(4);
553 while (doit_conv_flag_local == 0) {
555 cloudbox_field_mono_old_local = cloudbox_field_mono;
560 out2 <<
" Execute doit_scat_field_agenda. \n";
562 ws, doit_scat_field_local, cloudbox_field_mono, doit_scat_field_agenda);
565 out2 <<
" Execute doit_rte_agenda. \n";
567 ws, cloudbox_field_mono, doit_scat_field_local, doit_rte_agenda);
571 doit_conv_flag_local,
572 doit_iteration_counter_local,
574 cloudbox_field_mono_old_local,
575 doit_conv_test_agenda);
578 if (accelerated > 0 && doit_conv_flag_local == 0) {
579 acceleration_input[(doit_iteration_counter_local - 1) % 4] =
582 if (doit_iteration_counter_local % 4 == 0) {
584 cloudbox_field_mono, acceleration_input, accelerated, verbosity);
596 const Tensor6& doit_scat_field,
599 const Agenda& propmat_clearsky_agenda,
602 const Agenda& spt_calc_agenda,
606 const Agenda& ppath_step_agenda,
608 const Numeric& ppath_lraytrace,
611 const Vector& refellipsoid,
615 const Index& f_index,
616 const Agenda& surface_rtprop_agenda,
617 const Index& doit_za_interp,
623 <<
" cloudbox_fieldUpdate1D: Radiative transfer calculation in cloudbox\n";
624 out2 <<
" ------------------------------------------------------------- \n";
632 if (cloudbox_limits.
nelem() != 2)
634 "The cloudbox dimension is not 1D! \n" 635 "Do you really want to do a 1D calculation? \n" 636 "If not, use *cloudbox_fieldUpdateSeq3D*.\n");
641 if (za_grid[0] != 0. || za_grid[N_scat_za - 1] != 180.)
642 throw runtime_error(
"The range of *za_grid* must [0 180].");
644 if (p_grid.
nelem() < 2)
645 throw runtime_error(
"The length of *p_grid* must be >= 2.");
653 if (f_grid.
empty())
throw runtime_error(
"The frequency grid is empty.");
657 if (f_index >= f_grid.
nelem())
659 "*f_index* is greater than number of elements in the\n" 660 "frequency grid.\n");
662 if (!(doit_za_interp == 0 || doit_za_interp == 1))
664 "Interpolation method is not defined. Use \n" 665 "*doit_za_interpSet*.\n");
667 const Index stokes_dim = doit_scat_field.
ncols();
668 assert(stokes_dim > 0 || stokes_dim < 5);
671 assert(
is_size(cloudbox_field_mono,
672 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
679 assert(
is_size(doit_scat_field,
680 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
694 out3 <<
"Calculate optical properties of individual scattering elements\n";
704 Tensor5 ext_mat_field(cloudbox_limits[1] - cloudbox_limits[0] + 1,
711 cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1, stokes_dim, 0.);
713 Tensor6 cloudbox_field_old(cloudbox_field_mono);
716 Index aa_index_local = 0;
719 for (
Index za_index_local = 0; za_index_local < N_scat_za; za_index_local++) {
738 for (
Index p_index = cloudbox_limits[0]; p_index <= cloudbox_limits[1];
740 if ((p_index != 0) || (za_grid[za_index_local] <= 90.)) {
749 propmat_clearsky_agenda,
762 surface_rtprop_agenda,
779 const Agenda& propmat_clearsky_agenda,
782 const Agenda& spt_calc_agenda,
787 const Agenda& ppath_step_agenda,
789 const Numeric& ppath_lraytrace,
792 const Vector& refellipsoid,
796 const Index& f_index,
797 const Agenda& surface_rtprop_agenda,
798 const Index& doit_za_interp,
799 const Index& normalize,
800 const Numeric& norm_error_threshold,
801 const Index& norm_debug,
807 <<
" cloudbox_fieldUpdateSeq1D: Radiative transfer calculation in cloudbox\n";
808 out2 <<
" ------------------------------------------------------------- \n";
813 chk_not_empty(
"propmat_clearsky_agenda", propmat_clearsky_agenda);
817 if (cloudbox_limits.
nelem() != 2)
819 "The cloudbox dimension is not 1D! \n" 820 "Do you really want to do a 1D calculation? \n" 821 "For 3D use *cloudbox_fieldUpdateSeq3D*.\n");
826 if (za_grid[0] != 0. || za_grid[N_scat_za - 1] != 180.)
827 throw runtime_error(
"The range of *za_grid* must [0 180].");
829 if (p_grid.
nelem() < 2)
830 throw runtime_error(
"The length of *p_grid* must be >= 2.");
838 if (f_grid.
empty())
throw runtime_error(
"The frequency grid is empty.");
842 if (f_index >= f_grid.
nelem())
844 "*f_index* is greater than number of elements in the\n" 845 "frequency grid.\n");
847 if (!(doit_za_interp == 0 || doit_za_interp == 1))
849 "Interpolation method is not defined. Use \n" 850 "*doit_za_interpSet*.\n");
852 const Index stokes_dim = doit_scat_field.
ncols();
853 assert(stokes_dim > 0 || stokes_dim < 5);
856 assert(
is_size(cloudbox_field_mono,
857 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
864 assert(
is_size(doit_scat_field,
865 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
879 out3 <<
"Calculate optical properties of individual scattering elements\n";
889 Tensor5 ext_mat_field(cloudbox_limits[1] - cloudbox_limits[0] + 1,
896 cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1, stokes_dim, 0.);
901 180. - asin((refellipsoid[0] + z_field(cloudbox_limits[0], 0, 0)) /
902 (refellipsoid[0] + z_field(cloudbox_limits[1], 0, 0))) *
912 Matrix cloudbox_field_limb;
915 Index aa_index_local = 0;
929 norm_error_threshold,
935 for (
Index za_index_local = 0; za_index_local < N_scat_za; za_index_local++) {
955 if (za_grid[za_index_local] <= 90.) {
961 for (
Index p_index = cloudbox_limits[1] - 1;
962 p_index >= cloudbox_limits[0];
971 propmat_clearsky_agenda,
984 surface_rtprop_agenda,
988 }
else if (za_grid[za_index_local] >= theta_lim) {
992 for (
Index p_index = cloudbox_limits[0] + 1;
993 p_index <= cloudbox_limits[1];
1002 propmat_clearsky_agenda,
1015 surface_rtprop_agenda,
1029 bool conv_flag =
false;
1031 while (!conv_flag && limb_it < 10) {
1033 cloudbox_field_limb =
1034 cloudbox_field_mono(
joker, 0, 0, za_index_local, 0,
joker);
1035 for (
Index p_index = cloudbox_limits[0]; p_index <= cloudbox_limits[1];
1043 cloudbox_field_mono,
1049 propmat_clearsky_agenda,
1062 surface_rtprop_agenda,
1069 for (
Index p_index = 0;
1070 conv_flag && p_index < cloudbox_field_mono.
nvitrines();
1072 for (
Index stokes_index = 0; conv_flag && stokes_index < stokes_dim;
1074 Numeric diff = cloudbox_field_mono(
1075 p_index, 0, 0, za_index_local, 0, stokes_index) -
1076 cloudbox_field_limb(p_index, stokes_index);
1082 if (
abs(diff_bt) > epsilon[stokes_index]) {
1083 out2 <<
"Limb BT difference: " << diff_bt <<
" in stokes dim " 1084 << stokes_index <<
"\n";
1090 out2 <<
"Limb iterations: " << limb_it <<
"\n";
1101 const Tensor6& doit_scat_field,
1104 const Agenda& propmat_clearsky_agenda,
1107 const Agenda& spt_calc_agenda,
1112 const Agenda& ppath_step_agenda,
1114 const Numeric& ppath_lraytrace,
1119 const Vector& refellipsoid,
1123 const Index& f_index,
1124 const Index& doit_za_interp,
1130 <<
" cloudbox_fieldUpdateSeq3D: Radiative transfer calculatiuon in cloudbox.\n";
1131 out2 <<
" ------------------------------------------------------------- \n";
1136 chk_not_empty(
"propmat_clearsky_agenda", propmat_clearsky_agenda);
1140 if (cloudbox_limits.
nelem() != 6)
1141 throw runtime_error(
1142 "The cloudbox dimension is not 3D! \n" 1143 "Do you really want to do a 3D calculation? \n" 1144 "For 1D use *cloudbox_fieldUpdateSeq1D*.\n");
1149 if (za_grid[0] != 0. || za_grid[N_scat_za - 1] != 180.)
1150 throw runtime_error(
"The range of *za_grid* must [0 180].");
1155 if (aa_grid[0] != 0. || aa_grid[N_scat_aa - 1] != 360.)
1156 throw runtime_error(
"The range of *za_grid* must [0 360].");
1163 "z_field", z_field, p_grid.
nelem(), lat_grid.
nelem(), lon_grid.
nelem());
1165 "t_field", t_field, p_grid.
nelem(), lat_grid.
nelem(), lon_grid.
nelem());
1169 if (f_grid.
empty())
throw runtime_error(
"The frequency grid is empty.");
1173 if (f_index >= f_grid.
nelem())
1174 throw runtime_error(
1175 "*f_index* is greater than number of elements in the\n" 1176 "frequency grid.\n");
1178 if (!(doit_za_interp == 0 || doit_za_interp == 1))
1179 throw runtime_error(
1180 "Interpolation method is not defined. Use \n" 1181 "*doit_za_interpSet*.\n");
1183 const Index stokes_dim = doit_scat_field.
ncols();
1184 assert(stokes_dim > 0 || stokes_dim < 5);
1187 assert(
is_size(cloudbox_field_mono,
1188 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
1189 (cloudbox_limits[3] - cloudbox_limits[2]) + 1,
1190 (cloudbox_limits[5] - cloudbox_limits[4]) + 1,
1195 assert(
is_size(doit_scat_field,
1196 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
1197 (cloudbox_limits[3] - cloudbox_limits[2]) + 1,
1198 (cloudbox_limits[5] - cloudbox_limits[4]) + 1,
1210 out3 <<
"Calculate optical properties of individual scattering elements\n";
1220 const Index p_low = cloudbox_limits[0];
1221 const Index p_up = cloudbox_limits[1];
1222 const Index lat_low = cloudbox_limits[2];
1223 const Index lat_up = cloudbox_limits[3];
1224 const Index lon_low = cloudbox_limits[4];
1225 const Index lon_up = cloudbox_limits[5];
1229 Tensor5 ext_mat_field(p_up - p_low + 1,
1230 lat_up - lat_low + 1,
1231 lon_up - lon_low + 1,
1235 Tensor4 abs_vec_field(p_up - p_low + 1,
1236 lat_up - lat_low + 1,
1237 lon_up - lon_low + 1,
1242 for (
Index za_index = 0; za_index < N_scat_za; za_index++) {
1245 for (
Index aa_index = 1; aa_index < N_scat_aa; aa_index++) {
1264 Vector stokes_vec(stokes_dim, 0.);
1266 Numeric theta_lim = 180. - asin((refellipsoid[0] + z_field(p_low, 0, 0)) /
1267 (refellipsoid[0] + z_field(p_up, 0, 0))) *
1271 if (za_grid[za_index] <= 90.) {
1277 for (
Index p_index = p_up - 1; p_index >= p_low; p_index--) {
1278 for (
Index lat_index = lat_low; lat_index <= lat_up; lat_index++) {
1279 for (
Index lon_index = lon_low; lon_index <= lon_up; lon_index++) {
1281 cloudbox_field_mono,
1291 propmat_clearsky_agenda,
1312 else if (za_grid[za_index] > theta_lim) {
1316 for (
Index p_index = p_low + 1; p_index <= p_up; p_index++) {
1317 for (
Index lat_index = lat_low; lat_index <= lat_up; lat_index++) {
1318 for (
Index lon_index = lon_low; lon_index <= lon_up; lon_index++) {
1320 cloudbox_field_mono,
1330 propmat_clearsky_agenda,
1359 else if (za_grid[za_index] > 90. && za_grid[za_index] < theta_lim) {
1360 for (
Index p_index = p_low; p_index <= p_up; p_index++) {
1365 if (!(p_index == 0 && za_grid[za_index] > 90.)) {
1366 for (
Index lat_index = lat_low; lat_index <= lat_up; lat_index++) {
1367 for (
Index lon_index = lon_low; lon_index <= lon_up;
1370 cloudbox_field_mono,
1380 propmat_clearsky_agenda,
1417 const Tensor6& doit_scat_field,
1420 const Agenda& propmat_clearsky_agenda,
1423 const Agenda& spt_calc_agenda,
1432 const Index& f_index,
1438 <<
" cloudbox_fieldUpdateSeq1DPP: Radiative transfer calculation in cloudbox.\n";
1440 <<
" --------------------------------------------------------------------- \n";
1442 const Index stokes_dim = doit_scat_field.
ncols();
1447 if (stokes_dim < 0 || stokes_dim > 4)
1448 throw runtime_error(
1449 "The dimension of stokes vector must be" 1452 assert(
is_size(cloudbox_field_mono,
1453 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
1460 assert(
is_size(doit_scat_field,
1461 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
1469 assert(f_index <= f_grid.
nelem());
1479 out3 <<
"Calculate optical properties of individual scattering elements\n";
1490 Tensor5 ext_mat_field(cloudbox_limits[1] - cloudbox_limits[0] + 1,
1497 cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1, stokes_dim, 0.);
1500 for (za_index = 0; za_index < N_scat_za; za_index++) {
1519 Vector stokes_vec(stokes_dim, 0.);
1521 if (za_grid[za_index] <= 90) {
1530 for (
Index p_index = cloudbox_limits[1] - 1;
1531 p_index >= cloudbox_limits[0];
1534 cloudbox_field_mono,
1540 propmat_clearsky_agenda,
1551 }
else if (za_grid[za_index] > 90) {
1555 for (
Index p_index = cloudbox_limits[0] + 1;
1556 p_index <= cloudbox_limits[1];
1559 cloudbox_field_mono,
1565 propmat_clearsky_agenda,
1585 Index& doit_is_initialized,
1587 const Index& stokes_dim,
1588 const Index& atmosphere_dim,
1592 const Index& doit_za_grid_size,
1593 const Index& cloudbox_on,
1598 doit_is_initialized = 0;
1599 out0 <<
" Cloudbox is off, DOIT calculation will be skipped.\n";
1607 if (stokes_dim < 0 || stokes_dim > 4)
1608 throw runtime_error(
1609 "The dimension of stokes vector must be" 1621 throw runtime_error(
1622 "For accurate results, za_grid must have " 1623 "more than 15 elements.");
1624 else if (N_scat_za > 100) {
1626 out1 <<
"Warning: za_grid is very large, which means that the \n" 1627 <<
"calculation will be very slow.\n";
1630 if (za_grid[0] != 0. || za_grid[N_scat_za - 1] != 180.)
1631 throw runtime_error(
"The range of *za_grid* must [0 180].");
1634 throw runtime_error(
"*za_grid* must be increasing.");
1640 throw runtime_error(
1641 "For accurate results, aa_grid must have " 1642 "more than 5 elements.");
1643 else if (N_scat_aa > 100) {
1645 out1 <<
"Warning: aa_grid is very large which means that the \n" 1646 <<
"calculation will be very slow.\n";
1649 if (aa_grid[0] != 0. || aa_grid[N_scat_aa - 1] != 360.)
1650 throw runtime_error(
"The range of *aa_grid* must [0 360].");
1652 if (doit_za_grid_size < 16)
1653 throw runtime_error(
1654 "*doit_za_grid_size* must be greater than 15 for accurate results");
1655 else if (doit_za_grid_size > 100) {
1657 out1 <<
"Warning: doit_za_grid_size is very large which means that the \n" 1658 <<
"calculation will be very slow.\n";
1661 if (cloudbox_limits.
nelem() != 2 * atmosphere_dim)
1662 throw runtime_error(
1663 "*cloudbox_limits* is a vector which contains the" 1664 "upper and lower limit of the cloud for all " 1665 "atmospheric dimensions. So its dimension must" 1666 "be 2 x *atmosphere_dim*");
1671 const Index Np_cloud = cloudbox_limits[1] - cloudbox_limits[0] + 1;
1673 const Index Ns = stokes_dim;
1676 if (atmosphere_dim == 1) {
1677 cloudbox_field.
resize(Nf, Np_cloud, 1, 1, Nza, 1, Ns);
1678 doit_scat_field.
resize(Np_cloud, 1, 1, Nza, 1, Ns);
1679 }
else if (atmosphere_dim == 3) {
1680 const Index Nlat_cloud = cloudbox_limits[3] - cloudbox_limits[2] + 1;
1681 const Index Nlon_cloud = cloudbox_limits[5] - cloudbox_limits[4] + 1;
1684 cloudbox_field.
resize(Nf, Np_cloud, Nlat_cloud, Nlon_cloud, Nza, Naa, Ns);
1685 doit_scat_field.
resize(Np_cloud, Nlat_cloud, Nlon_cloud, Nza, Naa, Ns);
1687 throw runtime_error(
1688 "Scattering calculations are not possible for a 2D" 1689 "atmosphere. If you want to do scattering calculations" 1690 "*atmosphere_dim* has to be either 1 or 3");
1693 cloudbox_field = NAN;
1694 doit_scat_field = NAN;
1695 doit_is_initialized = 1;
1701 const Vector& p_grid_orig,
1705 Tensor6 cloudbox_field_mono_opt(
1706 p_grid_orig.
nelem(), 1, 1, cloudbox_field_mono.
npages(), 1, 1);
1708 Matrix itw_z(Z_gp.nelem(), 2);
1712 cloudbox_limits[0], cloudbox_limits[1] - cloudbox_limits[0] + 1)];
1714 os <<
"There is a problem with the pressure grid interpolation";
1718 gridpos(Z_gp, p_grid_cloudbox, p_grid_orig);
1725 cloudbox_field_mono(
joker, 0, 0,
i, 0, 0),
1728 cloudbox_field_mono = cloudbox_field_mono_opt;
1746 const Index& f_index,
1747 const Agenda& propmat_clearsky_agenda,
1750 const Index& cloudbox_size_max,
1755 if (cloudbox_field_mono.
ncols() != 1)
1756 throw runtime_error(
1757 " This method currently only works for unpolarized radiation " 1758 "( stokes_dim = 1)");
1761 if (scat_data_mono.
nelem() > 1 ||
1762 pnd_field.
nbooks() != cloudbox_limits[1] - cloudbox_limits[0] + 1)
1763 throw runtime_error(
1764 " ScatSpeciesMerge has to be applied in order to use this method");
1766 bool was_too_much =
false;
1767 Numeric tau_scat_max_internal = tau_scat_max;
1769 p_grid_orig = p_grid;
1770 vector<Numeric> z_grid_new;
1771 Vector ext_mat(cloudbox_limits[1] - cloudbox_limits[0] + 1);
1772 Vector abs_vec(cloudbox_limits[1] - cloudbox_limits[0] + 1);
1773 Vector scat_vec(cloudbox_limits[1] - cloudbox_limits[0] + 1);
1775 z_grid_new.reserve(1000);
1776 for (
Index i = 0;
i < cloudbox_limits[0];
i++)
1777 z_grid_new.push_back(z_field(
i, 0, 0));
1783 const Vector rtp_mag_dummy(3, 0);
1784 const Vector ppath_los_dummy;
1791 Index scat_data_insert_offset = 0;
1792 Vector single_scattering_albedo(cloudbox_limits[1] - cloudbox_limits[0] + 1,
1794 for (
Index k = cloudbox_limits[0]; k < cloudbox_limits[1] + 1; ++k) {
1795 Index cloudbox_index = k - cloudbox_limits[0];
1798 ext_mat[cloudbox_index] =
1799 scat_data_local[cloudbox_index].ext_mat_data(0, 0, 0, 0, 0);
1800 abs_vec[cloudbox_index] =
1801 scat_data_local[cloudbox_index].abs_vec_data(0, 0, 0, 0, 0);
1802 scat_vec[cloudbox_index] =
1803 ext_mat[cloudbox_index] - abs_vec[cloudbox_index];
1806 cur_propmat_clearsky,
1809 partial_source_dummy,
1812 f_grid[
Range(f_index, 1)],
1818 vmr_field(
joker, k, 0, 0),
1819 propmat_clearsky_agenda);
1820 for (
auto&
pm : cur_propmat_clearsky) {
1821 abs_coeff +=
pm.Kjj()[0];
1823 abs_coeff /= (
Numeric)cur_propmat_clearsky.nelem();
1824 single_scattering_albedo[cloudbox_index] =
1825 scat_vec[cloudbox_index] / (ext_mat[cloudbox_index] + abs_coeff);
1831 scat_data_insert_offset = 0;
1832 for (
Index k = cloudbox_limits[0]; k < cloudbox_limits[1]; ++k) {
1833 Index cloudbox_index = k - cloudbox_limits[0];
1834 const Numeric sgl_alb = (single_scattering_albedo[cloudbox_index] +
1835 single_scattering_albedo[cloudbox_index + 1]) /
1838 (z_field(k + 1, 0, 0) - z_field(k, 0, 0)) *
1839 ((scat_vec[cloudbox_index] + scat_vec[cloudbox_index + 1]) / 2);
1840 if (scat_opt_thk > tau_scat_max_internal && sgl_alb > sgl_alb_max) {
1841 Index factor = (
Index)ceil(scat_opt_thk / tau_scat_max_internal);
1842 for (
Index j = 1; j < factor; j++) {
1843 scat_data_insert_offset++;
1848 if (scat_data_insert_offset + cloudbox_limits[1] - cloudbox_limits[0] + 1 >
1849 cloudbox_size_max) {
1850 tau_scat_max_internal += 0.01;
1851 was_too_much =
true;
1853 }
while (scat_data_insert_offset + cloudbox_limits[1] - cloudbox_limits[0] +
1856 scat_data_insert_offset = 0;
1860 <<
"Warning: Pressure grid optimization with the thresholds tau_scat_max = " 1861 << tau_scat_max <<
" and sgl_slb_max = " << sgl_alb_max
1862 <<
" has lead to an enhancement larger than the value of" 1863 <<
" cloudbox_size_max = " << cloudbox_size_max
1864 <<
". This is why I changed tau_scat_max to " << tau_scat_max_internal
1865 <<
". This may lead to errors of a too coarse grid! \n";
1871 for (
Index k = cloudbox_limits[0]; k < cloudbox_limits[1]; ++k) {
1872 Index cloudbox_index = k - cloudbox_limits[0];
1873 const Numeric sgl_alb = (single_scattering_albedo[cloudbox_index] +
1874 single_scattering_albedo[cloudbox_index + 1]) /
1877 (z_field(k + 1, 0, 0) - z_field(k, 0, 0)) *
1878 ((scat_vec[cloudbox_index] + scat_vec[cloudbox_index + 1]) / 2);
1879 z_grid_new.push_back(z_field(k, 0, 0));
1881 if (scat_opt_thk > tau_scat_max_internal && sgl_alb > sgl_alb_max) {
1882 Index factor = (
Index)ceil(scat_opt_thk / tau_scat_max_internal);
1884 (z_field(k + 1, 0, 0) - z_field(k, 0, 0)) / (
Numeric)factor;
1886 scat_data_local[cloudbox_index + scat_data_insert_offset + 1];
1888 scat_data_local[cloudbox_index + scat_data_insert_offset];
1890 for (
Index j = 1; j < factor; j++) {
1891 z_grid_new.push_back(z_field(k, 0, 0) + (
Numeric)j * step);
1899 weightednextLayerPhamat *= weight;
1900 weightednextLayerExtmat *= weight;
1901 weightednextLayerAbsvec *= weight;
1912 scat_data_local.insert(scat_data_local.begin() + cloudbox_index +
1913 scat_data_insert_offset + 1,
1914 std::move(newLayer));
1916 scat_data_insert_offset++;
1921 cloudbox_limits_opt[0] = cloudbox_limits[0];
1922 cloudbox_limits_opt[1] = scat_data_insert_offset + cloudbox_limits[1];
1923 const Index cloudbox_opt_size =
1924 cloudbox_limits_opt[1] - cloudbox_limits_opt[0] + 1;
1925 out3 <<
"Frequency: " << f_grid[f_index]
1926 <<
" old: " << cloudbox_limits[1] - cloudbox_limits[0] + 1
1927 <<
" new: " << cloudbox_opt_size <<
" Factor: " 1928 << (
Numeric)cloudbox_opt_size /
1929 (
Numeric)(cloudbox_limits[1] - cloudbox_limits[0] + 1)
1933 z_grid_new.push_back(z_field(
i, 0, 0));
1935 Vector z_grid(z_grid_new.size());
1936 for (
Index i = 0;
i < z_grid.nelem();
i++) z_grid[
i] = z_grid_new[
i];
1937 p_grid_orig = p_grid[
Range(cloudbox_limits[0],
1938 cloudbox_limits[1] - cloudbox_limits[0] + 1)];
1943 Tensor3 t_field_new(z_grid.nelem(), 1, 1);
1944 Vector p_grid_opt(z_grid.nelem());
1945 Tensor6 cloudbox_field_mono_opt(
1946 cloudbox_opt_size, 1, 1, cloudbox_field_mono.
npages(), 1, 1);
1947 Tensor7 pha_mat_doit_opt(cloudbox_opt_size,
1955 Matrix itw_z(Z_gp.nelem(), 2);
1957 os <<
"At the current frequency " << f_grid[f_index]
1958 <<
" there was an error while interpolating the fields to the new z_field";
1969 for (
Index k = cloudbox_limits_opt[0]; k < cloudbox_limits_opt[1]; k++) {
1970 Index i = k - cloudbox_limits[0];
1971 scat_data_local[i].T_grid = t_field_new(i, 0, 0);
1975 interp(p_grid_opt, itw_z, p_grid, Z_gp);
1978 Tensor4 vmr_field_opt(vmr_field.
nbooks(), p_grid_opt.nelem(), 1, 1);
1981 vmr_field_opt(
i,
joker, 0, 0), itw_z, vmr_field(
i,
joker, 0, 0), Z_gp);
1987 Range(cloudbox_limits[0], cloudbox_limits[1] - cloudbox_limits[0] + 1);
1988 Range r2 =
Range(cloudbox_limits_opt[0], cloudbox_opt_size);
1991 z_field(
Range(cloudbox_limits[0],
1992 cloudbox_limits[1] - cloudbox_limits[0] + 1),
1995 z_grid[
Range(cloudbox_limits_opt[0], cloudbox_opt_size)]);
2001 cloudbox_field_mono(
joker, 0, 0,
i, 0, 0),
2005 for (
Index j = 0; j < pha_mat_doit.
nbooks(); j++) {
2006 for (
Index k = 0; k < pha_mat_doit.
npages(); k++) {
2009 pha_mat_doit(
joker,
i, 0, j, k, 0, 0),
2016 pnd_field.
resize(cloudbox_opt_size, cloudbox_opt_size, 1, 1);
2018 for (
Index i = 0;
i < cloudbox_opt_size;
i++) pnd_field(
i,
i, 0, 0) = 1.;
2021 p_grid = p_grid_opt;
2022 t_field = t_field_new;
2023 cloudbox_limits = cloudbox_limits_opt;
2024 cloudbox_field_mono = cloudbox_field_mono_opt;
2025 pha_mat_doit = pha_mat_doit_opt;
2026 z_field.
resize(z_grid.nelem(), 1, 1);
2027 z_field(
joker, 0, 0) = z_grid;
2028 vmr_field = vmr_field_opt;
2033 const Index& doit_iteration_counter,
2034 const Tensor6& cloudbox_field_mono,
2035 const Index& f_index,
2040 if (!frequencies.
nelem() || !iterations.
nelem())
return;
2046 os <<
"doit_iteration_f" << f_index <<
"_i" << doit_iteration_counter;
2049 if (frequencies[0] == -1 && iterations[0] == -1) {
2054 for (
Index j = 0; j < frequencies.
nelem(); j++) {
2055 if (f_index == frequencies[j] || (!j && frequencies[j] == -1)) {
2057 if (iterations[0] == -1) {
2059 cloudbox_field_mono,
2068 if (doit_iteration_counter == iterations[
i])
2070 cloudbox_field_mono,
2085 const Agenda& pha_mat_spt_agenda,
2086 const Tensor6& cloudbox_field_mono,
2089 const Index& atmosphere_dim,
2093 const Index& doit_za_grid_size,
2109 if (za_grid[0] != 0. || za_grid[Nza - 1] != 180.)
2110 throw runtime_error(
"The range of *za_grid* must [0 180].");
2115 if (Naa > 1 && (aa_grid[0] != 0. || aa_grid[Naa - 1] != 360.))
2116 throw runtime_error(
"The range of *aa_grid* must [0 360].");
2119 const Index stokes_dim = doit_scat_field.
ncols();
2120 assert(stokes_dim > 0 || stokes_dim < 5);
2130 if (atmosphere_dim == 1) {
2131 assert(
is_size(cloudbox_field_mono,
2132 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
2138 assert(
is_size(doit_scat_field,
2139 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
2145 }
else if (atmosphere_dim == 3) {
2146 assert(
is_size(cloudbox_field_mono,
2147 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
2148 (cloudbox_limits[3] - cloudbox_limits[2]) + 1,
2149 (cloudbox_limits[5] - cloudbox_limits[4]) + 1,
2153 assert(
is_size(doit_scat_field,
2154 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
2155 (cloudbox_limits[3] - cloudbox_limits[2]) + 1,
2156 (cloudbox_limits[5] - cloudbox_limits[4]) + 1,
2162 os <<
"The atmospheric dimension must be 1D or 3D \n" 2163 <<
"for scattering calculations using the DOIT\n" 2164 <<
"module, but it is not. The value of *atmosphere_dim*\n" 2165 <<
"is " << atmosphere_dim <<
".";
2166 throw runtime_error(os.
str());
2169 if (cloudbox_limits.
nelem() != 2 * atmosphere_dim)
2170 throw runtime_error(
2171 "*cloudbox_limits* is a vector which contains the" 2172 "upper and lower limit of the cloud for all " 2173 "atmospheric dimensions. So its dimension must" 2174 "be 2 x *atmosphere_dim*");
2178 if (doit_za_grid_size != Nza)
2179 throw runtime_error(
2180 "The zenith angle grids for the computation of\n" 2181 "the scattering integral and the RT part must \n" 2182 "be equal. Check definitions in \n" 2183 "*DOAngularGridsSet*. The keyword \n" 2184 "'za_grid_opt_file' should be empty. \n");
2190 doit_za_grid_size, aa_grid.
nelem(), stokes_dim, stokes_dim, 0.);
2201 grid_stepsize[0] = 180. / (
Numeric)(doit_za_grid_size - 1);
2203 grid_stepsize[1] = 360. / (
Numeric)(Naa - 1);
2206 Tensor3 product_field(Nza, Naa, stokes_dim, 0);
2208 out2 <<
" Calculate the scattered field\n";
2210 if (atmosphere_dim == 1) {
2213 for (
Index p_index = 0; p_index <= cloudbox_limits[1] - cloudbox_limits[0];
2216 for (
Index za_index_local = 0; za_index_local < Nza; za_index_local++) {
2218 out3 <<
"Multiplication of phase matrix with incoming" 2219 <<
" intensities \n";
2225 for (
Index za_in = 0; za_in < Nza; ++za_in) {
2226 for (
Index aa_in = 0; aa_in < Naa; ++aa_in) {
2230 for (
Index i = 0;
i < stokes_dim;
i++) {
2231 for (
Index j = 0; j < stokes_dim; j++) {
2232 product_field(za_in, aa_in,
i) +=
2234 p_index, za_index_local, 0, za_in, aa_in,
i, j) *
2235 cloudbox_field_mono(p_index, 0, 0, za_in, 0, j);
2244 for (
Index i = 0;
i < stokes_dim;
i++) {
2245 doit_scat_field(p_index, 0, 0, za_index_local, 0,
i) =
2250 for (
Index i = 0;
i < stokes_dim;
i++) {
2251 doit_scat_field(p_index, 0, 0, za_index_local, 0,
i) =
2263 else if (atmosphere_dim == 3) {
2268 for (
Index p_index = 0; p_index <= cloudbox_limits[1] - cloudbox_limits[0];
2270 for (
Index lat_index = 0;
2271 lat_index <= cloudbox_limits[3] - cloudbox_limits[2];
2273 for (
Index lon_index = 0;
2274 lon_index <= cloudbox_limits[5] - cloudbox_limits[4];
2276 Numeric rtp_temperature_local =
2277 t_field(p_index + cloudbox_limits[0],
2278 lat_index + cloudbox_limits[2],
2279 lon_index + cloudbox_limits[4]);
2281 for (
Index aa_index_local = 1; aa_index_local < Naa;
2283 for (
Index za_index_local = 0; za_index_local < Nza;
2285 out3 <<
"Calculate phase matrix \n";
2293 rtp_temperature_local,
2294 pha_mat_spt_agenda);
2309 for (
Index za_in = 0; za_in < Nza; ++za_in) {
2310 for (
Index aa_in = 0; aa_in < Naa; ++aa_in) {
2313 for (
Index i = 0;
i < stokes_dim;
i++) {
2314 for (
Index j = 0; j < stokes_dim; j++) {
2315 product_field(za_in, aa_in,
i) +=
2316 pha_mat_local(za_in, aa_in,
i, j) *
2317 cloudbox_field_mono(p_index,
2331 for (
Index i = 0;
i < stokes_dim;
i++) {
2332 doit_scat_field(p_index,
2359 const Agenda& pha_mat_spt_agenda,
2360 const Tensor6& cloudbox_field_mono,
2363 const Index& atmosphere_dim,
2367 const Index& doit_za_grid_size,
2368 const Index& doit_za_interp,
2382 if (za_grid[0] != 0. || za_grid[Nza - 1] != 180.)
2383 throw runtime_error(
"The range of *za_grid* must [0 180].");
2388 if (Naa > 1 && (aa_grid[0] != 0. || aa_grid[Naa - 1] != 360.))
2389 throw runtime_error(
"The range of *aa_grid* must [0 360].");
2392 const Index stokes_dim = doit_scat_field.
ncols();
2393 assert(stokes_dim > 0 || stokes_dim < 5);
2403 if (atmosphere_dim == 1) {
2404 assert(
is_size(cloudbox_field_mono,
2405 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
2411 assert(
is_size(doit_scat_field,
2412 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
2418 }
else if (atmosphere_dim == 3) {
2419 assert(
is_size(cloudbox_field_mono,
2420 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
2421 (cloudbox_limits[3] - cloudbox_limits[2]) + 1,
2422 (cloudbox_limits[5] - cloudbox_limits[4]) + 1,
2426 assert(
is_size(doit_scat_field,
2427 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
2428 (cloudbox_limits[3] - cloudbox_limits[2]) + 1,
2429 (cloudbox_limits[5] - cloudbox_limits[4]) + 1,
2435 os <<
"The atmospheric dimension must be 1D or 3D \n" 2436 <<
"for scattering calculations using the DOIT\n" 2437 <<
"module, but it is not. The value of *atmosphere_dim*\n" 2438 <<
"is " << atmosphere_dim <<
".";
2439 throw runtime_error(os.
str());
2442 if (!(doit_za_interp == 0 || doit_za_interp == 1))
2443 throw runtime_error(
2444 "Interpolation method is not defined. Use \n" 2445 "*doit_za_interpSet*.\n");
2447 if (cloudbox_limits.
nelem() != 2 * atmosphere_dim)
2448 throw runtime_error(
2449 "*cloudbox_limits* is a vector which contains the" 2450 "upper and lower limit of the cloud for all " 2451 "atmospheric dimensions. So its dimension must" 2452 "be 2 x *atmosphere_dim*");
2454 if (doit_za_grid_size < 16)
2455 throw runtime_error(
2456 "*doit_za_grid_size* must be greater than 15 for" 2457 "accurate results");
2458 else if (doit_za_grid_size > 100) {
2460 out1 <<
"Warning: doit_za_grid_size is very large which means that the \n" 2461 <<
"calculation will be very slow. The recommended value is 19.\n";
2468 doit_za_grid_size, aa_grid.
nelem(), stokes_dim, stokes_dim, 0.);
2479 nlinspace(za_g, 0, 180, doit_za_grid_size);
2484 gridpos(gp_za_i, za_grid, za_g);
2486 Matrix itw_za_i(doit_za_grid_size, 2);
2490 Matrix cloudbox_field_int(doit_za_grid_size, stokes_dim, 0);
2495 gridpos(gp_za, za_g, za_grid);
2501 Matrix doit_scat_field_org(doit_za_grid_size, stokes_dim, 0);
2506 grid_stepsize[0] = 180. / (
Numeric)(doit_za_grid_size - 1);
2508 grid_stepsize[1] = 360. / (
Numeric)(Naa - 1);
2511 Tensor3 product_field(doit_za_grid_size, Naa, stokes_dim, 0);
2513 if (atmosphere_dim == 1) {
2516 for (
Index p_index = 0; p_index <= cloudbox_limits[1] - cloudbox_limits[0];
2519 for (
Index i = 0;
i < stokes_dim;
i++) {
2520 if (doit_za_interp == 0) {
2523 cloudbox_field_mono(p_index, 0, 0,
joker, 0,
i),
2525 }
else if (doit_za_interp == 1) {
2527 for (
Index za = 0; za < za_g.
nelem(); za++) {
2528 cloudbox_field_int(za,
i) =
2530 cloudbox_field_mono(p_index, 0, 0,
joker, 0,
i),
2541 for (
Index za_index_local = 0; za_index_local < doit_za_grid_size;
2543 out3 <<
"Multiplication of phase matrix with incoming" 2544 <<
" intensities \n";
2550 for (
Index za_in = 0; za_in < doit_za_grid_size; za_in++) {
2551 for (
Index aa_in = 0; aa_in < Naa; ++aa_in) {
2555 for (
Index i = 0;
i < stokes_dim;
i++) {
2556 for (
Index j = 0; j < stokes_dim; j++) {
2557 product_field(za_in, aa_in,
i) +=
2559 p_index, za_index_local, 0, za_in, aa_in,
i, j) *
2560 cloudbox_field_int(za_in, j);
2567 out3 <<
"Compute integral. \n";
2569 for (
Index i = 0;
i < stokes_dim;
i++) {
2570 doit_scat_field_org(za_index_local,
i) =
2575 for (
Index i = 0;
i < stokes_dim;
i++) {
2576 doit_scat_field_org(za_index_local,
i) =
2588 for (
Index i = 0;
i < stokes_dim;
i++) {
2589 if (doit_za_interp == 0)
2593 doit_scat_field_org(
joker,
i),
2597 for (
Index za = 0; za < za_grid.
nelem(); za++) {
2598 doit_scat_field(p_index, 0, 0, za, 0,
i) =
interp_poly(
2599 za_g, doit_scat_field_org(
joker,
i), za_grid[za], gp_za[za]);
2607 else if (atmosphere_dim == 3) {
2609 for (
Index p_index = 0; p_index <= cloudbox_limits[1] - cloudbox_limits[0];
2611 for (
Index lat_index = 0;
2612 lat_index <= cloudbox_limits[3] - cloudbox_limits[2];
2614 for (
Index lon_index = 0;
2615 lon_index <= cloudbox_limits[5] - cloudbox_limits[4];
2617 Numeric rtp_temperature_local =
2618 t_field(p_index + cloudbox_limits[0],
2619 lat_index + cloudbox_limits[2],
2620 lon_index + cloudbox_limits[4]);
2623 for (
Index aa_index_local = 1; aa_index_local < Naa;
2626 for (
Index i = 0;
i < stokes_dim;
i++) {
2628 cloudbox_field_int(
joker,
i),
2630 cloudbox_field_mono(
2631 p_index, lat_index, lon_index,
joker, aa_index_local,
i),
2635 for (
Index za_index_local = 0; za_index_local < doit_za_grid_size;
2637 out3 <<
"Calculate phase matrix \n";
2645 rtp_temperature_local,
2646 pha_mat_spt_agenda);
2661 out3 <<
"Multiplication of phase matrix with" 2662 <<
"incoming intensity \n";
2664 for (
Index za_in = 0; za_in < doit_za_grid_size; za_in++) {
2665 for (
Index aa_in = 0; aa_in < Naa; ++aa_in) {
2668 for (
Index i = 0;
i < stokes_dim;
i++) {
2669 for (
Index j = 0; j < stokes_dim; j++) {
2670 product_field(za_in, aa_in,
i) +=
2671 pha_mat_local(za_in, aa_in,
i, j) *
2672 cloudbox_field_int(za_in, j);
2678 out3 <<
"Compute the integral \n";
2680 for (
Index i = 0;
i < stokes_dim;
i++) {
2681 doit_scat_field_org(za_index_local,
i) =
2690 for (
Index i = 0;
i < stokes_dim;
i++) {
2693 p_index, lat_index, lon_index,
joker, aa_index_local,
i),
2695 doit_scat_field_org(
joker,
i),
2705 out2 <<
" Finished scattered field.\n";
2710 Vector& doit_za_grid_opt,
2712 const Tensor6& cloudbox_field_mono,
2714 const Index& doit_za_interp,
2725 cloudbox_field_mono,
2731 cloudbox_field_mono.
ncols());
2733 if (cloudbox_field_mono.
ncols() < 1 || cloudbox_field_mono.
ncols() > 4)
2734 throw runtime_error(
2735 "The last dimension of *cloudbox_field* corresponds\n" 2736 "to the Stokes dimension, therefore the number of\n" 2737 "columns in *cloudbox_field* must be a number between\n" 2738 "1 and 4, but it is not!");
2740 if (!(doit_za_interp == 0 || doit_za_interp == 1))
2741 throw runtime_error(
2742 "Interpolation method is not defined. Use \n" 2743 "*doit_za_interpSet*.\n");
2745 if (za_grid.
nelem() < 500) {
2746 out1 <<
"Warning: The fine grid (*za_grid*) has less than\n" 2747 <<
"500 grid points which is likely not sufficient for\n" 2748 <<
"grid_optimization\n";
2757 Matrix cloudbox_field_opt_mat;
2758 cloudbox_field_opt_mat = 0.;
2762 cloudbox_field_opt_mat,
2764 cloudbox_field_mono,
2771 const Index& atmosphere_dim,
2777 if (atmosphere_dim != 1 && method ==
"polynomial")
2778 throw runtime_error(
2779 "Polynomial interpolation is only implemented for\n" 2780 "1D DOIT calculations as \n" 2781 "in 3D there can be numerical problems.\n" 2782 "Please use 'linear' interpolation method.");
2784 if (method ==
"linear")
2786 else if (method ==
"polynomial")
2789 throw runtime_error(
2790 "Possible interpolation methods are 'linear' " 2791 "and 'polynomial'.\n");
2797 const Index& atmfields_checked,
2798 const Index& atmgeom_checked,
2799 const Index& cloudbox_checked,
2800 const Index& scat_data_checked,
2801 const Index& cloudbox_on,
2803 const Agenda& doit_mono_agenda,
2804 const Index& doit_is_initialized,
2812 out0 <<
" Cloudbox is off, DOIT calculation will be skipped.\n";
2820 if (atmfields_checked != 1)
2821 throw runtime_error(
2822 "The atmospheric fields must be flagged to have " 2823 "passed a consistency check (atmfields_checked=1).");
2824 if (atmgeom_checked != 1)
2825 throw runtime_error(
2826 "The atmospheric geometry must be flagged to have " 2827 "passed a consistency check (atmgeom_checked=1).");
2828 if (cloudbox_checked != 1)
2829 throw runtime_error(
2830 "The cloudbox must be flagged to have " 2831 "passed a consistency check (cloudbox_checked=1).");
2834 if (!cloudbox_on)
return;
2836 if (scat_data_checked != 1)
2837 throw runtime_error(
2838 "The scattering data must be flagged to have " 2839 "passed a consistency check (scat_data_checked=1).");
2845 if (f_grid.
empty())
throw runtime_error(
"The frequency grid is empty.");
2849 if (!doit_is_initialized) {
2851 os <<
"Initialization method *DoitInit* has to be called before " 2853 throw runtime_error(os.
str());
2861 Agenda l_doit_mono_agenda(doit_mono_agenda);
2868 bool failed =
false;
2870 #pragma omp parallel for if (!arts_omp_in_parallel() && nf > 1) \ 2871 firstprivate(l_ws, l_doit_mono_agenda) 2872 for (
Index f_index = 0; f_index < nf; f_index++) {
2880 os <<
"Frequency: " << f_grid[f_index] / 1e9 <<
" GHz \n";
2883 Tensor6 cloudbox_field_mono_local =
2886 cloudbox_field_mono_local,
2889 l_doit_mono_agenda);
2891 cloudbox_field_mono_local;
2892 }
catch (
const std::exception& e) {
2895 os <<
"Error for f_index = " << f_index <<
" (" << f_grid[f_index]
2898 #pragma omp critical(DoitCalc_fail) 2901 fail_msg = os.
str();
2907 if (failed)
throw runtime_error(fail_msg);
2914 const Index& atmfields_checked,
2915 const Index& atmgeom_checked,
2916 const Index& cloudbox_checked,
2917 const Index& doit_is_initialized,
2918 const Agenda& iy_main_agenda,
2919 const Index& atmosphere_dim,
2924 const Index& cloudbox_on,
2927 const Index& stokes_dim,
2930 const Index& rigorous,
2934 if (atmfields_checked != 1)
2935 throw runtime_error(
2936 "The atmospheric fields must be flagged to have " 2937 "passed a consistency check (atmfields_checked=1).");
2938 if (atmgeom_checked != 1)
2939 throw runtime_error(
2940 "The atmospheric geometry must be flagged to have " 2941 "passed a consistency check (atmgeom_checked=1).");
2942 if (cloudbox_checked != 1)
2943 throw runtime_error(
2944 "The cloudbox must be flagged to have " 2945 "passed a consistency check (cloudbox_checked=1).");
2948 if (!cloudbox_on)
return;
2951 if (!doit_is_initialized) {
2953 os <<
"Initialization method *DoitInit* has to be called before " 2954 <<
"*DoitGetIncoming*.";
2955 throw runtime_error(os.
str());
2959 const String iy_unit =
"1";
2962 Index Np_cloud = cloudbox_limits[1] - cloudbox_limits[0] + 1;
2968 if (!(atmosphere_dim == 1 || atmosphere_dim == 3))
2969 throw runtime_error(
"The atmospheric dimensionality must be 1 or 3.");
2970 if (za_grid[0] != 0. || za_grid[Nza - 1] != 180.)
2971 throw runtime_error(
2972 "*za_grid* must include 0 and 180 degrees as endpoints.");
2975 if (atmosphere_dim == 1) {
2981 for (
Index boundary = 0; boundary <= 1; boundary++) {
2982 const Index boundary_index =
2983 boundary ? cloudbox_field.
nvitrines() - 1 : 0;
2984 pos[0] = z_field(cloudbox_limits[boundary], 0, 0);
2988 los[0] = za_grid[0];
2999 cloudbox_field(
joker, boundary_index, 0, 0, 0, 0,
joker) = iy;
3001 for (
Index za_index = 1; za_index < Nza; za_index++) {
3002 los[0] = za_grid[za_index];
3015 cloudbox_field(
joker, boundary_index, 0, 0, za_index, 0,
joker) = iy;
3018 for (
Index fi = 0; fi < Nf; fi++) {
3019 if (cloudbox_field(fi, boundary_index, 0, 0, za_index - 1, 0, 0) /
3021 fi, boundary_index, 0, 0, za_index, 0, 0) >
3023 cloudbox_field(fi, boundary_index, 0, 0, za_index - 1, 0, 0) /
3025 fi, boundary_index, 0, 0, za_index, 0, 0) <
3028 os <<
"ERROR: Radiance difference between " 3029 <<
"interpolation points is too large (factor " << maxratio
3031 <<
"to safely interpolate. This might be due to " 3032 <<
"za_grid being too coarse or the radiance field " 3033 <<
"being a step-like function.\n" 3034 <<
"Happens at boundary " << boundary_index
3035 <<
" between zenith angles " << za_grid[za_index - 1]
3036 <<
" and " << za_grid[za_index] <<
"deg\n" 3037 <<
"for frequency #" << fi <<
", where radiances are " 3038 << cloudbox_field(fi, boundary_index, 0, 0, za_index - 1, 0, 0)
3040 << cloudbox_field(fi, boundary_index, 0, 0, za_index, 0, 0)
3041 <<
" W/(sr m2 Hz).";
3042 throw runtime_error(os.
str());
3054 if (aa_grid[0] != 0. || aa_grid[Naa - 1] != 360.)
3055 throw runtime_error(
3056 "*aa_grid* must include 0 and 360 degrees as endpoints.");
3058 Index Nlat_cloud = cloudbox_limits[3] - cloudbox_limits[2] + 1;
3059 Index Nlon_cloud = cloudbox_limits[5] - cloudbox_limits[4] + 1;
3065 for (
Index i = 0;
i < Naa;
i++) aa_g[
i] = aa_grid[
i] - 180;
3072 for (
Index boundary = 0; boundary <= 1; boundary++) {
3073 const Index boundary_index =
3074 boundary ? cloudbox_field.
nvitrines() - 1 : 0;
3075 for (
Index lat_index = 0; lat_index < Nlat_cloud; lat_index++) {
3076 for (
Index lon_index = 0; lon_index < Nlon_cloud; lon_index++) {
3077 pos[2] = lon_grid[lon_index + cloudbox_limits[4]];
3078 pos[1] = lat_grid[lat_index + cloudbox_limits[2]];
3079 pos[0] = z_field(cloudbox_limits[boundary],
3080 lat_index + cloudbox_limits[2],
3081 lon_index + cloudbox_limits[4]);
3083 for (
Index za_index = 0; za_index < Nza; za_index++) {
3084 for (
Index aa_index = 0; aa_index < Naa; aa_index++) {
3085 los[0] = za_grid[za_index];
3086 los[1] = aa_g[aa_index];
3091 if ((za_index != 0 && za_index != (Nza - 1)) || aa_index == 0) {
3104 cloudbox_field(
joker,
3118 for (
Index boundary = 0; boundary <= 1; boundary++) {
3119 const Index boundary_index = boundary ? cloudbox_field.
nshelves() - 1 : 0;
3120 for (
Index p_index = 0; p_index < Np_cloud; p_index++) {
3121 for (
Index lon_index = 0; lon_index < Nlon_cloud; lon_index++) {
3122 pos[2] = lon_grid[lon_index + cloudbox_limits[4]];
3123 pos[1] = lat_grid[cloudbox_limits[boundary + 2]];
3124 pos[0] = z_field(p_index + cloudbox_limits[0],
3125 cloudbox_limits[boundary + 2],
3126 lon_index + cloudbox_limits[4]);
3128 for (
Index za_index = 0; za_index < Nza; za_index++) {
3129 for (
Index aa_index = 0; aa_index < Naa; aa_index++) {
3130 los[0] = za_grid[za_index];
3131 los[1] = aa_g[aa_index];
3135 if ((za_index != 0 && za_index != (Nza - 1)) || aa_index == 0) {
3148 cloudbox_field(
joker,
3162 for (
Index boundary = 0; boundary <= 1; boundary++) {
3163 const Index boundary_index = boundary ? cloudbox_field.
nbooks() - 1 : 0;
3164 for (
Index p_index = 0; p_index < Np_cloud; p_index++) {
3165 for (
Index lat_index = 0; lat_index < Nlat_cloud; lat_index++) {
3166 pos[2] = lon_grid[cloudbox_limits[boundary + 4]];
3167 pos[1] = lat_grid[lat_index + cloudbox_limits[2]];
3168 pos[0] = z_field(p_index + cloudbox_limits[0],
3169 lat_index + cloudbox_limits[2],
3170 cloudbox_limits[boundary + 4]);
3172 for (
Index za_index = 0; za_index < Nza; za_index++) {
3173 for (
Index aa_index = 0; aa_index < Naa; aa_index++) {
3174 los[0] = za_grid[za_index];
3175 los[1] = aa_g[aa_index];
3179 if ((za_index != 0 && za_index != (Nza - 1)) || aa_index == 0) {
3192 cloudbox_field(
joker,
3211 const Index& atmfields_checked,
3212 const Index& atmgeom_checked,
3213 const Index& cloudbox_checked,
3214 const Index& doit_is_initialized,
3215 const Agenda& iy_main_agenda,
3216 const Index& atmosphere_dim,
3223 const Index& stokes_dim,
3228 if (atmfields_checked != 1)
3229 throw runtime_error(
3230 "The atmospheric fields must be flagged to have " 3231 "passed a consistency check (atmfields_checked=1).");
3232 if (atmgeom_checked != 1)
3233 throw runtime_error(
3234 "The atmospheric geometry must be flagged to have " 3235 "passed a consistency check (atmgeom_checked=1).");
3236 if (cloudbox_checked != 1)
3237 throw runtime_error(
3238 "The cloudbox must be flagged to have " 3239 "passed a consistency check (cloudbox_checked=1).");
3242 if (!cloudbox_on)
return;
3245 if (!doit_is_initialized) {
3247 os <<
"Initialization method *DoitInit* has to be called before " 3248 <<
"*DoitGetIncoming1DAtm*.";
3249 throw runtime_error(os.
str());
3253 const String iy_unit =
"1";
3255 Index Np_cloud = cloudbox_limits[1] - cloudbox_limits[0] + 1;
3256 Index Nlat_cloud = cloudbox_limits[3] - cloudbox_limits[2] + 1;
3257 Index Nlon_cloud = cloudbox_limits[5] - cloudbox_limits[4] + 1;
3264 if (atmosphere_dim != 3)
3265 throw runtime_error(
"The atmospheric dimensionality must be 3.");
3266 if (za_grid[0] != 0. || za_grid[Nza - 1] != 180.)
3267 throw runtime_error(
3268 "*za_grid* must include 0 and 180 degrees as endpoints.");
3269 if (aa_grid[0] != 0. || aa_grid[Naa - 1] != 360.)
3270 throw runtime_error(
3271 "*aa_grid* must include 0 and 360 degrees as endpoints.");
3283 for (
Index i = 0;
i < Naa;
i++) aa_g[
i] = aa_grid[
i] - 180;
3293 pos[1] = lat_grid[cloudbox_limits[2]];
3294 pos[2] = lon_grid[cloudbox_limits[4]];
3295 los[1] = aa_g[aa_index];
3298 for (
Index p_index = 0; p_index < Np_cloud; p_index++) {
3300 cloudbox_limits[0] + p_index, cloudbox_limits[2], cloudbox_limits[4]);
3302 for (
Index za_index = 0; za_index < Nza; za_index++) {
3303 los[0] = za_grid[za_index];
3316 for (
Index aa = 0; aa < Naa; aa++) {
3319 for (
Index lat = 0; lat < Nlat_cloud; lat++) {
3320 for (
Index lon = 0; lon < Nlon_cloud; lon++) {
3321 cloudbox_field(
joker, 0, lat, lon, za_index, aa,
joker) = iy;
3326 else if (p_index == Np_cloud - 1)
3327 for (
Index lat = 0; lat < Nlat_cloud; lat++) {
3328 for (
Index lon = 0; lon < Nlon_cloud; lon++) {
3329 cloudbox_field(
joker,
3340 for (
Index lat = 0; lat < 2; lat++) {
3341 for (
Index lon = 0; lon < Nlon_cloud; lon++) {
3342 const Index boundary_index =
3343 lat ? cloudbox_field.
nshelves() - 1 : 0;
3345 joker, p_index, boundary_index, lon, za_index, aa,
joker) = iy;
3350 for (
Index lat = 0; lat < Nlat_cloud; lat++) {
3351 for (
Index lon = 0; lon < 2; lon++) {
3352 const Index boundary_index = lon ? cloudbox_field.
nbooks() - 1 : 0;
3354 joker, p_index, lat, boundary_index, za_index, aa,
joker) = iy;
3367 const Index& atmosphere_dim,
3368 const Index& stokes_dim,
3370 const Index& doit_is_initialized,
3371 const Tensor7& cloudbox_field_precalc,
3375 if (atmosphere_dim != 1) {
3377 os <<
"This method is currently only implemented for 1D atmospheres!\n";
3378 throw runtime_error(os.
str());
3382 if (!doit_is_initialized) {
3384 os <<
"Initialization method *DoitInit* has to be called before " 3385 <<
"*cloudbox_fieldSetFromPrecalc*";
3386 throw runtime_error(os.
str());
3392 Index np = cloudbox_limits[1] - cloudbox_limits[0] + 1;
3394 if (nf != cloudbox_field_precalc.
nlibraries()) {
3396 os <<
"cloudbox_field_precalc has wrong size in frequency dimension.\n" 3397 << nf <<
" frequency points are expected, but cloudbox_field_precalc " 3398 <<
"contains " << cloudbox_field_precalc.
nlibraries()
3399 <<
"frequency points.\n";
3400 throw runtime_error(os.
str());
3402 if (np != cloudbox_field_precalc.
nvitrines()) {
3404 os <<
"cloudbox_field_precalc has wrong size in pressure level dimension.\n" 3405 << np <<
" pressure levels expected, but cloudbox_field_precalc " 3406 <<
"contains " << cloudbox_field_precalc.
nvitrines()
3407 <<
"pressure levels.\n";
3408 throw runtime_error(os.
str());
3410 if (nza != cloudbox_field_precalc.
npages()) {
3412 os <<
"cloudbox_field_precalc has wrong size in polar angle dimension.\n" 3413 << nza <<
" angles expected, but cloudbox_field_precalc " 3414 <<
"contains " << cloudbox_field_precalc.
npages() <<
"angles.\n";
3415 throw runtime_error(os.
str());
3417 if (stokes_dim != cloudbox_field_precalc.
ncols()) {
3419 os <<
"cloudbox_field_precalc has wrong stokes dimension.\n" 3420 <<
"Dimension " << stokes_dim
3421 <<
" expected, but cloudbox_field_precalc is dimesnion " 3422 << cloudbox_field_precalc.
ncols() <<
".\n";
3423 throw runtime_error(os.
str());
3432 Index first_upwell = 0;
3433 assert(za_grid[0] < 90.);
3434 assert(za_grid[za_grid.
nelem() - 1] > 90.);
3435 while (za_grid[first_upwell] < 90.) first_upwell++;
3437 Range downwell(0, first_upwell);
3438 Range upwell(first_upwell, za_grid.
nelem() - first_upwell);
3449 cloudbox_field(
joker, np - 1, 0, 0, upwell, 0,
joker) =
3450 cloudbox_field_precalc(
joker, np - 1, 0, 0, upwell, 0,
joker);
3452 if (cloudbox_limits[0] != 0)
3455 cloudbox_field(
joker, 0, 0, 0, downwell, 0,
joker) =
3456 cloudbox_field_precalc(
joker, 0, 0, 0, downwell, 0,
joker);
3472 const Index& atmosphere_dim,
3473 const Index& cloudbox_on,
3474 const Index& doit_is_initialized,
3475 const Index& all_frequencies,
3480 if (!cloudbox_on)
return;
3483 if (!doit_is_initialized) {
3485 os <<
"Initialization method *DoitInit* has to be called before " 3486 <<
"*cloudbox_fieldSetClearsky*.";
3487 throw runtime_error(os.
str());
3491 <<
" Interpolate boundary clearsky field to obtain the initial field.\n";
3496 if (atmosphere_dim == 1) {
3499 for (
Index f_index = 0; f_index < nf; f_index++) {
3510 ArrayOfGridPos p_gp((cloudbox_limits[1] - cloudbox_limits[0]) + 1);
3513 p_grid[
Range(cloudbox_limits[0],
3515 (cloudbox_limits[1] - cloudbox_limits[0]))],
3516 p_grid[
Range(cloudbox_limits[0],
3517 (cloudbox_limits[1] - cloudbox_limits[0]) + 1)]);
3519 Matrix itw((cloudbox_limits[1] - cloudbox_limits[0]) + 1, 2);
3522 Tensor6 scat_i_p(2, 1, 1, N_za, 1, N_i);
3526 cloudbox_field(f_index,
3534 for (
Index za_index = 0; za_index < N_za; ++za_index) {
3535 for (
Index aa_index = 0; aa_index < N_aa; ++aa_index) {
3538 f_index,
Range(joker), 0, 0, za_index, aa_index,
i);
3541 scat_i_p(
Range(joker), 0, 0, za_index, aa_index,
i);
3543 interp(target_field, itw, source_field, p_gp);
3548 }
else if (atmosphere_dim == 3) {
3549 if (all_frequencies ==
false)
3550 throw runtime_error(
3551 "Error in cloudbox_fieldSetClearsky: For 3D " 3552 "all_frequencies option is not implemented \n");
3554 for (
Index f_index = 0; f_index < cloudbox_field.
nvitrines(); f_index++) {
3562 Tensor6 scat_i_p(2, N_lat, N_lon, N_za, N_aa, N_i);
3568 Tensor6 scat_i_lat(N_p, 2, N_lon, N_za, N_aa, N_i);
3574 Tensor6 scat_i_lon(N_p, N_lat, 2, N_za, N_aa, N_i);
3582 ArrayOfGridPos p_gp((cloudbox_limits[1] - cloudbox_limits[0]) + 1);
3583 ArrayOfGridPos lat_gp((cloudbox_limits[3] - cloudbox_limits[2]) + 1);
3584 ArrayOfGridPos lon_gp((cloudbox_limits[5] - cloudbox_limits[4]) + 1);
3591 p_grid[
Range(cloudbox_limits[0],
3593 (cloudbox_limits[1] - cloudbox_limits[0]))],
3594 p_grid[
Range(cloudbox_limits[0],
3595 (cloudbox_limits[1] - cloudbox_limits[0]) + 1)]);
3597 lat_grid[
Range(cloudbox_limits[2],
3599 (cloudbox_limits[3] - cloudbox_limits[2]))],
3600 lat_grid[
Range(cloudbox_limits[2],
3601 (cloudbox_limits[3] - cloudbox_limits[2]) + 1)]);
3603 lon_grid[
Range(cloudbox_limits[4],
3605 (cloudbox_limits[5] - cloudbox_limits[4]))],
3606 lon_grid[
Range(cloudbox_limits[4],
3607 (cloudbox_limits[5] - cloudbox_limits[4]) + 1)]);
3612 Matrix itw_p((cloudbox_limits[1] - cloudbox_limits[0]) + 1, 2);
3613 Matrix itw_lat((cloudbox_limits[3] - cloudbox_limits[2]) + 1, 2);
3614 Matrix itw_lon((cloudbox_limits[5] - cloudbox_limits[4]) + 1, 2);
3621 for (
Index lat_index = 0;
3622 lat_index <= (cloudbox_limits[3] - cloudbox_limits[2]);
3624 for (
Index lon_index = 0;
3625 lon_index <= (cloudbox_limits[5] - cloudbox_limits[4]);
3627 for (
Index za_index = 0; za_index < N_za; ++za_index) {
3628 for (
Index aa_index = 0; aa_index < N_aa; ++aa_index) {
3630 VectorView target_field = cloudbox_field(f_index,
3639 Range(
joker), lat_index, lon_index, za_index, aa_index,
i);
3641 interp(target_field, itw_p, source_field, p_gp);
3648 for (
Index p_index = 0;
3649 p_index <= (cloudbox_limits[1] - cloudbox_limits[0]);
3651 for (
Index lon_index = 0;
3652 lon_index <= (cloudbox_limits[5] - cloudbox_limits[4]);
3654 for (
Index za_index = 0; za_index < N_za; ++za_index) {
3655 for (
Index aa_index = 0; aa_index < N_aa; ++aa_index) {
3657 VectorView target_field = cloudbox_field(f_index,
3666 p_index,
Range(
joker), lon_index, za_index, aa_index,
i);
3668 interp(target_field, itw_lat, source_field, lat_gp);
3675 for (
Index p_index = 0;
3676 p_index <= (cloudbox_limits[1] - cloudbox_limits[0]);
3678 for (
Index lat_index = 0;
3679 lat_index <= (cloudbox_limits[3] - cloudbox_limits[2]);
3681 for (
Index za_index = 0; za_index < N_za; ++za_index) {
3682 for (
Index aa_index = 0; aa_index < N_aa; ++aa_index) {
3684 VectorView target_field = cloudbox_field(f_index,
3693 p_index, lat_index,
Range(
joker), za_index, aa_index,
i);
3695 interp(target_field, itw_lon, source_field, lon_gp);
3713 const Index& atmosphere_dim,
3714 const Index& stokes_dim,
3716 const Vector& cloudbox_field_values,
3724 cloudbox_field.
nrows(),
3725 cloudbox_field.
ncols());
3727 for (
Index f_index = 0; f_index < cloudbox_field.
nlibraries(); f_index++) {
3728 cloudbox_field_mono =
3738 cloudbox_field_values,
3742 cloudbox_field_mono;
3754 const Index& atmosphere_dim,
3755 const Index& stokes_dim,
3757 const Matrix& cloudbox_field_values,
3762 throw runtime_error(
3763 "Number of rows in *cloudbox_field_values* has to be equal" 3764 " the frequency dimension of *cloudbox_field*.");
3770 cloudbox_field.
nrows(),
3771 cloudbox_field.
ncols());
3773 for (
Index f_index = 0; f_index < cloudbox_field.
nlibraries(); f_index++) {
3774 cloudbox_field_mono =
3784 cloudbox_field_values(f_index,
joker),
3788 cloudbox_field_mono;
3800 const Index& atmosphere_dim,
3801 const Index& stokes_dim,
3803 const Vector& cloudbox_field_values,
3808 out2 <<
" Set initial field to constant values: " << cloudbox_field_values
3817 if (stokes_dim < 0 || stokes_dim > 4)
3818 throw runtime_error(
3819 "The dimension of stokes vector must be" 3822 if (stokes_dim != cloudbox_field_values.nelem())
3823 throw runtime_error(
3824 "Length of *cloudbox_field_values* has to be equal" 3826 if (cloudbox_limits.
nelem() != 2 * atmosphere_dim)
3827 throw runtime_error(
3828 "*cloudbox_limits* is a vector which contains the" 3829 "upper and lower limit of the cloud for all " 3830 "atmospheric dimensions. So its dimension must" 3831 "be 2 x *atmosphere_dim*.");
3833 for (
Index i = 0;
i < stokes_dim;
i++) {
3835 cloudbox_field_values[
i];
INDEX Index
The type to use for all integer numbers and indices.
Template functions for general supergeneric ws methods.
void cloudbox_field_monoSetConst(Tensor6 &cloudbox_field_mono, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Index &stokes_dim, const Vector &cloudbox_field_values, const Verbosity &verbosity)
WORKSPACE METHOD: cloudbox_field_monoSetConst.
Numeric interp_poly(ConstVectorView x, ConstVectorView y, const Numeric &x_i, const GridPos &gp)
Polynomial interpolation.
void DOAngularGridsSet(Index &doit_za_grid_size, Vector &aa_grid, Vector &za_grid, const Index &N_za_grid, const Index &N_aa_grid, const String &za_grid_opt_file, const Verbosity &verbosity)
WORKSPACE METHOD: DOAngularGridsSet.
void doit_mono_agendaExecute(Workspace &ws, Tensor6 &cloudbox_field_mono, const Vector &f_grid, const Index f_index, const Agenda &input_agenda)
void doit_scat_field_agendaExecute(Workspace &ws, Tensor6 &doit_scat_field, const Tensor6 &cloudbox_field_mono, const Agenda &input_agenda)
Index nelem() const
Number of elements.
Declarations having to do with the four output streams.
void doit_conv_flagLsq(Index &doit_conv_flag, Index &doit_iteration_counter, Tensor6 &cloudbox_field_mono, const Tensor6 &cloudbox_field_mono_old, const Vector &f_grid, const Index &f_index, const Vector &epsilon, const Index &max_iterations, const Index &throw_nonconv_error, const Verbosity &verbosity)
WORKSPACE METHOD: doit_conv_flagLsq.
Numeric invrayjean(const Numeric &i, const Numeric &f)
invrayjean
Numeric AngIntegrate_trapezoid_opti(ConstMatrixView Integrand, ConstVectorView za_grid, ConstVectorView aa_grid, ConstVectorView grid_stepsize)
AngIntegrate_trapezoid_opti.
Index nvitrines() const
Returns the number of vitrines.
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
void DoitGetIncoming1DAtm(Workspace &ws, Tensor7 &cloudbox_field, Index &cloudbox_on, const Index &atmfields_checked, const Index &atmgeom_checked, const Index &cloudbox_checked, const Index &doit_is_initialized, const Agenda &iy_main_agenda, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const EnergyLevelMap &nlte_field, const ArrayOfIndex &cloudbox_limits, const Vector &f_grid, const Index &stokes_dim, const Vector &za_grid, const Vector &aa_grid, const Verbosity &)
WORKSPACE METHOD: DoitGetIncoming1DAtm.
bool is_increasing(ConstVectorView x)
Checks if a vector is sorted and strictly increasing.
Array< RetrievalQuantity > ArrayOfRetrievalQuantity
Index nrows() const
Returns the number of rows.
Linear algebra functions.
void DoitWriteIterationFields(const Index &doit_iteration_counter, const Tensor6 &cloudbox_field_mono, const Index &f_index, const ArrayOfIndex &iterations, const ArrayOfIndex &frequencies, const Verbosity &verbosity)
WORKSPACE METHOD: DoitWriteIterationFields.
bool empty() const
Returns true if variable size is zero.
void cloudbox_field_ngAcceleration(Tensor6 &cloudbox_field_mono, const ArrayOfTensor6 &acceleration_input, const Index &accelerated, const Verbosity &)
Convergence acceleration.
invlib::Vector< ArtsVector > Vector
invlib wrapper type for ARTS vectors.
void doit_za_interpSet(Index &doit_za_interp, const Index &atmosphere_dim, const String &method, const Verbosity &)
WORKSPACE METHOD: doit_za_interpSet.
This file contains basic functions to handle XML data files.
void p2gridpos(ArrayOfGridPos &gp, ConstVectorView old_pgrid, ConstVectorView new_pgrid, const Numeric &extpolfac)
Calculates grid positions for pressure values.
void cloud_ppath_update3D(Workspace &ws, Tensor6View cloudbox_field_mono, const Index &p_index, const Index &lat_index, const Index &lon_index, const Index &za_index, const Index &aa_index, ConstVectorView za_grid, ConstVectorView aa_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View doit_scat_field, const Agenda &propmat_clearsky_agenda, ConstTensor4View vmr_field, const Agenda &ppath_step_agenda, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Index &, const Verbosity &verbosity)
Radiative transfer calculation along a path inside the cloudbox (3D).
void cloudbox_field_monoOptimizeReverse(Tensor6 &cloudbox_field_mono, const Vector &p_grid_orig, const Vector &p_grid, const ArrayOfIndex &cloudbox_limits, const Verbosity &)
WORKSPACE METHOD: cloudbox_field_monoOptimizeReverse.
void cloudbox_fieldUpdate1D(Workspace &ws, Tensor6 &cloudbox_field_mono, const Tensor6 &doit_scat_field, const ArrayOfIndex &cloudbox_limits, const Agenda &propmat_clearsky_agenda, const Tensor4 &vmr_field, const Agenda &spt_calc_agenda, const Vector &za_grid, const Tensor4 &pnd_field, const Agenda &ppath_step_agenda, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, const Vector &p_grid, const Tensor3 &z_field, const Vector &refellipsoid, const Tensor3 &t_field, const Vector &f_grid, const Index &f_index, const Agenda &surface_rtprop_agenda, const Index &doit_za_interp, const Verbosity &verbosity)
WORKSPACE METHOD: cloudbox_fieldUpdate1D.
Index nelem() const
Returns the number of elements.
void DoitGetIncoming(Workspace &ws, Tensor7 &cloudbox_field, const Index &atmfields_checked, const Index &atmgeom_checked, const Index &cloudbox_checked, const Index &doit_is_initialized, const Agenda &iy_main_agenda, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const EnergyLevelMap &nlte_field, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Vector &f_grid, const Index &stokes_dim, const Vector &za_grid, const Vector &aa_grid, const Index &rigorous, const Numeric &maxratio, const Verbosity &)
WORKSPACE METHOD: DoitGetIncoming.
This file contains the definition of Array.
void cloudbox_fieldSetClearsky(Tensor7 &cloudbox_field, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Index &cloudbox_on, const Index &doit_is_initialized, const Index &all_frequencies, const Verbosity &verbosity)
WORKSPACE METHOD: cloudbox_fieldSetClearsky.
void pha_mat_spt_agendaExecute(Workspace &ws, Tensor5 &pha_mat_spt, const Index za_index, const Index scat_lat_index, const Index scat_lon_index, const Index scat_p_index, const Index aa_index, const Numeric rtp_temperature, const Agenda &input_agenda)
void DoitCalc(Workspace &ws, Tensor7 &cloudbox_field, const Index &atmfields_checked, const Index &atmgeom_checked, const Index &cloudbox_checked, const Index &scat_data_checked, const Index &cloudbox_on, const Vector &f_grid, const Agenda &doit_mono_agenda, const Index &doit_is_initialized, const Verbosity &verbosity)
WORKSPACE METHOD: DoitCalc.
void cloudbox_fieldUpdateSeq3D(Workspace &ws, Tensor6 &cloudbox_field_mono, const Tensor6 &doit_scat_field, const ArrayOfIndex &cloudbox_limits, const Agenda &propmat_clearsky_agenda, const Tensor4 &vmr_field, const Agenda &spt_calc_agenda, const Vector &za_grid, const Vector &aa_grid, const Tensor4 &pnd_field, const Agenda &ppath_step_agenda, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Vector &refellipsoid, const Tensor3 &t_field, const Vector &f_grid, const Index &f_index, const Index &doit_za_interp, const Verbosity &verbosity)
WORKSPACE METHOD: cloudbox_fieldUpdateSeq3D.
The global header file for ARTS.
void cloudbox_fieldUpdateSeq1D(Workspace &ws, Tensor6 &cloudbox_field_mono, Tensor6 &doit_scat_field, const ArrayOfIndex &cloudbox_limits, const Agenda &propmat_clearsky_agenda, const Tensor4 &vmr_field, const Agenda &spt_calc_agenda, const Vector &za_grid, const Vector &aa_grid, const Tensor4 &pnd_field, const Agenda &ppath_step_agenda, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, const Vector &p_grid, const Tensor3 &z_field, const Vector &refellipsoid, const Tensor3 &t_field, const Vector &f_grid, const Index &f_index, const Agenda &surface_rtprop_agenda, const Index &doit_za_interp, const Index &normalize, const Numeric &norm_error_threshold, const Index &norm_debug, const Verbosity &verbosity)
WORKSPACE METHOD: cloudbox_fieldUpdateSeq1D.
void doit_scat_fieldCalc(Workspace &ws, Tensor6 &doit_scat_field, const Agenda &pha_mat_spt_agenda, const Tensor6 &cloudbox_field_mono, const Tensor4 &pnd_field, const Tensor3 &t_field, const Index &atmosphere_dim, const ArrayOfIndex &cloudbox_limits, const Vector &za_grid, const Vector &aa_grid, const Index &doit_za_grid_size, const Tensor7 &pha_mat_doit, const Verbosity &verbosity)
WORKSPACE METHOD: doit_scat_fieldCalc.
_CS_string_type str() const
void DoitInit(Tensor6 &doit_scat_field, Tensor7 &cloudbox_field, Index &doit_is_initialized, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &f_grid, const Vector &za_grid, const Vector &aa_grid, const Index &doit_za_grid_size, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Verbosity &verbosity)
WORKSPACE METHOD: DoitInit.
Declarations for agendas.
void doit_conv_flagAbsBT(Index &doit_conv_flag, Index &doit_iteration_counter, Tensor6 &cloudbox_field_mono, const Tensor6 &cloudbox_field_mono_old, const Vector &f_grid, const Index &f_index, const Vector &epsilon, const Index &max_iterations, const Index &throw_nonconv_error, const Verbosity &verbosity)
WORKSPACE METHOD: doit_conv_flagAbsBT.
void cloudbox_fieldSetConstPerFreq(Tensor7 &cloudbox_field, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Index &stokes_dim, const Matrix &cloudbox_field_values, const Verbosity &verbosity)
WORKSPACE METHOD: cloudbox_fieldSetConstPerFreq.
void nlinspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
nlinspace
void doit_conv_test_agendaExecute(Workspace &ws, Index &doit_conv_flag, Index &doit_iteration_counter, const Tensor6 &cloudbox_field_mono, const Tensor6 &cloudbox_field_mono_old, const Agenda &input_agenda)
void cloudbox_field_monoIterate(Workspace &ws, Tensor6 &cloudbox_field_mono, const Agenda &doit_scat_field_agenda, const Agenda &doit_rte_agenda, const Agenda &doit_conv_test_agenda, const Index &accelerated, const Verbosity &verbosity)
WORKSPACE METHOD: cloudbox_field_monoIterate.
void get_iy(Workspace &ws, Matrix &iy, const Index &cloudbox_on, ConstVectorView f_grid, const EnergyLevelMap &nlte_field, ConstVectorView rte_pos, ConstVectorView rte_los, ConstVectorView rte_pos2, const String &iy_unit, const Agenda &iy_main_agenda)
Basic call of iy_main_agenda.
void cloud_fieldsCalc(Workspace &ws, Tensor5View ext_mat_field, Tensor4View abs_vec_field, const Agenda &spt_calc_agenda, const Index &za_index, const Index &aa_index, const ArrayOfIndex &cloudbox_limits, ConstTensor3View t_field, ConstTensor4View pnd_field, const Verbosity &verbosity)
Calculate ext_mat, abs_vec for all points inside the cloudbox for one.
Index nrows() const
Returns the number of rows.
void doit_scat_fieldCalcLimb(Workspace &ws, Tensor6 &doit_scat_field, const Agenda &pha_mat_spt_agenda, const Tensor6 &cloudbox_field_mono, const Tensor4 &pnd_field, const Tensor3 &t_field, const Index &atmosphere_dim, const ArrayOfIndex &cloudbox_limits, const Vector &za_grid, const Vector &aa_grid, const Index &doit_za_grid_size, const Index &doit_za_interp, const Tensor7 &pha_mat_doit, const Verbosity &verbosity)
WORKSPACE METHOD: doit_scat_fieldCalcLimb.
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
void xml_read_from_file(const String &filename, T &type, const Verbosity &verbosity)
Reads data from XML file.
NUMERIC Numeric
The type to use for all floating point numbers.
void cloudbox_fieldSetConst(Tensor7 &cloudbox_field, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Index &stokes_dim, const Vector &cloudbox_field_values, const Verbosity &verbosity)
WORKSPACE METHOD: cloudbox_fieldSetConst.
Index nlibraries() const
Returns the number of libraries.
Header file for special_interp.cc.
Propagation path structure and functions.
Numeric pow(const Rational base, Numeric exp)
Power of.
void resize(Index p, Index r, Index c)
Resize function.
Header file for logic.cc.
Radiative transfer in cloudbox.
void doit_za_grid_optCalc(Vector &doit_za_grid_opt, const Tensor6 &cloudbox_field_mono, const Vector &za_grid, const Index &doit_za_interp, const Numeric &acc, const Verbosity &verbosity)
WORKSPACE METHOD: doit_za_grid_optCalc.
Index npages() const
Returns the number of pages.
This can be used to make arrays out of anything.
Index nshelves() const
Returns the number of shelves.
Index ncols() const
Returns the number of columns.
void OptimizeDoitPressureGrid(Workspace &ws, Vector &p_grid, Tensor4 &pnd_field, Tensor3 &t_field, ArrayOfArrayOfSingleScatteringData &scat_data_mono, Tensor3 &z_field, ArrayOfIndex &cloudbox_limits, Tensor6 &cloudbox_field_mono, Tensor7 &pha_mat_doit, Tensor4 &vmr_field, Vector &p_grid_orig, const Vector &f_grid, const Index &f_index, const Agenda &propmat_clearsky_agenda, const Numeric &tau_scat_max, const Numeric &sgl_alb_max, const Index &cloudbox_size_max, const Verbosity &verbosity)
WORKSPACE METHOD: OptimizeDoitPressureGrid.
void doit_conv_flagAbs(Index &doit_conv_flag, Index &doit_iteration_counter, Tensor6 &cloudbox_field_mono, const Tensor6 &cloudbox_field_mono_old, const Vector &epsilon, const Index &max_iterations, const Index &throw_nonconv_error, const Verbosity &verbosity)
WORKSPACE METHOD: doit_conv_flagAbs.
void resize(Index n)
Resize function.
void pha_matCalc(Tensor4 &pha_mat, const Tensor5 &pha_mat_spt, const Tensor4 &pnd_field, const Index &atmosphere_dim, const Index &scat_p_index, const Index &scat_lat_index, const Index &scat_lon_index, const Verbosity &)
WORKSPACE METHOD: pha_matCalc.
A constant view of a Vector.
void doit_scat_fieldNormalize(Workspace &ws, Tensor6 &doit_scat_field, const Tensor6 &cloudbox_field_mono, const ArrayOfIndex &cloudbox_limits, const Agenda &spt_calc_agenda, const Index &atmosphere_dim, const Vector &za_grid, const Vector &aa_grid, const Tensor4 &pnd_field, const Tensor3 &t_field, const Numeric &norm_error_threshold, const Index &norm_debug, const Verbosity &verbosity)
Normalization of scattered field.
Index npages() const
Returns the number of pages.
void cloudbox_fieldUpdateSeq1DPP(Workspace &ws, Tensor6 &cloudbox_field_mono, Index &za_index, const Tensor6 &doit_scat_field, const ArrayOfIndex &cloudbox_limits, const Agenda &propmat_clearsky_agenda, const Tensor4 &vmr_field, const Agenda &spt_calc_agenda, const Vector &za_grid, const Tensor4 &pnd_field, const Vector &p_grid, const Tensor3 &z_field, const Tensor3 &t_field, const Vector &f_grid, const Index &f_index, const Verbosity &verbosity)
WORKSPACE METHOD: cloudbox_fieldUpdateSeq1DPP.
Index nshelves() const
Returns the number of shelves.
void cloud_ppath_update1D_noseq(Workspace &ws, Tensor6View cloudbox_field_mono, const Index &p_index, const Index &za_index, ConstVectorView za_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View cloudbox_field_mono_old, ConstTensor6View doit_scat_field, const Agenda &propmat_clearsky_agenda, ConstTensor4View vmr_field, const Agenda &ppath_step_agenda, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, ConstVectorView p_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Agenda &surface_rtprop_agenda, const Index &scat_za_interp, const Verbosity &verbosity)
Calculation of radiation field along a propagation path step for specified zenith direction and press...
Index npages() const
Returns the number of pages.
Index nbooks() const
Returns the number of books.
void resize(Index v, Index s, Index b, Index p, Index r, Index c)
Resize function.
void doit_rte_agendaExecute(Workspace &ws, Tensor6 &cloudbox_field_mono, const Tensor6 &doit_scat_field, const Agenda &input_agenda)
void cloudbox_fieldSetFromPrecalc(Tensor7 &cloudbox_field, const Vector &za_grid, const Vector &f_grid, const Index &atmosphere_dim, const Index &stokes_dim, const ArrayOfIndex &cloudbox_limits, const Index &doit_is_initialized, const Tensor7 &cloudbox_field_precalc, const Verbosity &)
WORKSPACE METHOD: cloudbox_fieldSetFromPrecalc.
bool is_size(ConstVectorView x, const Index &n)
Verifies that the size of x is l.
void propmat_clearsky_agendaExecute(Workspace &ws, ArrayOfPropagationMatrix &propmat_clearsky, ArrayOfStokesVector &nlte_source, ArrayOfPropagationMatrix &dpropmat_clearsky_dx, ArrayOfStokesVector &dnlte_dx_source, ArrayOfStokesVector &nlte_dsource_dx, const ArrayOfRetrievalQuantity &jacobian_quantities, const Vector &f_grid, const Vector &rtp_mag, const Vector &rtp_los, const Numeric rtp_pressure, const Numeric rtp_temperature, const EnergyLevelMap &rtp_nlte, const Vector &rtp_vmr, const Agenda &input_agenda)
Index nvitrines() const
Returns the number of vitrines.
The structure to describe a propagation path and releated quantities.
Index ncols() const
Returns the number of columns.
void cloud_ppath_update1D_planeparallel(Workspace &ws, Tensor6View cloudbox_field_mono, const Index &p_index, const Index &za_index, ConstVectorView za_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View doit_scat_field, const Agenda &propmat_clearsky_agenda, ConstTensor4View vmr_field, ConstVectorView p_grid, ConstTensor3View z_field, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Verbosity &verbosity)
Radiative transfer calculation inside cloudbox for planeparallel case.
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
void resize(Index l, Index v, Index s, Index b, Index p, Index r, Index c)
Resize function.
void xml_write_to_file(const String &filename, const T &type, const FileType ftype, const Index no_clobber, const Verbosity &verbosity)
Write data to XML file.
void cloud_ppath_update1D(Workspace &ws, Tensor6View cloudbox_field_mono, const Index &p_index, const Index &za_index, ConstVectorView za_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View doit_scat_field, const Agenda &propmat_clearsky_agenda, ConstTensor4View vmr_field, const Agenda &ppath_step_agenda, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, ConstVectorView p_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Agenda &surface_rtprop_agenda, const Index &scat_za_interp, const Verbosity &verbosity)
Calculates radiation field along a propagation path step for specified zenith direction and pressure ...
This file contains declerations of functions of physical character.
Index nrows() const
Returns the number of rows.
Index nbooks() const
Returns the number of books.
void resize(Index b, Index p, Index r, Index c)
Resize function.
Numeric AngIntegrate_trapezoid(ConstMatrixView Integrand, ConstVectorView za_grid, ConstVectorView aa_grid)
AngIntegrate_trapezoid.
Declaration of functions in rte.cc.
Numeric sqrt(const Rational r)
Square root.
void za_gridOpt(Vector &za_grid_opt, Matrix &cloudbox_field_opt, ConstVectorView za_grid_fine, ConstTensor6View cloudbox_field_mono, const Numeric &acc, const Index &scat_za_interp)
Optimize the zenith angle grid.
Auxiliary header stuff related to workspace variable groups.
Index nbooks() const
Returns the number of books.