10#include <Faddeeva/Faddeeva.hh>
19#include "matpack_data.h"
20#include "predefined/predef_data.h"
21#include "propagationmatrix.h"
42template <
bool check_exist>
45 const Vector& f [[maybe_unused]],
46 const Numeric& p [[maybe_unused]],
47 const Numeric& t [[maybe_unused]],
48 const VMRS& vmr [[maybe_unused]],
49 const PredefinedModelData& predefined_model_data
52 case find_species_index(Species::Species::Water,
"ForeignContCKDMT400"):
53 if constexpr (not check_exist) MT_CKD400::compute_foreign_h2o(pm, f, p, t, vmr.H2O, predefined_model_data.get<MT_CKD400::WaterData>());
55 case find_species_index(Species::Species::Water,
"SelfContCKDMT400"):
56 if constexpr (not check_exist) MT_CKD400::compute_self_h2o(pm, f, p, t, vmr.H2O, predefined_model_data.get<MT_CKD400::WaterData>());
58 case find_species_index(Species::Species::Oxygen,
"MPM2020"):
59 if constexpr (not check_exist) MPM2020::compute(pm, f, p, t, vmr.O2);
61 case find_species_index(Species::Species::Oxygen,
"PWR2021"):
62 if constexpr (not check_exist) PWR20xx::compute_o2_2021(pm, f, p, t, vmr.O2, vmr.H2O);
64 case find_species_index(Species::Species::Water,
"PWR2021"):
65 if constexpr (not check_exist) PWR20xx::compute_h2o_2021(pm, f, p, t, vmr.H2O);
67 case find_species_index(Species::Species::Nitrogen,
"SelfContPWR2021"):
68 if constexpr (not check_exist) PWR20xx::compute_n2(pm, f, p, t, vmr.N2, vmr.H2O);
70 case find_species_index(Species::Species::Oxygen,
"PWR2022"):
71 if constexpr (not check_exist) PWR20xx::compute_o2_2022(pm, f, p, t, vmr.O2, vmr.H2O);
73 case find_species_index(Species::Species::Water,
"PWR2022"):
74 if constexpr (not check_exist) PWR20xx::compute_h2o_2022(pm, f, p, t, vmr.H2O);
76 case find_species_index(Species::Species::Oxygen,
"PWR98"):
77 if constexpr (not check_exist) PWR98::oxygen(pm, f, p, t, vmr.O2, vmr.H2O);
79 case find_species_index(Species::Species::Oxygen,
"TRE05"):
80 if constexpr (not check_exist) TRE05::oxygen(pm, f, p, t, vmr.O2, vmr.H2O);
82 case find_species_index(Species::Species::Water,
"PWR98"):
83 if constexpr (not check_exist) PWR98::water(pm, f, p, t, vmr.H2O);
85 case find_species_index(Species::Species::Oxygen,
"MPM89"):
86 if constexpr (not check_exist) MPM89::oxygen(pm, f, p, t, vmr.O2, vmr.H2O);
88 case find_species_index(Species::Species::Water,
"MPM89"):
89 if constexpr (not check_exist) MPM89::water(pm, f, p, t, vmr.H2O);
91 case find_species_index(Species::Species::Nitrogen,
"SelfContMPM93"):
92 if constexpr (not check_exist) MPM93::nitrogen(pm, f, p, t, vmr.N2, vmr.H2O);
94 case find_species_index(Species::Species::Water,
"ForeignContCKDMT350"):
95 if constexpr (not check_exist) CKDMT350::compute_foreign_h2o(pm, f, p, t, vmr.H2O);
97 case find_species_index(Species::Species::Water,
"SelfContCKDMT350"):
98 if constexpr (not check_exist) CKDMT350::compute_self_h2o(pm, f, p, t, vmr.H2O);
100 case find_species_index(Species::Species::Water,
"ForeignContCKDMT320"):
101 if constexpr (not check_exist) CKDMT320::compute_foreign_h2o(pm, f, p, t, vmr.H2O);
103 case find_species_index(Species::Species::Water,
"SelfContCKDMT320"):
104 if constexpr (not check_exist) CKDMT320::compute_self_h2o(pm, f, p, t, vmr.H2O);
106 case find_species_index(Species::Species::Water,
"ForeignContStandardType"):
107 if constexpr (not check_exist) Standard::water_foreign(pm, f, p, t, vmr.H2O);
109 case find_species_index(Species::Species::Water,
"SelfContStandardType"):
110 if constexpr (not check_exist) Standard::water_self(pm, f, p, t, vmr.H2O);
112 case find_species_index(Species::Species::Oxygen,
"SelfContStandardType"):
113 if constexpr (not check_exist) Standard::oxygen(pm, f, p, t, vmr.O2, vmr.H2O);
115 case find_species_index(Species::Species::Nitrogen,
"SelfContStandardType"):
116 if constexpr (not check_exist) Standard::nitrogen(pm, f, p, t, vmr.N2);
118 case find_species_index(Species::Species::CarbonDioxide,
"CKDMT252"):
119 if constexpr (not check_exist) MT_CKD252::carbon_dioxide(pm, f, p, t, vmr.CO2);
121 case find_species_index(Species::Species::Oxygen,
"visCKDMT252"):
122 if constexpr (not check_exist) MT_CKD252::oxygen_vis(pm, f, p, t, vmr.O2);
124 case find_species_index(Species::Species::Nitrogen,
"CIAfunCKDMT252"):
125 if constexpr (not check_exist) MT_CKD252::nitrogen_fun(pm, f, p, t, vmr.N2, vmr.H2O, vmr.O2);
127 case find_species_index(Species::Species::Nitrogen,
"CIArotCKDMT252"):
128 if constexpr (not check_exist) MT_CKD252::nitrogen_rot(pm, f, p, t, vmr.N2, vmr.H2O, vmr.O2);
130 case find_species_index(Species::Species::Oxygen,
"CIAfunCKDMT100"):
131 if constexpr (not check_exist) MT_CKD100::oxygen_cia(pm, f, p, t, vmr.O2);
133 case find_species_index(Species::Species::Oxygen,
"v0v0CKDMT100"):
134 if constexpr (not check_exist) MT_CKD100::oxygen_v0v0(pm, f, p, t, vmr.O2, vmr.N2);
136 case find_species_index(Species::Species::Oxygen,
"v1v0CKDMT100"):
137 if constexpr (not check_exist) MT_CKD100::oxygen_v0v1(pm, f, p, t, vmr.O2);
139 case find_species_index(Species::Species::liquidcloud,
"ELL07"):
140 if constexpr (not check_exist) ELL07::compute(pm, f, t, vmr.LWC);
142 case find_species_index(Species::Species::FINAL,
"Not A Model"):
break;
148 PropagationMatrix pm;
149 return compute_selection<true>(pm, model, {}, {}, {}, {}, {});
158template <
bool special>
160 if constexpr (special) {
163 constexpr Numeric
d = 1e-6;
164 constexpr Numeric l =
d * 1e-4;
165 return x < l ?
d : x *
d;
186template <
bool special>
188 const PropagationMatrix& pm,
194 const Species::Species spec,
195 const PredefinedModelData& predefined_model_data
200 case Species::Species::Oxygen:
201 dvmr = dvmr_calc<special>(vmr.
O2);
202 if constexpr (not special) vmr.
O2 += dvmr;
204 case Species::Species::Water:
205 dvmr = dvmr_calc<special>(vmr.
H2O);
206 if constexpr (not special) vmr.
H2O += dvmr;
208 case Species::Species::Nitrogen:
209 dvmr = dvmr_calc<special>(vmr.
N2);
210 if constexpr (not special) vmr.
N2 += dvmr;
212 case Species::Species::CarbonDioxide:
213 dvmr = dvmr_calc<special>(vmr.
CO2);
214 if constexpr (not special) vmr.
CO2 += dvmr;
216 case Species::Species::liquidcloud:
217 dvmr = dvmr_calc<special>(vmr.
LWC);
218 if constexpr (not special) vmr.
LWC += dvmr;
224 sizeof(
VMRS) /
sizeof(Numeric) == 5,
225 "It seems you have changed VMRS. Please check that the derivatives are up-to-date above this assert");
227 if constexpr (not special) {
229 compute_selection<false>(dpm, model, f, p, t, vmr, predefined_model_data);
237 compute_vmr_deriv<false>(
238 dpm, pm, model, f, p, t, vmr, spec, predefined_model_data);
244void compute(PropagationMatrix& propmat_clearsky,
245 ArrayOfPropagationMatrix& dpropmat_clearsky_dx,
247 const Vector& f_grid,
248 const Numeric& rtp_pressure,
249 const Numeric& rtp_temperature,
252 const PredefinedModelData& predefined_model_data) {
253 if (not compute_selection<true>(propmat_clearsky,
259 predefined_model_data))
264 const bool do_vmrs_jac =
265 std::any_of(jacobian_quantities.begin(),
266 jacobian_quantities.end(),
267 [](
auto& deriv) { return deriv == Jacobian::Line::VMR; }) or
268 std::any_of(jacobian_quantities.begin(),
269 jacobian_quantities.end(),
270 [model](
auto& deriv) {
271 return deriv == Jacobian::Special::ArrayOfSpeciesTagVMR and
272 std::any_of(deriv.Target().species_array_id.begin(),
273 deriv.Target().species_array_id.end(),
275 return tag.Isotopologue() == model;
279 if (do_freq_jac or do_temp_jac or do_vmrs_jac) {
281 PropagationMatrix pm(f_grid.nelem());
282 PropagationMatrix dpm(f_grid.nelem());
283 compute_selection<false>(pm,
289 predefined_model_data);
292 propmat_clearsky.Kjj() += pm.Kjj();
299 compute_selection<false>(dpm,
305 predefined_model_data);
308 for (Index iq = 0; iq < dpropmat_clearsky_dx.nelem(); iq++) {
309 if (jacobian_quantities[iq] == Jacobian::Atm::Temperature) {
310 dpropmat_clearsky_dx[iq].Kjj() += dpm.Kjj();
323 compute_selection<false>(dpm,
329 predefined_model_data);
332 for (Index iq = 0; iq < dpropmat_clearsky_dx.nelem(); iq++) {
334 dpropmat_clearsky_dx[iq].Kjj() += dpm.Kjj();
339 for (Index iq = 0; iq < dpropmat_clearsky_dx.nelem(); iq++) {
340 auto& deriv = jacobian_quantities[iq];
341 if (deriv == Jacobian::Line::VMR) {
342 if (compute_vmr_deriv<false>(dpm,
349 deriv.QuantumIdentity().Species(),
350 predefined_model_data))
351 dpropmat_clearsky_dx[iq].Kjj() += dpm.Kjj();
352 }
else if (deriv == Jacobian::Special::ArrayOfSpeciesTagVMR and
353 std::any_of(deriv.Target().species_array_id.begin(),
354 deriv.Target().species_array_id.end(),
356 return tag.Isotopologue() == model;
358 if (compute_vmr_deriv<true>(
366 deriv.Target().species_array_id.front().Spec(),
367 predefined_model_data))
368 dpropmat_clearsky_dx[iq].Kjj() += dpm.Kjj();
372 compute_selection<false>(propmat_clearsky,
378 predefined_model_data);
This can be used to make arrays out of anything.
Helper macros for debugging.
#define ARTS_ASSERT(condition,...)
bool do_frequency_jacobian(const ArrayOfRetrievalQuantity &js) noexcept
Returns if the array wants a frequency derivative.
bool do_temperature_jacobian(const ArrayOfRetrievalQuantity &js) noexcept
Returns if the array wants the temperature derivative.
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.
Numeric frequency_perturbation(const ArrayOfRetrievalQuantity &js) noexcept
Returns the frequency perturbation if it exists.
Routines for setting up the jacobian.
Constains various line scaling functions.
bool compute_vmr_deriv(PropagationMatrix &dpm, const PropagationMatrix &pm, const SpeciesIsotopeRecord &model, const Vector &f, const Numeric &p, const Numeric &t, VMRS vmr, const Species::Species spec, const PredefinedModelData &predefined_model_data)
Compute the partial VMR derivative.
bool compute_selection(PropagationMatrix &pm, const SpeciesIsotopeRecord &model, const Vector &f, const Numeric &p, const Numeric &t, const VMRS &vmr, const PredefinedModelData &predefined_model_data)
Compute the selected model and returns if it can be computed.
constexpr Numeric dvmr_calc(Numeric x) noexcept
Sets a VMR perturbation.
bool can_compute(const SpeciesIsotopeRecord &model)
Returns true if the model can be computed.
void compute(PropagationMatrix &propmat_clearsky, ArrayOfPropagationMatrix &dpropmat_clearsky_dx, const SpeciesIsotopeRecord &model, const Vector &f_grid, const Numeric &rtp_pressure, const Numeric &rtp_temperature, const VMRS &vmr, const ArrayOfRetrievalQuantity &jacobian_quantities, const PredefinedModelData &predefined_model_data)
Compute the predefined model.
constexpr Index find_species_index(const Species spec, const std::string_view isot) noexcept
invlib::Vector< ArtsVector > Vector
invlib wrapper type for ARTS vectors.
Contains known required VMR values.
Struct containing all information needed about one isotope.