56 throw std::runtime_error(
57 "Error in getB0: Unsupported main species/isotopologue. Check your broadening data");
70 throw std::runtime_error(
71 "Error in adiabatic_factor: Unsupported species pairs, main-collider. Check your broadening data");
93 throw std::runtime_error(
94 "Error in basis_rate: Unsupported species pairs, main-collider. Check your broadening data");
104 const Index& size)
try {
115 const Vector pseudo_vmrs({1, 0});
120 if (
main.IsSpecies(
"CO2"))
122 else if (
main.IsSpecies(
"O2") and
main.IsIsotopologue(
"66"))
125 throw "Unsupported species";
127 #pragma omp parallel for schedule( \ 128 guided, 1) if (DO_FAST_WIGNER && !arts_omp_in_parallel()) 131 wig_temp_init(2 *
int(size));
134 W(
i,
i) = shape_parameters.G0;
136 const Numeric& popi = population[
i];
137 for (
Index j = 0; j <
n; j++) {
138 const Numeric& popj = population[j];
173 throw "DEVELOPER BUG: Add species here as well, the other one is to check if the computations are valid at all...";
188 }
catch (
const char* e) {
190 os <<
"Errors raised by *relaxation_matrix_calculations*:\n";
191 os <<
"\tError: " << e <<
'\n';
192 throw std::runtime_error(os.str());
193 }
catch (
const std::exception& e) {
195 os <<
"Errors in calls by *relaxation_matrix_calculations*:\n";
197 throw std::runtime_error(os.str());
238 for (
Index i = 0; i <
n; i++) {
239 Wr(i, i) = W(sorted[i], sorted[i]);
240 for (
Index j = 0; j <
n; j++) {
242 Wr(i, j) = -
std::abs(W(sorted[i], sorted[j]));
248 for (
Index i = 0; i <
n; i++) {
251 for (
Index j = 0; j <
n; j++) {
253 Sup +=
std::abs(d[sorted[j]]) * Wr(i, j);
255 Slo +=
std::abs(d[sorted[j]]) * Wr(i, j);
259 if (not std::isnormal(UL)) UL = 1.0;
262 for (
Index j = i; j <
n; j++) {
263 const Numeric r = population[sorted[
i]] / population[sorted[j]];
264 Wr(j, i) = r * Wr(i, j);
265 if (j not_eq i) Wr(i, j) *= -UL;
269 for (
Index i = 0; i < n - 1; i++) Wr(n - 1, i) = 0;
272 for (
Index i = 0; i <
n; i++)
273 for (
Index j = 0; j <
n; j++) W(sorted[i], sorted[j]) = Wr(i, j);
274 }
catch (
const char* e) {
276 os <<
"Errors raised by *normalize_relaxation_matrix*:\n";
277 os <<
"\tError: " << e <<
'\n';
278 throw std::runtime_error(os.str());
279 }
catch (
const std::exception& e) {
281 os <<
"Errors in calls by *normalize_relaxation_matrix*:\n";
283 throw std::runtime_error(os.str());
291 const Vector& colliders_vmr,
294 const Index& size)
try {
302 for (
Index ic = 0; ic < c; ic++)
310 W, population, d0, band, partition_functions, T);
314 }
catch (
const char* e) {
316 os <<
"Errors raised by *hartmann_relaxation_matrix*:\n";
317 os <<
"\tError: " << e <<
'\n';
318 throw std::runtime_error(os.str());
319 }
catch (
const std::exception& e) {
321 os <<
"Errors in calls by *hartmann_relaxation_matrix*:\n";
323 throw std::runtime_error(os.str());
353 for (
auto k = 0; k <
n; k++) {
359 }
catch (
const char* e) {
361 os <<
"Errors raised by *population_density_vector*:\n";
362 os <<
"\tError: " << e <<
'\n';
363 throw std::runtime_error(os.str());
364 }
catch (
const std::exception& e) {
366 os <<
"Errors in calls by *population_density_vector*:\n";
368 throw std::runtime_error(os.str());
380 for (
Index k = 0; k <
n; k++) {
385 }
catch (
const char* e) {
387 os <<
"Errors raised by *dipole_vector*:\n";
388 os <<
"\tError: " << e <<
'\n';
389 throw std::runtime_error(os.str());
390 }
catch (
const std::exception& e) {
392 os <<
"Errors in calls by *dipole_vector*:\n";
394 throw std::runtime_error(os.str());
419 }
catch (
const char* e) {
421 os <<
"Errors raised by *reduced_dipole_vector*:\n";
422 os <<
"\tError: " << e <<
'\n';
423 throw std::runtime_error(os.str());
424 }
catch (
const std::exception& e) {
426 os <<
"Errors in calls by *reduced_dipole_vector*:\n";
428 throw std::runtime_error(os.str());
439 for (
Index j = 0; j <
n; j++) {
441 if (std::isnormal(df)) sum += d0[j] / d0[
i] * W(
i, j) / df;
456 for (
Index j = 0; j <
n; j++) {
458 if (std::isnormal(df)) sum += W(
i, j) * W(j,
i) / df;
478 for (
Index j = 0; j <
n; j++) {
480 if (std::isnormal(df)) {
485 sum2 += r * W(
i, j) / df;
489 for (
Index k = 0; k <
n; k++) {
491 if (std::isnormal(dfk)) sum_tmp += W(k, j) * W(
i, k) / (dfk * df);
503 const Vector& collider_species_vmr,
506 const Index& size)
try {
514 collider_species_vmr,
519 }
catch (
const std::exception& e) {
521 os <<
"Errors in calls by *hartmann_ecs_interface*:\n";
523 throw std::runtime_error(os.str());
542 const Numeric& collider_mass) {
543 const bool jbig = Jjl >= Jkl;
547 const int Ji = (2 * (jbig ? Jju : Jku)).
toInt();
548 const int Jf = (2 * (jbig ? Jjl : Jkl)).toInt();
549 const int Ji_p = (2 * (jbig ? Jku : Jju)).toInt();
550 const int Jf_p = (2 * (jbig ? Jkl : Jjl)).toInt();
551 const int li = (2 * (jbig ? l2ju : l2ku)).toInt();
552 const int lf = (2 * (jbig ? l2jl : l2kl)).toInt();
556 const int en =
std::min(Ji + Ji_p, Jf + Jf_p);
559 const Numeric AF1 = af.
get(Ji / 2, B0, T, main_mass, collider_mass);
562 const Numeric K1 = (((li + lf) % 4) ? 1.0 : -1.0) *
Numeric(Ji_p + 1) *
566 for (
int L = 4; L <= en; L += 4) {
572 const Numeric AF2 = af.
get(L / 2, B0, T, main_mass, collider_mass);
584 return {jbig ? sum : sum *
r, jbig ? sum /
r : sum};
603 for (
auto&
r : Ji) rmax =
max(
r, rmax);
604 for (
auto&
r : Jf) rmax =
max(
r, rmax);
608 #pragma omp parallel for schedule( \ 609 guided, 1) if (DO_FAST_WIGNER && !arts_omp_in_parallel()) 611 wig_temp_init(
int(2 * rmax));
612 for (
Index j = 0; j <
n; j++) {
613 if (
i == j)
continue;
614 if (Ji[
i] < Ji[j])
continue;
616 const Numeric K1 = (((l2i[
i] + l2f[
i]) % 2) ? 1 : -1) *
618 sqrt((2 * Jf[
i] + 1) * (2 * Jf[j] + 1));
619 const Numeric d_ratio = d[j] / d[
i];
620 [[maybe_unused]]
const Numeric exp =
623 const int en =
std::min(
int(Ji[i] * 2) +
int(Ji[j] * 2),
624 int(Jf[i] * 2) +
int(Jf[j] * 2));
625 for (
int L = 4; L <= en; L += 4) {
634 const Numeric dE = L / 2 * (L / 2 + 1);
641 c[6] = std::log(dE) / T;
642 c[7] = std::log(dE) * std::log(dE);
646 for (
auto kk = 0; kk <
params; kk++)
647 M(i, j, kk) += a[kk] * K2 * (std::isnormal(c[kk]) ? c[kk] : 0);
650 if (std::isnormal(d_ratio))
651 M(i, j,
joker) *= d_ratio * K1;
656 M(i, j,
joker) *= rho[j] / rho[
i];
657 M(j, i,
joker) *= rho[
i] / rho[j];
674 const auto n = Ji.
nelem();
686 for (
Index j = 0; j <
n; j++) {
692 [[maybe_unused]]
const Numeric R2 =
lsf(a, A, gamma);
699 for (
Index j = 0; j <
n; j++) {
714 Numeric const1 = 0.086 + 8154e-7 * T;
715 static constexpr
Numeric const2 = 0.5805;
717 return (2 * L + 1) /
std::pow(L * L + L, const1) *
728 static constexpr
Numeric const1 = 0.545e-10;
729 static constexpr
Numeric constant = 2000 * R * inv_pi *
pow2(inv_ln_2);
732 const Numeric invmu = (1 /
mass + 1 / collider_mass);
733 const Numeric vm2 = constant * T * invmu;
753 const Numeric& collider_mass) {
758 J1u.
toNumeric(), (J1u - N1u).toInt(), (J1u - N1u).toInt()) >
760 J2u.
toNumeric(), (J2u - N2u).toInt(), (J2u - N2u).toInt());
763 const int Nk = (2 * (onebig ? N1u : N2u).toInt());
764 const int Nkp = (2 * (onebig ? N1l : N2l).toInt());
765 const int Jk = (2 * (onebig ? J1u : J2u).toInt());
766 const int Jkp = (2 * (onebig ? J1l : J2l).toInt());
767 const int Nl = (2 * (onebig ? N2u : N1u).toInt());
768 const int Nlp = (2 * (onebig ? N2l : N1l).toInt());
769 const int Jl = (2 * (onebig ? J2u : J1u).toInt());
770 const int Jlp = (2 * (onebig ? J2l : J1l).toInt());
772 if (Nl not_eq Nlp or Nk not_eq Nkp)
throw "ERRROR, bad N-values";
787 for (
int L = 4; L < 400; L += 4) {
788 const int sgn = ((Jk + Jl + L + 2) % 4) ? 1 : -1;
797 return {onebig ? sum : sum * rho2 / rho1, onebig ? sum * rho1 / rho2 : sum};
804 const Numeric& collider_mass)
const {
809 if (L < 1)
return 0.;
811 static constexpr
Numeric constant = 2000 * R * inv_pi *
pow2(inv_ln_2);
813 const Numeric invmu = (1 / main_mass + 1 / collider_mass);
815 const Numeric vm2 = constant * T * invmu;
818 mdata[
Index(HartmannPos::dc)]) /
832 return a1 /
std::pow(EL, a2) * std::exp(-a3 * h * B0 * EL / (k * T));
842 throw std::runtime_error(
"Bad input to compute_2nd_order_lm_coeff");
845 for (
auto i = 0;
i <
n - 1;
i++) {
846 if (x[
i] >= x[
i + 1])
847 throw std::runtime_error(
848 "Bad structure on x-input; must be constantly increasing");
849 if (x[
i] > x0) best_x++;
853 Vector ans(2, y[best_x] * 0.5), dans(2, 0), delta(n, 0);
858 constexpr
auto max_loop_count = 20;
861 for (
auto i = 0;
i <
n;
i++) {
865 A(
i, 1) = (theta - 1.0) * TP;
866 const Numeric f = ans[0] * TP + ans[1] * (theta - 1.0) * TP;
873 if (not std::isnormal(res))
break;
879 }
while (rel_res > rel_res_limit and loop_count < max_loop_count);
881 return {ans[0], ans[1]};
887 const Eigen::ComplexEigenSolver<Eigen::MatrixXcd>& M) {
888 const auto n = population.
nelem();
890 auto& V = M.eigenvectors();
891 auto Vinv = V.inverse().eval();
895 for (
auto i = 0;
i <
n;
i++) {
896 for (
auto j1 = 0; j1 <
n; j1++) {
897 for (
auto j2 = 0; j2 <
n; j2++) {
899 population[j1] * dipole[j1] * dipole[j2] * V(
i, j2) * Vinv(j1,
i);
908 const auto n = population.
nelem();
911 for (
auto i = 0;
i <
n;
i++) I0 += pi * population[
i] *
pow2(dipole[
i]);
918 const Index& wigner_initialized,
919 const Numeric& temperature)
try {
923 const Vector collider_species_vmr = {0.21, 0.79};
931 throw "Limit in functionality encountered. We only support CO2-626 and O2-66 for now.";
934 throw "Bad species length, only works for self+air broadening for now";
939 collider_species_vmr,
944 throw "Population type has not been implemented";
945 }
catch (
const char* e) {
947 os <<
"Errors raised by *relmatInAir*:\n";
948 os <<
"\tError: " << e <<
'\n';
949 throw std::runtime_error(os.str());
950 }
catch (
const std::exception& e) {
952 os <<
"Errors in calls by *relmatInAir*:\n";
954 throw std::runtime_error(os.str());
INDEX Index
The type to use for all integer numbers and indices.
Namespace containing several constants, physical and mathematical.
AdiabaticFactor adiabatic_factor(const SpeciesTag &main, const SpeciesTag &collider)
Struct to help keep position of the two matched outputs clear.
Vector vmrs(const ConstVectorView &atmospheric_vmrs, const ArrayOfArrayOfSpeciesTag &atmospheric_species, const QuantumIdentifier &self, const ArrayOfSpeciesTag &lineshape_species, bool self_in_list, bool bath_in_list, Type type)
Returns a VMR vector for this model's main calculations.
Numeric dstimulated_emissiondT(Numeric T, Numeric F0)
Computes temperature derivative of exp(-hf/kT)
Numeric o2_66_adiabatic_factor_makarov(int L, Numeric T, Numeric collider_mass)
Numeric dboltzman_factordT(Numeric T, Numeric E0)
Computes temperature derivatives exp(- E0/kT)
const ArrayOfSpeciesTag & BroadeningSpecies() const noexcept
Returns the broadening species.
Numeric lsf(VectorView x, ConstMatrixView A, ConstVectorView y, bool residual) noexcept
Least squares fitting by solving x for known A and y.
A class implementing complex numbers for ARTS.
Numeric T0() const noexcept
Returns reference temperature.
Numeric E0(size_t k) const noexcept
Lower level energy.
Index nelem() const
Number of elements.
void linearized_relaxation_matrix(Tensor3 &M, const ArrayOfRational &Ji, const ArrayOfRational &Jf, const ArrayOfRational &l2i, const ArrayOfRational &l2f, [[maybe_unused]] const Vector &F0, const Vector &d, const Vector &rho, const Numeric &T, const Vector &a=Vector(params, 1))
G0 G2 FVC Y DV Numeric E0
Numeric population_density(Numeric T, Numeric E0, Numeric F0, Numeric QT)
Rational LowerQuantumNumber(size_t k, QuantumNumberType qnt) const noexcept
Quantum number lower level.
Numeric o2_66_inelastic_cross_section_makarov(int L, Numeric T)
Index Species() const
Molecular species index.
Matrix CO2_ir_training(const ArrayOfRational &Ji, const ArrayOfRational &Jf, const ArrayOfRational &l2i, const ArrayOfRational &l2f, const Vector &F0, const Vector &d, const Vector &rho, const Vector &gamma, const Numeric &T)
CO2 IR training algorithm for linearization.
constexpr T hitran2arts_broadening(T x)
Index Isotopologue() const noexcept
Isotopologue Index.
Numeric reduced_magnetic_quadrapole(Rational Jf, Rational Ji, Rational N)
Compute the reduced magnetic quadrapole moment.
Numeric lte_linestrength(Numeric S0, Numeric E0, Numeric F0, Numeric QT0, Numeric T0, Numeric QT, Numeric T)
Gets the local thermodynamic equilibrium line strength.
Linear algebra functions.
Vector rosenkranz_shifting_second_order(const AbsorptionLines &band, const Matrix &W)
Computes DV for Rosenkranz's line mixing coefficients.
Numeric boltzman_factor(Numeric T, Numeric E0)
Computes exp(- E0/kT)
invlib::Vector< ArtsVector > Vector
invlib wrapper type for ARTS vectors.
ComplexVector equivalent_linestrengths(const Vector &population, const Vector &dipole, const Eigen::ComplexEigenSolver< Eigen::MatrixXcd > &M)
Equivalent line strengths.
Some molecular constants.
Index NumLines() const noexcept
Number of lines.
Line mixing calculation implementation.
Vector population_density_vector(const AbsorptionLines &band, const SpeciesAuxData &partition_functions, const Numeric &T)
Compute the population density.
Numeric stimulated_emission(Numeric T, Numeric F0)
Computes exp(-hf/kT)
Matrix relaxation_matrix_calculations(const AbsorptionLines &band, const Vector &population, const SpeciesTag &collider, const Numeric &collider_vmr, const Numeric &T, const Index &size)
constexpr T pow2(T x)
power of two
PopulationType Population() const noexcept
Returns population style.
Wigner symbol interactions.
Index nelem() const
Returns the number of elements.
bool Self() const noexcept
Returns self broadening status.
Contains sorting routines.
Numeric I0(size_t k) const noexcept
Reference line strength.
Numeric o2_ecs_wigner_symbol(int Nl, int Nk, int Jl, int Jk, int Jl_p, int Jk_p, int L)
Returns the wigner symbol used in Makarov etal 2013.
Rational UpperQuantumNumber(size_t k, QuantumNumberType qnt) const noexcept
Quantum number upper level.
Stuff related to lineshape functions.
const AuxType & getParamType(const Index species, const Index isotopologue) const
Return a constant reference to the parameter types.
void swap(ComplexVector &v1, ComplexVector &v2)
Swaps two objects.
bool IsSpecies(const String &s) const
Check if the species is same as SpeciesTag(s).Species()
RedPoleType
Type of reduced dipole.
Numeric reduced_rovibrational_dipole(Rational Jf, Rational Ji, Rational lf, Rational li, Rational k=Rational(1))
Compute the reduced rovibrational dipole moment.
Numeric co2_ecs_wigner_symbol(int Ji, int Jf, int Ji_p, int Jf_p, int L, int li, int lf)
Returns the wigner symbol used in Niro etal 2004.
Numeric get(const Numeric &L, const Numeric &B0, const Numeric &T) const
Get the basis rate.
OffDiagonalElementOutput O2_66_MW(const Rational &J1u, const Rational &N1u, const Rational &J1l, const Rational &N1l, const Rational &J2u, const Rational &N2u, const Rational &J2l, const Rational &N2l, const Numeric &rho1, const Numeric &rho2, const Numeric &T, const Numeric &collider_mass)
O2-66 MW off diagonal element computer.
Basis rate of transitions.
Numeric get(const Numeric &L, const Numeric &B0, const Numeric &T, const Numeric &main_mass, const Numeric &collider_mass) const
Get AF.
void relmatInAir(Matrix &relmat, const AbsorptionLines &band, const SpeciesAuxData &partition_functions, const Index &wigner_initialized, const Numeric &temperature)
Compute the relaxation matrix in air mixture.
Implements rational numbers to work with other ARTS types.
bool Bath() const noexcept
Returns bath broadening status.
Numeric hamiltonian_freq(T J, int dcol=0, int drow=0)
Hamiltonian frequency.
Index Species() const noexcept
Species Index.
A tag group can consist of the sum of several of these.
Numeric mol_X(const Numeric &L, const Numeric &B0, const Numeric &T) const
Computes the basis rate using Hartman method.
constexpr Numeric kaycm2freq(T x)
Vector dipole_vector(const AbsorptionLines &band, const SpeciesAuxData &partition_functions)
Dipole vector.
const ArrayOfGriddedField1 & getParam(const Index species, const Index isotopologue) const
Return a constant reference to the parameters.
Numeric getB0(const SpeciesTag &main)
NUMERIC Numeric
The type to use for all floating point numbers.
Numeric SpeciesMass() const
Mass of main species.
bool IsIsotopologue(const String &i) const
Check if the isotopologue is same as SpeciesTag(s).Isotopologue()
To keep track of (y0 + y1 * (T0 / T - 1.)) * pow(T0 / T, n)
int main(int argc, char **argv)
This is the main function of ARTS.
Numeric dpopulation_densitydT(Numeric T, Numeric E0, Numeric F0, Numeric QT, Numeric dQTdT)
BasisRate basis_rate(const SpeciesTag &main, const SpeciesTag &collider, const Numeric &T, const Numeric &T0)
constexpr Numeric toNumeric() const
Converts this to a Numeric.
Numeric pow(const Rational base, Numeric exp)
Power of.
void get_sorted_indexes(ArrayOfIndex &sorted, const T &data)
get_sorted_indexes
LineShape::Output ShapeParameters(size_t k, Numeric T, Numeric P, const Vector &vmrs) const noexcept
Line shape parameters.
Vector reduced_dipole_vector(const AbsorptionLines &band, const RedPoleType type)
Reduced dipole vector.
Matrix hartmann_ecs_interface(const AbsorptionLines &band, const ArrayOfSpeciesTag &collider_species, const Vector &collider_species_vmr, const SpeciesAuxData &partition_functions, const Numeric &T, const Index &size)
Energy corrected sudden relaxation matrix using Hartmann's method.
basic_ostringstream< char, string_char_traits< char >, alloc > ostringstream
Vector rosenkranz_first_order(const AbsorptionLines &band, const Matrix &W, const Vector &d0)
Computes Y for Rosenkranz's line mixing coefficients.
Adiabatic factor computations.
Constains various line scaling functions.
OffDiagonalElementOutput CO2_IR(const Rational &Jku, const Rational &Jju, const Rational &Jkl, const Rational &Jjl, const Rational &l2ku, const Rational &l2ju, const Rational &l2kl, const Rational &l2jl, const Numeric &j_rho, const Numeric &k_rho, const BasisRate &br, const AdiabaticFactor &af, const Numeric &T, const Numeric &B0, const Numeric &main_mass, const Numeric &collider_mass)
CO2 IR off diagonal element computer.
Numeric F0(size_t k) const noexcept
Central frequency.
Namespace containing several practical unit conversions, physical and mathematical.
constexpr Numeric freq2angfreq(T x)
Numeric mol_X(const Numeric &L, const Numeric &B0, const Numeric &T, const Numeric &main_mass, const Numeric &collider_mass) const
Hartmann AF.
SecondOrderLineMixingCoeffs compute_2nd_order_lm_coeff(ConstVectorView y, ConstVectorView x, const Numeric exp, const Numeric x0)
Fit to a second order line mixing formula the input.
A constant view of a Vector.
Matrix hartmann_relaxation_matrix(const AbsorptionLines &band, const Vector &population, const Vector &d0, const ArrayOfSpeciesTag &colliders, const Vector &colliders_vmr, const SpeciesAuxData &partition_functions, const Numeric &T, const Index &size)
const QuantumIdentifier & QuantumIdentity() const noexcept
Returns identity status.
Vector rosenkranz_scaling_second_order(const AbsorptionLines &band, const Matrix &W, const Vector &d0)
Computes G for Rosenkranz's line mixing coefficients.
Numeric single_partition_function(const Numeric &T, const SpeciesAuxData::AuxType &partition_type, const ArrayOfGriddedField1 &partition_data)
Computes the partition function at one temperature.
Auxiliary data for isotopologues.
constexpr int toInt(int n=1) const
Converts the value to int by n-scaled division in Index form.
Numeric total_linestrengths(const Vector &population, const Vector &dipole)
Sum of line strengths.
String SpeciesName() const noexcept
Species Name.
Index Isotopologue() const
Isotopologue species index.
LineShape::Type LineShapeType() const noexcept
Returns lineshapetype style.
Numeric sqrt(const Rational r)
Square root.
void normalize_relaxation_matrix(Matrix &W, const Vector &population, const Vector &, const AbsorptionLines &band, const SpeciesAuxData &partition_functions, const Numeric &T)