42 for (
auto&
var : main) {
43 const bool bad_stokes = sd not_eq
var.StokesDimensions();
44 const bool bad_freq = nf not_eq
var.NumberOfFrequencies();
45 if (bad_freq or bad_stokes)
return true;
52 for (
auto& species : abs_species) {
53 if (species.nelem()) {
54 for (
auto& spec : species)
55 if (species[0].
Species() not_eq spec.Species() or
56 species[0].Isotopologue() not_eq spec.Isotopologue() or
57 species[0].Type() not_eq spec.Type())
69 else if (
min(var) < 0)
79 else if (
min(var) < 0)
102 const Numeric& rtp_temperature,
103 const Index& manual_tag,
113 const Index nq = jacobian_quantities_positions.
nelem();
118 const bool do_src = not nlte_source.empty();
119 const bool do_jac = not jacobian_quantities_positions.
nelem();
121 throw "*abs_species* sub-arrays must have the same species, isotopologue, and type as first sub-array.";
122 if ((rtp_mag.
nelem() not_eq 3) and (not manual_tag))
123 throw "Only for 3D *rtp_mag* or a manual magnetic field";
124 if (rtp_vmr.
nelem() not_eq abs_species.
nelem())
125 throw "*rtp_vmr* must match *abs_species*";
126 if (abs_species.
nelem() not_eq propmat_clearsky.
nelem())
127 throw "*abs_species* must match *propmat_clearsky*";
129 throw "*propmat_clearsky* must have *stokes_dim* 4 and frequency dim same as *f_grid*";
130 if (do_src and (nlte_source.
nelem() not_eq abs_species.
nelem()))
131 throw "*abs_species* must match *nlte_source* when non-LTE is on";
133 throw "*nlte_source* must have *stokes_dim* 4 and frequency dim same as *f_grid* when non-LTE is on";
134 if (do_jac and (nq not_eq dpropmat_clearsky_dx.
nelem()))
135 throw "*dpropmat_clearsky_dx* must match derived form of *jacobian_quantities*";
136 if (do_jac and
bad_propmat(dpropmat_clearsky_dx, f_grid))
137 throw "*dpropmat_clearsky_dx* must have Stokes dim 4 and frequency dim same as *f_grid*";
138 if (do_jac and do_src and (nq not_eq dnlte_dx_source.
nelem()))
139 throw "*dnlte_dx_source* must match derived form of *jacobian_quantities* when non-LTE is on";
140 if (do_jac and do_src and
bad_propmat(dnlte_dx_source, f_grid))
141 throw "*dnlte_dx_source* must have Stokes dim 4 and frequency dim same as *f_grid* when non-LTE is on";
142 if (do_jac and do_src and (nq not_eq nlte_dsource_dx.
nelem()))
143 throw "*nlte_dsource_dx* must match derived form of *jacobian_quantities* when non-LTE is on";
144 if (do_jac and do_src and
bad_propmat(nlte_dsource_dx, f_grid))
145 throw "*nlte_dsource_dx* must have Stokes dim 4 and frequency dim same as *f_grid* when non-LTE is on";
146 if (
any_negative(f_grid))
throw "Negative frequency (at least one value).";
147 if (
any_negative(rtp_vmr))
throw "Negative VMR (at least one value).";
148 if (
any_negative(rtp_nlte.
Data()))
throw "Negative NLTE (at least one value).";
149 if (rtp_temperature <= 0)
throw "Non-positive temperature";
150 if (rtp_pressure <= 0)
throw "Non-positive pressure";
151 if (manual_tag and H0 < 0)
throw "Negative manual magnetic field strength";
155 const Numeric dnumdens_dt_dmvr =
174 const auto polarization_scale_dtheta_data =
176 const auto polarization_scale_deta_data =
183 planck(B, f_grid, rtp_temperature);
198 for (
Index ispecies = 0; ispecies <
ns; ispecies++) {
201 if (not abs_species[ispecies].
nelem() or not
is_zeeman(abs_species[ispecies]) or not abs_lines_per_species[ispecies].
nelem())
204 for (
auto& band : abs_lines_per_species[ispecies]) {
207 partition_functions.
getParamType(band.QuantumIdentity()),
208 partition_functions.
getParam(band.QuantumIdentity()));
210 partition_functions.
getParamType(band.QuantumIdentity()),
211 partition_functions.
getParam(band.QuantumIdentity()));
213 partition_functions.
getParamType(band.QuantumIdentity()),
214 partition_functions.
getParam(band.QuantumIdentity()));
217 const Vector line_shape_vmr = band.BroadeningSpeciesVMR(rtp_vmr, abs_species);
218 const Numeric numdens = rtp_vmr[ispecies] * dnumdens_dmvr;
219 const Numeric dnumdens_dT = rtp_vmr[ispecies] * dnumdens_dt_dmvr;
228 jacobian_quantities_positions,
244 auto pol_real = pol.attenuation();
245 auto pol_imag = pol.dispersion();
246 auto abs = propmat_clearsky[ispecies].Data()(0, 0,
joker,
joker);
249 MapToEigen(
abs).leftCols<4>().noalias() += numdens * sum.
F.real() * pol_real;
250 MapToEigen(
abs).rightCols<3>().noalias() += numdens * sum.
F.imag() * pol_imag;
253 for (
Index j = 0; j < nq; j++) {
254 const auto& deriv = jacobian_quantities[jacobian_quantities_positions[j]];
256 Eigen::Matrix<Numeric, Eigen::Dynamic, 7, Eigen::RowMajor>>
257 dabs(dpropmat_clearsky_dx[j].Data().get_c_array(),
261 dabs.leftCols<4>().noalias() +=
262 numdens * sum.
dF.col(j).real() * pol_real +
263 dnumdens_dT * sum.
F.real() * pol_real;
264 dabs.rightCols<3>().noalias() +=
265 numdens * sum.
dF.col(j).imag() * pol_imag +
266 dnumdens_dT * sum.
F.imag() * pol_imag;
268 dabs.leftCols<4>().noalias() +=
269 numdens * X.dH_du * sum.
dF.col(j).real() * pol_real +
270 numdens * X.deta_du * sum.
F.real() *
271 dpol_deta.attenuation() +
272 numdens * X.dtheta_du * sum.
F.real() *
273 dpol_dtheta.attenuation();
274 dabs.rightCols<3>().noalias() +=
275 numdens * X.dH_du * sum.
dF.col(j).imag() * pol_imag +
276 numdens * X.deta_du * sum.
F.imag() *
277 dpol_deta.dispersion() +
278 numdens * X.dtheta_du * sum.
F.imag() *
279 dpol_dtheta.dispersion();
281 dabs.leftCols<4>().noalias() +=
282 numdens * X.dH_dv * sum.
dF.col(j).real() * pol_real +
283 numdens * X.deta_dv * sum.
F.real() *
284 dpol_deta.attenuation() +
285 numdens * X.dtheta_dv * sum.
F.real() *
286 dpol_dtheta.attenuation();
287 dabs.rightCols<3>().noalias() +=
288 numdens * X.dH_dv * sum.
dF.col(j).imag() * pol_imag +
289 numdens * X.deta_dv * sum.
F.imag() *
290 dpol_deta.dispersion() +
291 numdens * X.dtheta_dv * sum.
F.imag() *
292 dpol_dtheta.dispersion();
294 dabs.leftCols<4>().noalias() +=
295 numdens * X.dH_dw * sum.
dF.col(j).real() * pol_real +
296 numdens * X.deta_dw * sum.
F.real() *
297 dpol_deta.attenuation() +
298 numdens * X.dtheta_dw * sum.
F.real() *
299 dpol_dtheta.attenuation();
300 dabs.rightCols<3>().noalias() +=
301 numdens * X.dH_dw * sum.
dF.col(j).imag() * pol_imag +
302 numdens * X.deta_dw * sum.
F.imag() *
303 dpol_deta.dispersion() +
304 numdens * X.dtheta_dw * sum.
F.imag() *
305 dpol_dtheta.dispersion();
307 deriv.QuantumIdentity().In(band.QuantumIdentity())) {
308 dabs.leftCols<4>().noalias() +=
309 numdens * sum.
dF.col(j).real() * pol_real +
310 dnumdens_dmvr * sum.
F.real() * pol_real;
311 dabs.rightCols<3>().noalias() +=
312 numdens * sum.
dF.col(j).imag() * pol_imag +
313 dnumdens_dmvr * sum.
F.imag() * pol_imag;
315 dabs.leftCols<4>().noalias() +=
316 numdens * sum.
dF.col(j).real() * pol_real;
317 dabs.rightCols<3>().noalias() +=
318 numdens * sum.
dF.col(j).imag() * pol_imag;
326 nlte_source[ispecies].Data()(0, 0,
joker,
joker);
330 .noalias() += numdens * eB.cwiseProduct(sum.
N.real()) * pol_real;
332 for (
Index j = 0; j < nq; j++) {
334 jacobian_quantities[jacobian_quantities_positions[j]];
337 Eigen::Matrix<Numeric, Eigen::Dynamic, 4, Eigen::RowMajor>>
338 dnlte_dx_src(dnlte_dx_source[j].Data().get_c_array(),
340 nlte_dsrc_dx(nlte_dsource_dx[j].Data().get_c_array(),
344 dnlte_dx_src.noalias() +=
345 dnumdens_dT * eB.cwiseProduct(sum.
N.real()) * pol_real +
346 numdens * eB.cwiseProduct(sum.
dN.col(j).real()) * pol_real;
348 nlte_dsrc_dx.noalias() +=
349 numdens * edBdT.cwiseProduct(sum.
N.real()) * pol_real;
351 dnlte_dx_src.noalias() +=
352 numdens * X.dH_du * eB.cwiseProduct(sum.
dN.col(j).real()) * pol_real +
353 numdens * X.deta_du * eB.cwiseProduct(sum.
N.real()) *
354 dpol_deta.attenuation() +
355 numdens * X.dtheta_du * eB.cwiseProduct(sum.
N.real()) *
356 dpol_dtheta.attenuation();
358 dnlte_dx_src.noalias() +=
359 numdens * X.dH_dv * eB.cwiseProduct(sum.
dN.col(j).real()) * pol_real +
360 numdens * X.deta_dv * eB.cwiseProduct(sum.
N.real()) *
361 dpol_deta.attenuation() +
362 numdens * X.dtheta_dv * eB.cwiseProduct(sum.
N.real()) *
363 dpol_dtheta.attenuation();
365 dnlte_dx_src.noalias() +=
366 numdens * X.dH_dw * eB.cwiseProduct(sum.
dN.col(j).real()) * pol_real +
367 numdens * X.deta_dw * eB.cwiseProduct(sum.
N.real()) *
368 dpol_deta.attenuation() +
369 numdens * X.dtheta_dw * eB.cwiseProduct(sum.
N.real()) *
370 dpol_dtheta.attenuation();
372 deriv.QuantumIdentity().In(band.QuantumIdentity()))
373 dnlte_dx_src.noalias() +=
374 dnumdens_dmvr * eB.cwiseProduct(sum.
N.real()) * pol_real +
375 numdens * eB.cwiseProduct(sum.
dN.col(j).real()) * pol_real;
377 dnlte_dx_src.noalias() +=
378 numdens * eB.cwiseProduct(sum.
dN.col(j).real()) * pol_real;
384 }
catch (
const char* e) {
386 os <<
"Errors raised by *zeeman_on_the_fly* internal function:\n";
387 os <<
"\tError: " << e <<
'\n';
388 throw std::runtime_error(os.str());
389 }
catch (
const std::exception& e) {
392 os <<
"Errors in calls by *zeeman_on_the_fly* internal function:\n";
394 throw std::runtime_error(os.str());
INDEX Index
The type to use for all integer numbers and indices.
ArrayOfIndex equivalent_propmattype_indexes(const ArrayOfRetrievalQuantity &js)
Returns a list of positions for the derivatives in Propagation Matrix calculations.
void var(VectorView var, const Vector &y, const ArrayOfVector &ys, const Index start=0, const Index end=-1)
Compute the variance of the ranged ys.
bool bad_abs_species(const ArrayOfArrayOfSpeciesTag &abs_species)
Checks if abs_species is acceptable.
Index nelem() const
Number of elements.
QuantumIdentifier::QType Index LowerQuantumNumbers Species
const Tensor4 & Data() const noexcept
Energy level type.
Constants of physical expressions as constexpr.
void set_cross_section_of_band(InternalData &scratch, InternalData &sum, const ConstVectorView f_grid, const AbsorptionLines &band, const ArrayOfRetrievalQuantity &derivatives_data, const ArrayOfIndex &derivatives_data_active, const Vector &vmrs, const EnergyLevelMap &nlte, const Numeric &P, const Numeric &T, const Numeric &isot_ratio, const Numeric &H, const Numeric &DC, const Numeric &dDCdT, const Numeric &QT, const Numeric &dQTdT, const Numeric &QT0, const bool no_negatives=false, const bool zeeman=false, const Zeeman::Polarization zeeman_polarization=Zeeman::Polarization::Pi)
Computes the cross-section of an absorption band.
const PolarizationVector & SelectPolarization(const AllPolarizationVectors &data, Polarization type) noexcept
Selects the polarization vector depending on polarization type.
constexpr Numeric deg2rad(T x)
Converts degrees to radians.
bool empty() const
Returns true if variable size is zero.
Some molecular constants.
Numeric dsingle_partition_function_dT(const Numeric &QT, const Numeric &T, const Numeric &dT, const SpeciesAuxData::AuxType &partition_type, const ArrayOfGriddedField1 &partition_data)
Computes the partition function temperature derivative.
AllPolarizationVectors AllPolarization_deta(Numeric theta, Numeric eta) noexcept
The derivative of AllPolarization wrt eta.
Numeric number_density(const Numeric &p, const Numeric &t)
number_density
Index nelem() const
Returns the number of elements.
bool any_negative(const Vector &var)
Checks for negative values.
Stuff related to lineshape functions.
const AuxType & getParamType(const Index species, const Index isotopologue) const
Return a constant reference to the parameter types.
Numeric dplanck_dt(const Numeric &f, const Numeric &t)
dplanck_dt
Numeric getIsotopologueRatio(const SpeciesTag &st) const
Returns mparams[st.Species()][st.Isotopologue()][0].data[0] if st.Isotopologue() > 0...
const ArrayOfQuantumIdentifier & Levels() const noexcept
Energy level type.
Numeric temperature_perturbation(const ArrayOfRetrievalQuantity &js) noexcept
Returns the temperature perturbation if it exists.
const ArrayOfGriddedField1 & getParam(const Index species, const Index isotopologue) const
Return a constant reference to the parameters.
Numeric dnumber_density_dt(const Numeric &p, const Numeric &t)
dnumber_density_dT
NUMERIC Numeric
The type to use for all floating point numbers.
constexpr Derived FromPreDerived(Numeric H, Numeric theta, Numeric eta) noexcept
Sets Derived from predefined Derived parameters.
Numeric dDopplerConstant_dT(const Numeric &T, const Numeric &dc)
Returns the temperature derivative of the frequency-independent part of the Doppler broadening...
int main(int argc, char **argv)
This is the main function of ARTS.
basic_ostringstream< char, string_char_traits< char >, alloc > ostringstream
This can be used to make arrays out of anything.
Constains various line scaling functions.
bool empty() const
Check if variable is empty.
Numeric DopplerConstant(Numeric T, Numeric mass)
Returns the frequency-independent part of the Doppler broadening.
Index nelem(const Lines &l)
Number of lines.
Numeric planck(const Numeric &f, const Numeric &t)
planck
Derived FromGrids(Numeric u, Numeric v, Numeric w, Numeric z, Numeric a) noexcept
Computes the derived plane from ARTS grids.
Numeric single_partition_function(const Numeric &T, const SpeciesAuxData::AuxType &partition_type, const ArrayOfGriddedField1 &partition_data)
Computes the partition function at one temperature.
AllPolarizationVectors AllPolarization_dtheta(Numeric theta, const Numeric eta) noexcept
The derivative of AllPolarization wrt theta.
Auxiliary data for isotopologues.
ComplexConstMatrixViewMap MapToEigen(const ConstComplexMatrixView &A)
void zeeman_on_the_fly(ArrayOfPropagationMatrix &propmat_clearsky, ArrayOfStokesVector &nlte_source, ArrayOfPropagationMatrix &dpropmat_clearsky_dx, ArrayOfStokesVector &dnlte_dx_source, ArrayOfStokesVector &nlte_dsource_dx, const ArrayOfArrayOfSpeciesTag &abs_species, const ArrayOfRetrievalQuantity &jacobian_quantities, const ArrayOfArrayOfAbsorptionLines &abs_lines_per_species, const SpeciesAuxData &isotopologue_ratios, const SpeciesAuxData &partition_functions, const Vector &f_grid, const Vector &rtp_vmr, const EnergyLevelMap &rtp_nlte, const Vector &rtp_mag, const Vector &rtp_los, const Numeric &rtp_pressure, const Numeric &rtp_temperature, const Index &manual_tag, const Numeric &H0, const Numeric &theta0, const Numeric &eta0)
Main and only way to compute Zeeman effect.
bool bad_propmat(const Array< T > &main, const Vector &f_grid, const Index sd=4)
Checks if a Propagation Matrix or something similar has good grids.
AllPolarizationVectors AllPolarization(Numeric theta, Numeric eta) noexcept
Computes the polarization of each polarization type.