37#include "matpack_data.h"
66 const Numeric& rtp_pressure,
67 const Numeric& rtp_temperature,
68 const Vector& rtp_vmr,
76 abs_t = rtp_temperature;
79 abs_vmrs.resize(rtp_vmr.nelem(), 1);
80 abs_vmrs = ExhaustiveMatrixView{rtp_vmr};
91 abs_lines_per_species.resize(abs_species.
nelem());
95 for (
auto& lines : abs_lines_per_species) lines.resize(0);
97#pragma omp parallel for schedule(dynamic) if (!arts_omp_in_parallel())
98 for (Index ilines = 0; ilines < abs_lines.
nelem(); ilines++) {
102 if (lines.
NumLines() == 0)
continue;
105 for (Index i = 0; i < abs_species.
nelem() and lines.
NumLines(); i++) {
106 for (
auto& this_tag : abs_species[i]) {
108 if (not same_or_joker(this_tag.Isotopologue(), lines.
Isotopologue()))
112 if (this_tag.lower_freq >= 0 or this_tag.upper_freq >= 0) {
113 const Numeric low = (this_tag.lower_freq >= 0)
114 ? this_tag.lower_freq
115 : std::numeric_limits<Numeric>::lowest();
116 const Numeric upp = (this_tag.upper_freq >= 0)
117 ? this_tag.upper_freq
118 : std::numeric_limits<Numeric>::max();
122 these_lines.
lines.resize(0);
123 for (Index k = lines.
NumLines() - 1; k >= 0; k--)
124 if (low <= lines.
lines[k].F0 and upp >= lines.
lines[k].F0)
131 abs_lines_per_species[i].push_back(these_lines);
135 if (lines.
NumLines() == 0)
goto leave_inner_loop;
138 abs_lines_per_species[i].push_back(lines);
139 goto leave_inner_loop;
143 leave_inner_loop : {}
146 abs_lines_per_species.shrink_to_fit();
147 for (
auto& spec_band : abs_lines_per_species)
148 std::sort(spec_band.begin(), spec_band.end(), [](
auto&
a,
auto&
b) {
149 return a.lines.size() and b.lines.size() and
150 a.lines.front().F0 < b.lines.front().F0;
157 Index& propmat_clearsky_agenda_checked,
164 propmat_clearsky_agenda_checked =
false;
171 for (Index i = 0; i < Index(Species::Species::FINAL); ++i) {
172 const String specname = Species::toShortName(Species::Species(i));
174 String filename = basename;
175 if (basename.length() && basename[basename.length() - 1] !=
'/')
177 filename += specname;
182 included.push_back(specname);
186 }
catch (
const std::runtime_error& e) {
188 excluded.push_back(specname);
193 out2 <<
" Included Species (" << included.
nelem() <<
"):\n";
194 for (Index i = 0; i < included.nelem(); ++i)
195 out2 <<
" " << included[i] <<
"\n";
197 out2 <<
" Excluded Species (" << excluded.
nelem() <<
"):\n";
198 for (Index i = 0; i < excluded.
nelem(); ++i)
199 out2 <<
" " << excluded[i] <<
"\n";
205 Index& propmat_clearsky_agenda_checked,
212 for (Index i = 0; i < Index(Species::Species::FINAL); ++i) {
213 if (Species::Species(i) not_eq Species::Species::Bath) {
214 specs.emplace_back(Species::toShortName(Species::Species(i)));
220 propmat_clearsky_agenda_checked,
231 const Index& atmosphere_dim,
232 const Vector& p_grid,
233 const Tensor3& t_field,
234 const Tensor4& vmr_field,
238 "Atmospheric dimension must be 1D, but atmosphere_dim is ",
243 abs_t = t_field(joker, 0, 0);
244 abs_vmrs = vmr_field(joker, joker, 0, 0);
253 StokesVector& nlte_source,
254 ArrayOfStokesVector& dnlte_source_dx,
256 const ArrayOfMatrix& src_coef_per_species,
257 const ArrayOfMatrix& dsrc_coef_dx,
259 const Vector& f_grid,
260 const Numeric& rtp_temperature,
267 Index n_species = src_coef_per_species.nelem();
271 Index n_f = src_coef_per_species[0].nrows();
275 "Must have exactly one pressure.")
279 "Frequency dimension of nlte_source does not\n"
280 "match abs_coef_per_species.")
282 const Vector B =
planck(f_grid, rtp_temperature);
284 StokesVector sv(n_f, nlte_source.StokesDimensions());
285 for (Index si = 0; si < n_species; ++si) {
286 sv.Kjj() = src_coef_per_species[si](joker, 0);
288 nlte_source.Kjj() += sv.Kjj();
292 for (Index ii = 0; ii < jacobian_quantities.
nelem(); ii++) {
293 const auto& deriv = jacobian_quantities[ii];
295 if (not deriv.propmattype())
continue;
297 if (deriv == Jacobian::Atm::Temperature) {
298 const Vector dB =
dplanck_dt(f_grid, rtp_temperature);
300 for (Index si = 0; si < n_species; ++si) {
301 sv.Kjj() = src_coef_per_species[si](joker, 0);
303 dnlte_source_dx[ii].Kjj() += sv.Kjj();
306 sv.Kjj() = dsrc_coef_dx[ii](joker, 0);
308 dnlte_source_dx[ii].Kjj() += sv.Kjj();
310 const Vector dB =
dplanck_df(f_grid, rtp_temperature);
312 for (Index si = 0; si < n_species; ++si) {
313 sv.Kjj() = src_coef_per_species[si](joker, 0);
315 dnlte_source_dx[ii].Kjj() += sv.Kjj();
318 sv.Kjj() = dsrc_coef_dx[ii](joker, 0);
320 dnlte_source_dx[ii].Kjj() += sv.Kjj();
322 sv.Kjj() = dsrc_coef_dx[ii](joker, 0);
324 dnlte_source_dx[ii].Kjj() += sv.Kjj();
331 PropagationMatrix& propmat_clearsky,
332 StokesVector& nlte_source,
333 ArrayOfPropagationMatrix& dpropmat_clearsky_dx,
334 ArrayOfStokesVector& dnlte_source_dx,
337 const Vector& f_grid,
338 const Index& stokes_dim,
339 const Index& propmat_clearsky_agenda_checked,
341 const Index nf = f_grid.nelem();
342 const Index nq = jacobian_quantities.
nelem();
345 !propmat_clearsky_agenda_checked,
346 "You must call *propmat_clearsky_agenda_checkedCalc* before calling this method.")
351 "stokes_dim not in [1, 2, 3, 4]");
354 if (propmat_clearsky.StokesDimensions() == stokes_dim and
355 propmat_clearsky.NumberOfFrequencies() == nf) {
356 propmat_clearsky.SetZero();
358 propmat_clearsky = PropagationMatrix(nf, stokes_dim);
362 if (dpropmat_clearsky_dx.nelem() not_eq nq) {
363 dpropmat_clearsky_dx =
364 ArrayOfPropagationMatrix(nq, PropagationMatrix(nf, stokes_dim));
366 for (
auto& pm : dpropmat_clearsky_dx) {
367 if (pm.StokesDimensions() == stokes_dim and
368 pm.NumberOfFrequencies() == nf) {
371 pm = PropagationMatrix(nf, stokes_dim);
377 if (nlte_source.StokesDimensions() == stokes_dim and
378 nlte_source.NumberOfFrequencies() == nf) {
379 nlte_source.SetZero();
381 nlte_source = StokesVector(nf, stokes_dim);
385 if (dnlte_source_dx.nelem() not_eq nq) {
386 dnlte_source_dx = ArrayOfStokesVector(nq, StokesVector(nf, stokes_dim));
388 for (
auto& pm : dnlte_source_dx) {
389 if (pm.StokesDimensions() == stokes_dim and
390 pm.NumberOfFrequencies() == nf) {
393 pm = StokesVector(nf, stokes_dim);
401 PropagationMatrix& propmat_clearsky,
402 ArrayOfPropagationMatrix& dpropmat_clearsky_dx,
403 const Index& stokes_dim,
404 const Index& atmosphere_dim,
405 const Vector& f_grid,
409 const Vector& rtp_vmr,
410 const Vector& rtp_los,
411 const Vector& rtp_mag,
414 for (Index sp = 0; sp < abs_species.
nelem() && ife < 0; sp++) {
415 if (abs_species[sp].FreeElectrons()) {
421 "Free electrons not found in *abs_species* and "
422 "Faraday rotation can not be calculated.");
425 if (select_abs_species.
nelem() and select_abs_species not_eq abs_species[ife])
return;
429 static const Numeric FRconst =
439 "To include Faraday rotation, stokes_dim >= 3 is required.")
441 atmosphere_dim == 1 && rtp_los.nelem() < 1,
442 "For applying propmat_clearskyAddFaraday, los needs to be specified\n"
443 "(at least zenith angle component for atmosphere_dim==1),\n"
446 atmosphere_dim > 1 && rtp_los.nelem() < 2,
447 "For applying propmat_clearskyAddFaraday, los needs to be specified\n"
448 "(both zenith and azimuth angle components for atmosphere_dim>1),\n"
451 const Numeric ne = rtp_vmr[ife];
453 if (ne != 0 && (rtp_mag[0] != 0 || rtp_mag[1] != 0 || rtp_mag[2] != 0)) {
458 rtp_los, rtp_mag[0], rtp_mag[1], rtp_mag[2], atmosphere_dim);
460 Numeric dc1_u = 0.0, dc1_v = 0.0, dc1_w = 0.0;
462 dc1_u = (2 * FRconst *
470 dc1_v = (2 * FRconst *
478 dc1_w = (2 * FRconst *
488 for (Index iv = 0; iv < f_grid.nelem(); iv++) {
489 const Numeric f2 = f_grid[iv] * f_grid[iv];
490 const Numeric r = ne * c1 / f2;
491 propmat_clearsky.AddFaraday(r, iv);
494 for (Index iq = 0; iq < jacobian_quantities.
nelem(); iq++) {
496 dpropmat_clearsky_dx[iq].AddFaraday(-2.0 * ne * r / f_grid[iv], iv);
497 else if (jacobian_quantities[iq] == Jacobian::Atm::MagneticU)
498 dpropmat_clearsky_dx[iq].AddFaraday(ne * dc1_u / f2, iv);
499 else if (jacobian_quantities[iq] == Jacobian::Atm::MagneticV)
500 dpropmat_clearsky_dx[iq].AddFaraday(ne * dc1_v / f2, iv);
501 else if (jacobian_quantities[iq] == Jacobian::Atm::MagneticW)
502 dpropmat_clearsky_dx[iq].AddFaraday(ne * dc1_w / f2, iv);
503 else if (jacobian_quantities[iq] == Jacobian::Atm::Electrons)
504 dpropmat_clearsky_dx[iq].AddFaraday(r, iv);
505 else if (jacobian_quantities[iq] == abs_species[ife])
506 dpropmat_clearsky_dx[iq].AddFaraday(r, iv);
515 PropagationMatrix& propmat_clearsky,
516 ArrayOfPropagationMatrix& dpropmat_clearsky_dx,
518 const Index& stokes_dim,
519 const Index& atmosphere_dim,
520 const Vector& f_grid,
524 const Vector& rtp_vmr,
525 const Vector& rtp_los,
526 const Numeric& rtp_temperature,
528 const Index& scat_data_checked,
529 const Index& use_abs_as_ext,
535 We do not yet support select_abs_species for lookup table calculations
546 "The scat_data must be flagged to have "
547 "passed a consistency check (scat_data_checked=1).")
551 for (Index sp = 0; sp < abs_species.
nelem(); sp++) {
552 if (abs_species[sp].Particles()) {
559 "For applying propmat_clearskyAddParticles, *abs_species* needs to"
560 "contain species 'particles', but it does not.\n")
564 "Number of 'particles' entries in abs_species and of elements in\n"
565 "*scat_data* needs to be identical. But you have ",
567 " 'particles' entries\n"
570 " *scat_data* elements.\n")
573 atmosphere_dim == 1 && rtp_los.nelem() < 1,
574 "For applying *propmat_clearskyAddParticles*, *rtp_los* needs to be specified\n"
575 "(at least zenith angle component for atmosphere_dim==1),\n"
578 atmosphere_dim > 1 && rtp_los.nelem() < 2,
579 "For applying *propmat_clearskyAddParticles*, *rtp_los* needs to be specified\n"
580 "(both zenith and azimuth angle components for atmosphere_dim>1),\n"
584 Numeric rtp_vmr_sum = 0.0;
591 const Index na = abs_species.
nelem();
593 mirror_los(rtp_los_back, rtp_los, atmosphere_dim);
599 if (do_jac_frequencies) {
601 <<
"Frequency perturbation not available for absorbing particles.\n";
605 ArrayOfArrayOfTensor5 ext_mat_Nse;
606 ArrayOfArrayOfTensor4 abs_vec_Nse;
612 if (do_jac_temperature) {
614 T_array = rtp_temperature;
618 T_array = rtp_temperature;
620 Matrix dir_array(1, 2);
621 dir_array(0, joker) = rtp_los_back;
634 const Index nf = abs_vec_Nse[0][0].nbooks();
635 Tensor3 tmp(nf, stokes_dim, stokes_dim);
638 PropagationMatrix internal_propmat(propmat_clearsky.NumberOfFrequencies(),
639 propmat_clearsky.StokesDimensions());
645 for (Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
646 for (Index i_se = 0; i_se < scat_data[i_ss].
nelem(); i_se++) {
648 while (sp < na && not abs_species[sp].Particles()) sp++;
649 internal_propmat.SetZero();
656 "Negative absorbing particle 'vmr' (aka number density)"
662 " (vmr_field entry #",
666 if (rtp_vmr[sp] > 0.) {
668 "Temperature interpolation error:\n"
674 if (use_abs_as_ext) {
676 for (Index iv = 0; iv < f_grid.nelem(); iv++)
677 internal_propmat.AddAbsorptionVectorAtPosition(
678 abs_vec_Nse[i_ss][i_se](iv, 0, 0, joker), iv);
680 for (Index iv = 0; iv < f_grid.nelem(); iv++)
681 internal_propmat.AddAbsorptionVectorAtPosition(
682 abs_vec_Nse[i_ss][i_se](0, 0, 0, joker), iv);
685 for (Index iv = 0; iv < f_grid.nelem(); iv++)
686 internal_propmat.SetAtPosition(
687 ext_mat_Nse[i_ss][i_se](iv, 0, 0, joker, joker), iv);
689 for (Index iv = 0; iv < f_grid.nelem(); iv++)
690 internal_propmat.SetAtPosition(
691 ext_mat_Nse[i_ss][i_se](0, 0, 0, joker, joker), iv);
693 propmat_clearsky += rtp_vmr[sp] * internal_propmat;
697 if (do_jac_temperature) {
699 t_ok(i_se_flat, 1) < 0.,
700 "Temperature interpolation error (in perturbation):\n"
709 if (jacobian_quantities.
nelem()) rtp_vmr_sum += rtp_vmr[sp];
711 for (Index iq = 0; iq < jacobian_quantities.
nelem(); iq++) {
712 const auto& deriv = jacobian_quantities[iq];
714 if (not deriv.propmattype())
continue;
716 if (deriv == Jacobian::Atm::Temperature) {
717 if (use_abs_as_ext) {
718 tmp(joker, joker, 0) = abs_vec_Nse[i_ss][i_se](joker, 1, 0, joker);
719 tmp(joker, joker, 0) -= abs_vec_Nse[i_ss][i_se](joker, 0, 0, joker);
721 tmp = ext_mat_Nse[i_ss][i_se](joker, 1, 0, joker, joker);
722 tmp -= ext_mat_Nse[i_ss][i_se](joker, 0, 0, joker, joker);
729 for (Index iv = 0; iv < f_grid.nelem(); iv++)
731 dpropmat_clearsky_dx[iq].AddAbsorptionVectorAtPosition(
732 tmp(iv, joker, 0), iv);
734 dpropmat_clearsky_dx[iq].AddAtPosition(tmp(iv, joker, joker),
737 for (Index iv = 0; iv < f_grid.nelem(); iv++)
739 dpropmat_clearsky_dx[iq].AddAbsorptionVectorAtPosition(
740 tmp(0, joker, 0), iv);
742 dpropmat_clearsky_dx[iq].AddAtPosition(tmp(0, joker, joker),
746 else if (deriv == Jacobian::Atm::Particulates) {
747 for (Index iv = 0; iv < f_grid.nelem(); iv++)
748 dpropmat_clearsky_dx[iq].AddAtPosition(internal_propmat, iv);
751 else if (deriv == abs_species[sp]) {
752 dpropmat_clearsky_dx[iq] += internal_propmat;
764 ARTS_ASSERT(abs_species[sp][0].Type() != Species::TagType::Particles);
768 if (rtp_vmr_sum != 0.0) {
769 for (Index iq = 0; iq < jacobian_quantities.
nelem(); iq++) {
770 const auto& deriv = jacobian_quantities[iq];
772 if (not deriv.propmattype())
continue;
774 if (deriv == Jacobian::Atm::Particulates) {
775 dpropmat_clearsky_dx[iq] /= rtp_vmr_sum;
782 const Vector& f_grid,
783 const Numeric& sparse_df,
784 const String& speedup_option,
788 if (not f_grid.nelem()) {
789 sparse_f_grid.resize(0);
793 switch (Options::toLblSpeedupOrThrow(speedup_option)) {
794 case Options::LblSpeedup::LinearIndependent:
798 case Options::LblSpeedup::QuadraticIndependent:
801 case Options::LblSpeedup::None:
802 sparse_f_grid.resize(0);
804 case Options::LblSpeedup::FINAL: {
810 const Numeric& sparse_df,
811 const String& speedup_option,
814 Vector sparse_f_grid;
816 sparse_f_grid, f_grid, sparse_df, speedup_option, verbosity);
817 return sparse_f_grid;
823 PropagationMatrix& propmat_clearsky,
824 StokesVector& nlte_source,
825 ArrayOfPropagationMatrix& dpropmat_clearsky_dx,
826 ArrayOfStokesVector& dnlte_source_dx,
828 const Vector& f_grid,
834 const Numeric& rtp_pressure,
835 const Numeric& rtp_temperature,
837 const Vector& rtp_vmr,
838 const Index& nlte_do,
839 const Index& lbl_checked,
841 const Numeric& sparse_df,
842 const Numeric& sparse_lim,
843 const String& speedup_option,
848 const Index nf = f_grid.nelem();
849 const Index nq = jacobian_quantities.
nelem();
850 const Index ns = abs_species.
nelem();
856 "*rtp_vmr* must match *abs_species*")
858 "*f_grid* must match *propmat_clearsky*")
860 "*f_grid* must match *nlte_source*")
862 not nq and (nq not_eq dpropmat_clearsky_dx.nelem()),
863 "*dpropmat_clearsky_dx* must match derived form of *jacobian_quantities*")
865 not nq and bad_propmat(dpropmat_clearsky_dx, f_grid),
866 "*dpropmat_clearsky_dx* must have frequency dim same as *f_grid*")
868 nlte_do and (nq not_eq dnlte_source_dx.nelem()),
869 "*dnlte_source_dx* must match derived form of *jacobian_quantities* when non-LTE is on")
871 nlte_do and bad_propmat(dnlte_source_dx, f_grid),
872 "*dnlte_source_dx* must have frequency dim same as *f_grid* when non-LTE is on")
874 "Negative frequency (at least one value).")
875 ARTS_USER_ERROR_IF((any_cutoff(abs_lines_per_species) or speedup_option not_eq
"None") and not is_increasing(f_grid),
876 "Must be sorted and increasing if any cutoff or speedup is used.")
878 "Negative VMR (at least one value).")
880 "Negative NLTE (at least one value).")
884 sparse_lim > 0 and sparse_df > sparse_lim,
885 "If sparse grids are to be used, the limit must be larger than the grid-spacing.\n"
888 " Hz and the grid_spacing is ",
896 f_grid, sparse_df, speedup_option, verbosity);
897 const Options::LblSpeedup speedup_type =
898 f_grid_sparse.nelem() ? Options::toLblSpeedupOrThrow(speedup_option)
899 : Options::LblSpeedup::None;
901 sparse_lim <= 0 and speedup_type not_eq Options::LblSpeedup::None,
902 "Must have a sparse limit if you set speedup_option")
907 f_grid_sparse, jacobian_quantities, nlte_do);
910 for (Index ispecies = 0; ispecies < ns; ispecies++) {
911 if (select_abs_species.
nelem() and
912 select_abs_species not_eq abs_species[ispecies])
916 if (not abs_species[ispecies].nelem() or abs_species[ispecies].
Zeeman() or
917 not abs_lines_per_species[ispecies].nelem())
920 for (
auto& band : abs_lines_per_species[ispecies]) {
926 band.BroadeningSpeciesVMR(rtp_vmr, abs_species),
927 abs_species[ispecies],
929 isotopologue_ratios[band.Isotopologue()],
940 const Index nbands = [](
auto& lines) {
942 for (
auto& abs_lines : lines) n += abs_lines.nelem();
944 }(abs_lines_per_species);
946 std::vector<LineShape::ComputeData> vcom(
949 f_grid, jacobian_quantities,
static_cast<bool>(nlte_do)});
950 std::vector<LineShape::ComputeData> vsparse_com(
953 f_grid_sparse, jacobian_quantities,
static_cast<bool>(nlte_do)});
955#pragma omp parallel for schedule(dynamic)
956 for (Index i = 0; i < nbands; i++) {
957 const auto [ispecies, iband] =
958 flat_index(i, abs_species, abs_lines_per_species);
960 if (select_abs_species.
nelem() and
961 select_abs_species not_eq abs_species[ispecies])
965 if (not abs_species[ispecies].nelem() or abs_species[ispecies].
Zeeman() or
966 not abs_lines_per_species[ispecies].nelem())
969 auto& band = abs_lines_per_species[ispecies][iband];
975 band.BroadeningSpeciesVMR(rtp_vmr, abs_species),
976 abs_species[ispecies],
978 isotopologue_ratios[band.Isotopologue()],
988 for (
auto& pcom: vcom) com += pcom;
989 for (
auto& pcom: vsparse_com) sparse_com += pcom;
992 switch (speedup_type) {
993 case Options::LblSpeedup::LinearIndependent:
996 case Options::LblSpeedup::QuadraticIndependent:
999 case Options::LblSpeedup::None:
1001 case Options::LblSpeedup::FINAL: {
1006 propmat_clearsky.Kjj() += com.
F.real();
1009 for (Index j = 0; j < nq; j++) {
1010 if (not jacobian_quantities[j].propmattype())
continue;
1011 dpropmat_clearsky_dx[j].Kjj() += com.
dF.real()(joker, j);
1016 nlte_source.Kjj() += com.
N.real();
1019 for (Index j = 0; j < nq; j++) {
1020 if (not jacobian_quantities[j].propmattype())
continue;
1021 dnlte_source_dx[j].Kjj() += com.
dN.real()(joker, j);
1028 const Vector& f_grid,
1029 const Index& stokes_dim,
1031 propmat_clearsky = PropagationMatrix(f_grid.nelem(), stokes_dim);
1037 for (Index i = 0; i < propmat_clearsky.NumberOfFrequencies(); i++)
1038 if (propmat_clearsky.Kjj()[i] < 0.0) propmat_clearsky.SetAtPosition(0.0, i);
1057 const Vector& f_grid,
1058 const Tensor3& z_field,
1059 const Tensor7& propmat_clearsky_field,
1060 const Index& atmosphere_dim,
1065 int nlev_dimid, nlyr_dimid, nwvl_dimid, stokes_dimid, none_dimid;
1067 int wvlmin_varid, wvlmax_varid, z_varid, wvl_varid, tau_varid;
1070 "WriteMolTau can only be used for atmosphere_dim=1")
1071#pragma omp critical(netcdf__critical_region)
1074 if ((retval = nc_create(filename.c_str(), NC_CLOBBER, &ncid)))
1078 if ((retval = nc_def_dim(ncid,
"nlev", (
int)z_field.npages(), &nlev_dimid)))
1082 nc_def_dim(ncid,
"nlyr", (
int)z_field.npages() - 1, &nlyr_dimid)))
1085 if ((retval = nc_def_dim(ncid,
"nwvl", (
int)f_grid.nelem(), &nwvl_dimid)))
1088 if ((retval = nc_def_dim(ncid,
"none", 1, &none_dimid)))
1091 if ((retval = nc_def_dim(ncid,
1093 (
int)propmat_clearsky_field.nbooks(),
1098 if ((retval = nc_def_var(
1099 ncid,
"wvlmin", NC_DOUBLE, 1, &none_dimid, &wvlmin_varid)))
1102 if ((retval = nc_def_var(
1103 ncid,
"wvlmax", NC_DOUBLE, 1, &none_dimid, &wvlmax_varid)))
1106 if ((retval = nc_def_var(ncid,
"z", NC_DOUBLE, 1, &nlev_dimid, &z_varid)))
1110 nc_def_var(ncid,
"wvl", NC_DOUBLE, 1, &nwvl_dimid, &wvl_varid)))
1113 dimids[0] = nlyr_dimid;
1114 dimids[1] = nwvl_dimid;
1115 dimids[2] = stokes_dimid;
1116 dimids[3] = stokes_dimid;
1119 nc_def_var(ncid,
"tau", NC_DOUBLE, 4, &dimids[0], &tau_varid)))
1123 if ((retval = nc_put_att_text(ncid, wvlmin_varid,
"units", 2,
"nm")))
1126 if ((retval = nc_put_att_text(ncid, wvlmax_varid,
"units", 2,
"nm")))
1129 if ((retval = nc_put_att_text(ncid, z_varid,
"units", 2,
"km")))
1132 if ((retval = nc_put_att_text(ncid, wvl_varid,
"units", 2,
"nm")))
1135 if ((retval = nc_put_att_text(ncid, tau_varid,
"units", 1,
"-")))
1140 if ((retval = nc_enddef(ncid)))
nca_error(retval,
"nc_enddef");
1145 if ((retval = nc_put_var_double(ncid, wvlmin_varid, &wvlmin[0])))
1150 if ((retval = nc_put_var_double(ncid, wvlmax_varid, &wvlmax[0])))
1153 double z[z_field.npages()];
1154 for (
int iz = 0; iz < z_field.npages(); iz++)
1155 z[iz] = z_field(z_field.npages() - 1 - iz, 0, 0) * 1e-3;
1157 if ((retval = nc_put_var_double(ncid, z_varid, &z[0])))
1160 double wvl[f_grid.nelem()];
1161 for (
int iv = 0; iv < f_grid.nelem(); iv++)
1162 wvl[iv] =
SPEED_OF_LIGHT / f_grid[f_grid.nelem() - 1 - iv] * 1e9;
1164 if ((retval = nc_put_var_double(ncid, wvl_varid, &wvl[0])))
1167 const Index zfnp = z_field.npages() - 1;
1168 const Index fgne = f_grid.nelem();
1169 const Index amfnb = propmat_clearsky_field.nbooks();
1171 Tensor4 tau(zfnp, fgne, amfnb, amfnb, 0.);
1174 for (
int is = 0; is < propmat_clearsky_field.nlibraries(); is++)
1175 for (
int iz = 0; iz < zfnp; iz++)
1176 for (
int iv = 0; iv < fgne; iv++)
1177 for (
int is1 = 0; is1 < amfnb; is1++)
1178 for (
int is2 = 0; is2 < amfnb; is2++)
1180 tau(iz, iv, is1, is2) +=
1182 (propmat_clearsky_field(is,
1183 f_grid.nelem() - 1 - iv,
1186 z_field.npages() - 1 - iz,
1189 propmat_clearsky_field(is,
1190 f_grid.nelem() - 1 - iv,
1193 z_field.npages() - 2 - iz,
1196 (z_field(z_field.npages() - 1 - iz, 0, 0) -
1197 z_field(z_field.npages() - 2 - iz, 0, 0));
1199 if ((retval = nc_put_var_double(ncid, tau_varid, tau.unsafe_data_handle())))
1203 if ((retval = nc_close(ncid)))
nca_error(retval,
"nc_close");
1210 const Vector& f_grid
_U_,
1211 const Tensor3& z_field
_U_,
1212 const Tensor7& propmat_clearsky_field
_U_,
1213 const Index& atmosphere_dim
_U_,
1218 "The workspace method WriteMolTau is not available"
1219 "because ARTS was compiled without NetCDF support.");
1227 Agenda& propmat_clearsky_agenda,
1228 Index& propmat_clearsky_agenda_checked,
1234 const Numeric& T_extrapolfac,
1236 const Numeric& extpolfac,
1237 const Numeric& force_p,
1238 const Numeric& force_t,
1239 const Index& ignore_errors,
1240 const Numeric& lines_sparse_df,
1241 const Numeric& lines_sparse_lim,
1242 const String& lines_speedup_option,
1243 const Index& manual_mag_field,
1244 const Index& no_negatives,
1245 const Numeric& theta,
1246 const Index& use_abs_as_ext,
1247 const Index& use_abs_lookup_ind,
1252 propmat_clearsky_agenda_checked = 0;
1257 const bool use_abs_lookup =
static_cast<bool>(use_abs_lookup_ind);
1263 agenda.
add(
"propmat_clearskyInit");
1266 if (use_abs_lookup) {
1267 agenda.
add(
"propmat_clearskyAddFromLookup",
1268 SetWsv{
"extpolfac", extpolfac},
1269 SetWsv{
"no_negatives", no_negatives});
1273 if (not use_abs_lookup and any_species.
Plain and
1276 agenda.
add(
"propmat_clearskyAddLines",
1277 SetWsv{
"lines_sparse_df", lines_sparse_df},
1278 SetWsv{
"lines_sparse_lim", lines_sparse_lim},
1279 SetWsv{
"lines_speedup_option", lines_speedup_option},
1280 SetWsv{
"no_negatives", no_negatives});
1284 if (any_species.
Zeeman and
1287 agenda.
add(
"propmat_clearskyAddZeeman",
1288 SetWsv{
"manual_mag_field", manual_mag_field},
1295 if (not use_abs_lookup and any_species.
XsecFit) {
1296 agenda.
add(
"propmat_clearskyAddXsecFit",
1297 SetWsv{
"force_p", force_p},
1298 SetWsv{
"force_t", force_t});
1302 if (not use_abs_lookup and any_species.
Plain and
1305 agenda.
add(
"propmat_clearskyAddOnTheFlyLineMixing");
1309 if (any_species.
Zeeman and
1312 agenda.
add(
"propmat_clearskyAddOnTheFlyLineMixingWithZeeman");
1316 if (not use_abs_lookup and any_species.
Cia) {
1317 agenda.
add(
"propmat_clearskyAddCIA",
1318 SetWsv{
"T_extrapolfac", T_extrapolfac},
1319 SetWsv{
"ignore_errors", ignore_errors});
1323 if (not use_abs_lookup and any_species.
Predefined) {
1324 agenda.
add(
"propmat_clearskyAddPredefined");
1329 agenda.
add(
"propmat_clearskyAddParticles",
1330 SetWsv{
"use_abs_as_ext", use_abs_as_ext});
1335 agenda.
add(
"propmat_clearskyAddFaraday");
1339 if (not use_abs_lookup and any_species.
Plain and
1342 agenda.
add(
"propmat_clearskyAddHitranLineMixingLines");
1346 propmat_clearsky_agenda = agenda.
finalize();
1347 propmat_clearsky_agenda_checked = 1;
1350 if (out3.sufficient_priority()) {
1351 out3 <<
"propmat_clearsky_agendaAuto sets propmat_clearsky_agenda to:\n\n"
1352 << propmat_clearsky_agenda <<
'\n';
Declarations required for the calculation of absorption coefficients.
AbsorptionSpeciesBandIndex flat_index(Index i, const ArrayOfArrayOfSpeciesTag &abs_species, const ArrayOfArrayOfAbsorptionLines &abs_lines_per_species)
Get a flat index pair for species and band.
Contains the absorption namespace.
Declarations for agendas.
This file contains the definition of Array.
Index TotalNumberOfElements(const Array< Array< base > > &aa)
Determine total number of elements in an ArrayOfArray.
The global header file for ARTS.
Constants of physical expressions as constexpr.
int arts_omp_get_max_threads()
Wrapper for omp_get_max_threads.
int arts_omp_get_thread_num()
Wrapper for omp_get_thread_num.
bool arts_omp_in_parallel()
Wrapper for omp_in_parallel.
Header file for helper functions for OpenMP.
Stuff related to time in ARTS.
This can be used to make arrays out of anything.
Index nelem() const ARTS_NOEXCEPT
Helper macros for debugging.
#define ARTS_ASSERT(condition,...)
#define ARTS_USER_ERROR_IF(condition,...)
void find_xml_file(String &filename, const Verbosity &verbosity)
Find an xml file.
This file contains basic functions to handle ASCII files.
bool do_frequency_jacobian(const ArrayOfRetrievalQuantity &js) noexcept
Returns if the array wants a frequency derivative.
bool do_magnetic_jacobian(const ArrayOfRetrievalQuantity &js) noexcept
Returns if the array wants a magnetic derivative.
bool do_temperature_jacobian(const ArrayOfRetrievalQuantity &js) noexcept
Returns if the array wants the temperature derivative.
Numeric magnetic_field_perturbation(const ArrayOfRetrievalQuantity &js) noexcept
Returns the magnetic field perturbation if it exists.
bool is_frequency_parameter(const RetrievalQuantity &t) noexcept
Returns if the Retrieval quantity is a frequency parameter in propagation matrix calculations.
Numeric temperature_perturbation(const ArrayOfRetrievalQuantity &js) noexcept
Returns the temperature perturbation if it exists.
Routines for setting up the jacobian.
void sparse_f_gridFromFrequencyGrid(Vector &sparse_f_grid, const Vector &f_grid, const Numeric &sparse_df, const String &speedup_option, const Verbosity &)
WORKSPACE METHOD: sparse_f_gridFromFrequencyGrid.
constexpr Numeric ELECTRON_MASS
void isotopologue_ratiosInitFromHitran(SpeciesIsotopologueRatios &isotopologue_ratios, const Verbosity &)
WORKSPACE METHOD: isotopologue_ratiosInitFromHitran.
constexpr Numeric SPEED_OF_LIGHT
Vector create_sparse_f_grid_internal(const Vector &f_grid, const Numeric &sparse_df, const String &speedup_option, const Verbosity &verbosity)
void propmat_clearskyInit(PropagationMatrix &propmat_clearsky, StokesVector &nlte_source, ArrayOfPropagationMatrix &dpropmat_clearsky_dx, ArrayOfStokesVector &dnlte_source_dx, const ArrayOfRetrievalQuantity &jacobian_quantities, const Vector &f_grid, const Index &stokes_dim, const Index &propmat_clearsky_agenda_checked, const Verbosity &)
WORKSPACE METHOD: propmat_clearskyInit.
void nlte_sourceFromTemperatureAndSrcCoefPerSpecies(StokesVector &nlte_source, ArrayOfStokesVector &dnlte_source_dx, const ArrayOfMatrix &src_coef_per_species, const ArrayOfMatrix &dsrc_coef_dx, const ArrayOfRetrievalQuantity &jacobian_quantities, const Vector &f_grid, const Numeric &rtp_temperature, const Verbosity &)
void abs_speciesDefineAllInScenario(ArrayOfArrayOfSpeciesTag &tgs, Index &propmat_clearsky_agenda_checked, const String &basename, const Verbosity &verbosity)
WORKSPACE METHOD: abs_speciesDefineAllInScenario.
constexpr Numeric VACUUM_PERMITTIVITY
void abs_speciesDefineAll(ArrayOfArrayOfSpeciesTag &abs_species, Index &propmat_clearsky_agenda_checked, const Verbosity &verbosity)
WORKSPACE METHOD: abs_speciesDefineAll.
void AbsInputFromRteScalars(Vector &abs_p, Vector &abs_t, Matrix &abs_vmrs, const Numeric &rtp_pressure, const Numeric &rtp_temperature, const Vector &rtp_vmr, const Verbosity &)
void propmat_clearskyForceNegativeToZero(PropagationMatrix &propmat_clearsky, const Verbosity &)
WORKSPACE METHOD: propmat_clearskyForceNegativeToZero.
void propmat_clearskyAddLines(PropagationMatrix &propmat_clearsky, StokesVector &nlte_source, ArrayOfPropagationMatrix &dpropmat_clearsky_dx, ArrayOfStokesVector &dnlte_source_dx, const Vector &f_grid, const ArrayOfArrayOfSpeciesTag &abs_species, const ArrayOfSpeciesTag &select_abs_species, const ArrayOfRetrievalQuantity &jacobian_quantities, const ArrayOfArrayOfAbsorptionLines &abs_lines_per_species, const SpeciesIsotopologueRatios &isotopologue_ratios, const Numeric &rtp_pressure, const Numeric &rtp_temperature, const EnergyLevelMap &rtp_nlte, const Vector &rtp_vmr, const Index &nlte_do, const Index &lbl_checked, const Numeric &sparse_df, const Numeric &sparse_lim, const String &speedup_option, const Index &robust, const Verbosity &verbosity)
WORKSPACE METHOD: propmat_clearskyAddLines.
void propmat_clearskyZero(PropagationMatrix &propmat_clearsky, const Vector &f_grid, const Index &stokes_dim, const Verbosity &)
WORKSPACE METHOD: propmat_clearskyZero.
void propmat_clearskyAddParticles(PropagationMatrix &propmat_clearsky, ArrayOfPropagationMatrix &dpropmat_clearsky_dx, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &f_grid, const ArrayOfArrayOfSpeciesTag &abs_species, const ArrayOfSpeciesTag &select_abs_species, const ArrayOfRetrievalQuantity &jacobian_quantities, const Vector &rtp_vmr, const Vector &rtp_los, const Numeric &rtp_temperature, const ArrayOfArrayOfSingleScatteringData &scat_data, const Index &scat_data_checked, const Index &use_abs_as_ext, const Verbosity &verbosity)
WORKSPACE METHOD: propmat_clearskyAddParticles.
void propmat_clearskyAddFaraday(PropagationMatrix &propmat_clearsky, ArrayOfPropagationMatrix &dpropmat_clearsky_dx, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &f_grid, const ArrayOfArrayOfSpeciesTag &abs_species, const ArrayOfSpeciesTag &select_abs_species, const ArrayOfRetrievalQuantity &jacobian_quantities, const Vector &rtp_vmr, const Vector &rtp_los, const Vector &rtp_mag, const Verbosity &)
WORKSPACE METHOD: propmat_clearskyAddFaraday.
void WriteMolTau(const Vector &f_grid, const Tensor3 &z_field, const Tensor7 &propmat_clearsky_field, const Index &atmosphere_dim, const String &filename, const Verbosity &)
WORKSPACE METHOD: WriteMolTau.
void AbsInputFromAtmFields(Vector &abs_p, Vector &abs_t, Matrix &abs_vmrs, const Index &atmosphere_dim, const Vector &p_grid, const Tensor3 &t_field, const Tensor4 &vmr_field, const Verbosity &)
WORKSPACE METHOD: AbsInputFromAtmFields.
void abs_lines_per_speciesCreateFromLines(ArrayOfArrayOfAbsorptionLines &abs_lines_per_species, const ArrayOfAbsorptionLines &abs_lines, const ArrayOfArrayOfSpeciesTag &abs_species, const Verbosity &)
WORKSPACE METHOD: abs_lines_per_speciesCreateFromLines.
void isotopologue_ratiosInitFromBuiltin(SpeciesIsotopologueRatios &isotopologue_ratios, const Verbosity &)
WORKSPACE METHOD: isotopologue_ratiosInitFromBuiltin.
constexpr Numeric ELECTRON_CHARGE
void propmat_clearsky_agendaAuto(Workspace &ws, Agenda &propmat_clearsky_agenda, Index &propmat_clearsky_agenda_checked, const ArrayOfArrayOfSpeciesTag &abs_species, const ArrayOfArrayOfAbsorptionLines &abs_lines_per_species, const Numeric &H, const Numeric &T_extrapolfac, const Numeric &eta, const Numeric &extpolfac, const Numeric &force_p, const Numeric &force_t, const Index &ignore_errors, const Numeric &lines_sparse_df, const Numeric &lines_sparse_lim, const String &lines_speedup_option, const Index &manual_mag_field, const Index &no_negatives, const Numeric &theta, const Index &use_abs_as_ext, const Index &use_abs_lookup_ind, const Verbosity &verbosity)
WORKSPACE METHOD: propmat_clearsky_agendaAuto.
void abs_speciesSet(ArrayOfArrayOfSpeciesTag &abs_species, Index &propmat_clearsky_agenda_checked, const ArrayOfString &names, const Verbosity &verbosity)
WORKSPACE METHOD: abs_speciesSet.
Workspace methods and template functions for supergeneric XML IO.
constexpr bool any_negative(const MatpackType &var) noexcept
Checks for negative values.
Declarations having to do with the four output streams.
Declaration of the class MdRecord.
constexpr Numeric pi
The following mathematical constants are generated in python Decimal package by the code:
constexpr Numeric vacuum_permittivity
Vacuum permittivity [F/m].
constexpr Numeric electron_mass
Mass of resting electron [kg].
constexpr Numeric speed_of_light
Speed of light [m/s] From: https://en.wikipedia.org/wiki/2019_redefinition_of_SI_base_units Date: 201...
constexpr Numeric elementary_charge
Elementary charge [C] From: https://en.wikipedia.org/wiki/2019_redefinition_of_SI_base_units Date: 20...
SpeciesIsotopologueRatios isotopologue_ratios()
void compute(ComputeData &com, ComputeData &sparse_com, const AbsorptionLines &band, const ArrayOfRetrievalQuantity &jacobian_quantities, const EnergyLevelMap &nlte, const Vector &vmrs, const ArrayOfSpeciesTag &self_tag, const Numeric &self_vmr, const Numeric &isot_ratio, const Numeric &P, const Numeric &T, const Numeric &H, const Numeric &sparse_lim, const Zeeman::Polarization zeeman_polarization, const Options::LblSpeedup speedup_type, const bool robust) ARTS_NOEXCEPT
Compute the absorption of an absorption band.
bool good_linear_sparse_f_grid(const Vector &f_grid_dense, const Vector &f_grid_sparse) noexcept
Vector triple_sparse_f_grid(const Vector &f_grid, const Numeric &sparse_df) noexcept
Vector linear_sparse_f_grid(const Vector &f_grid, const Numeric &sparse_df) ARTS_NOEXCEPT
constexpr IsotopologueRatios isotopologue_ratiosInitFromBuiltin()
Implements Zeeman modeling.
void nca_error(const int e, const std::string_view s)
Throws a runtime error for the given NetCDF error code.
This file contains basic functions to handle NetCDF data files.
void opt_prop_NScatElems(ArrayOfArrayOfTensor5 &ext_mat, ArrayOfArrayOfTensor4 &abs_vec, ArrayOfArrayOfIndex &ptypes, Matrix &t_ok, const ArrayOfArrayOfSingleScatteringData &scat_data, const Index &stokes_dim, const Vector &T_array, const Matrix &dir_array, const Index &f_index, const Index &t_interp_order)
Extinction and absorption from all scattering elements.
Scattering database structure and functions.
This file contains header information for the dealing with command line parameters.
Numeric dplanck_df(const Numeric &f, const Numeric &t)
dplanck_df
Numeric planck(const Numeric &f, const Numeric &t)
planck
Numeric dplanck_dt(const Numeric &f, const Numeric &t)
dplanck_dt
This file contains declerations of functions of physical character.
Numeric dotprod_with_los(const ConstVectorView &los, const Numeric &u, const Numeric &v, const Numeric &w, const Index &atmosphere_dim)
Calculates the dot product between a field and a LOS.
void mirror_los(Vector &los_mirrored, const ConstVectorView &los, const Index &atmosphere_dim)
Determines the backward direction for a given line-of-sight.
Declaration of functions in rte.cc.
bool ByHITRANRosenkranzRelmat
bool ByRovibLinearDipoleLineMixing
AbsorptionPopulationTagTypeStatus population
SingleLine PopLine(Index) noexcept
Pops a single line.
Array< SingleLine > lines
A list of individual lines.
Index NumLines() const noexcept
Number of lines.
Species::IsotopeRecord Isotopologue() const noexcept
Isotopologue Index.
void ReverseLines() noexcept
Reverses the order of the internal lines.
void AppendSingleLine(SingleLine &&sl)
Appends a single line to the absorption lines.
Helper class to create an agenda.
void add(const std::string_view method, Input &&... input)
Add a method with as many inputs as you want. These inputs must be of type Wsv.
Agenda finalize()
Check the agenda and return a copy of it (ignoring/touching all agenda input/output not dealt with)
Main computational data for the line shape and strength calculations.
void interp_add_even(const ComputeData &sparse) ARTS_NOEXCEPT
Add a sparse grid to this grid via linear interpolation.
void interp_add_triplequad(const ComputeData &sparse) ARTS_NOEXCEPT
Add a sparse grid to this grid via square interpolation.
Struct to test of an ArrayOfArrayOfSpeciesTag contains a tagtype.
This file contains basic functions to handle XML data files.