ARTS  2.3.1285(git:92a29ea9-dirty)
zeemandata.h
Go to the documentation of this file.
1 /* Copyright (C) 2018 Richard Larsson
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA. */
17 
29 #ifndef zeemandata_h
30 #define zeemandata_h
31 
32 #include <limits>
33 #include "constants.h"
34 #include "file.h"
35 #include "mystring.h"
36 #include "quantum.h"
37 #include "wigner_functions.h"
38 
40 namespace Zeeman {
41 
44 
51 constexpr Index dM(Polarization type) noexcept {
52  switch (type) {
54  return -1;
55  case Polarization::Pi:
56  return 0;
58  return 1;
59  }
61 }
62 
77 constexpr Rational start(Rational Ju, Rational Jl, Polarization type) noexcept {
78  switch (type) {
80  if (Ju < Jl)
81  return -Ju;
82  else if (Ju == Jl)
83  return -Ju + 1;
84  else
85  return -Ju + 2;
86  case Polarization::Pi:
87  return -std::min(Ju, Jl);
89  return -Ju;
90  }
92 }
93 
108 constexpr Rational end(Rational Ju, Rational Jl, Polarization type) noexcept {
109  switch (type) {
111  return Ju + 1;
112  case Polarization::Pi:
113  return std::min(Ju, Jl);
115  if (Ju < Jl)
116  return Ju + 1;
117  else if (Ju == Jl)
118  return Ju;
119  else
120  return Jl;
121  }
123 }
124 
135 constexpr Index nelem(Rational Ju, Rational Jl, Polarization type) noexcept {
136  return (end(Ju, Jl, type) - start(Ju, Jl, type)).toIndex() + 1;
137 }
138 
152 constexpr Rational Mu(Rational Ju,
153  Rational Jl,
154  Polarization type,
155  Index n) noexcept {
156  return start(Ju, Jl, type) + n;
157 }
158 
159 
173 constexpr Rational Ml(Rational Ju,
174  Rational Jl,
175  Polarization type,
176  Index n) noexcept {
177  return Mu(Ju, Jl, type, n) + dM(type);
178 }
179 
191 constexpr Numeric PolarizationFactor(Polarization type) noexcept {
192  switch (type) {
194  return .75;
195  case Polarization::Pi:
196  return 1.5;
198  return .75;
199  }
201 }
202 
212 constexpr bool GoodHundData(const QuantumNumbers& qns) noexcept {
213  if (qns[QuantumNumberType::Hund].isUndefined()) return false;
214  switch (Hund(qns[QuantumNumberType::Hund].toIndex())) {
215  case Hund::CaseA:
216  if (qns[QuantumNumberType::Omega].isUndefined() or
217  qns[QuantumNumberType::J].isUndefined() or
218  qns[QuantumNumberType::Lambda].isUndefined() or
219  qns[QuantumNumberType::S].isUndefined())
220  return false;
221  break;
222  case Hund::CaseB:
223  if (qns[QuantumNumberType::N].isUndefined() or
224  qns[QuantumNumberType::J].isUndefined() or
225  qns[QuantumNumberType::Lambda].isUndefined() or
226  qns[QuantumNumberType::S].isUndefined())
227  return false;
228  break;
229  default:
230  return false;
231  }
232  return true;
233 }
234 
250  Rational J,
251  Rational Lambda,
252  Rational S,
253  Numeric GS,
254  Numeric GL) noexcept {
255  auto JJ = J * (J + 1);
256  auto NN = N * (N + 1);
257  auto SS = S * (S + 1);
258  auto LL = Lambda * Lambda;
259 
260  if (JJ == 0)
261  return 0.0;
262  else if (NN not_eq 0) {
263  auto T1 = ((JJ + SS - NN) / JJ / 2).toNumeric();
264  auto T2 = ((JJ - SS + NN) * LL / NN / JJ / 2).toNumeric();
265  return GS * T1 + GL * T2;
266  } else {
267  auto T1 = ((JJ + SS - NN) / JJ / 2).toNumeric();
268  return GS * T1;
269  }
270 }
271 
286 constexpr Numeric SimpleGCaseA(Rational Omega,
287  Rational J,
288  Rational Lambda,
289  Rational Sigma,
290  Numeric GS,
291  Numeric GL) noexcept {
292  auto JJ = J * (J + 1);
293 
294  if (JJ == 0)
295  return 0.0;
296  else {
297  auto DIV = Omega / JJ;
298  auto T1 = (Sigma * DIV).toNumeric();
299  auto T2 = (Lambda * DIV).toNumeric();
300  return GS * T1 + GL * T2;
301  }
302 }
303 
315 constexpr Numeric SimpleG(const QuantumNumbers& qns,
316  const Numeric& GS,
317  const Numeric& GL) noexcept{
318  if (not GoodHundData(qns))
319  return NAN;
320 
321  switch (Hund(qns[QuantumNumberType::Hund].toIndex())) {
322  case Hund::CaseA:
327  GS,
328  GL);
329  case Hund::CaseB:
331  qns[QuantumNumberType::J],
332  qns[QuantumNumberType::Lambda],
333  qns[QuantumNumberType::S],
334  GS,
335  GL);
336  }
337 
338  return NAN;
339 }
340 
348  Numeric gu, gl;
349 };
350 
358 class Model {
359  private:
361 
362  public:
364  constexpr Model(SplittingData gs = {NAN, NAN}) noexcept : mdata(gs) {}
365 
376  explicit Model(const QuantumIdentifier& qid) noexcept;
377 
379  /* constexpr */ bool empty() const noexcept {
380  return std::isnan(mdata.gu) and std::isnan(mdata.gl);
381  }
382 
384  Numeric& gu() noexcept { return mdata.gu; }
385 
387  Numeric& gl() noexcept { return mdata.gl; }
388 
390  void gu(Numeric x) noexcept { mdata.gu = x; }
391 
393  void gl(Numeric x) noexcept { mdata.gl = x; }
394 
396  constexpr Numeric gu() const noexcept { return mdata.gu; }
397 
399  constexpr Numeric gl() const noexcept { return mdata.gl; }
400 
415  using Constant::pow2;
416 
417  auto ml = Ml(Ju, Jl, type, n);
418  auto mu = Mu(Ju, Jl, type, n);
419  auto dm = Rational(dM(type));
420  return PolarizationFactor(type) * pow2(wigner3j(Jl, Rational(1), Ju, ml, -dm, -mu));
421  }
422 
436  constexpr Numeric Splitting(Rational Ju, Rational Jl, Polarization type, Index n) const
437  noexcept {
438  using Constant::bohr_magneton;
439  using Constant::h;
440  constexpr Numeric C = bohr_magneton / h;
441 
442  return C * (Ml(Ju, Jl, type, n).toNumeric() * gl() -
443  Mu(Ju, Jl, type, n).toNumeric() * gu());
444  }
445 
447  friend inline std::ostream& operator<<(std::ostream& os, const Model& m);
448 
450  friend inline std::istream& operator>>(std::istream& is, Model& m);
451 
453  friend inline std::ostream& operator<<(bofstream& bof, const Model& m);
454 
456  friend inline std::istream& operator>>(bifstream& bif, Model& m);
457 }; // Model;
458 
468 Model GetSimpleModel(const QuantumIdentifier& qid) noexcept;
469 
481 Model GetAdvancedModel(const QuantumIdentifier& qid) noexcept;
482 
483 inline std::ostream& operator<<(std::ostream& os, const Model& m) {
484  os << m.mdata.gu << ' ' << m.mdata.gl;
485  return os;
486 }
487 
488 inline std::istream& operator>>(std::istream& is, Model& m) {
489  is >> double_imanip() >> m.mdata.gu >> m.mdata.gl;
490  return is;
491 }
492 
493 inline std::ostream& operator<<(bofstream& bof, const Model& m) {
494  bof << m.mdata.gu << m.mdata.gl;
495  return bof;
496 }
497 
498 inline std::istream& operator>>(bifstream& bif, Model& m) {
499  bif >> m.mdata.gu >> m.mdata.gl;
500  return bif;
501 }
502 
510  private:
511  Eigen::RowVector4d att; // attenuation vector
512  Eigen::RowVector3d dis; // dispersion vector
513 
514  public:
517  Numeric b = 0,
518  Numeric c = 0,
519  Numeric d = 0,
520  Numeric u = 0,
521  Numeric v = 0,
522  Numeric w = 0) noexcept
523  : att(a, b, c, d), dis(u, v, w){};
524 
526  const Eigen::RowVector4d& attenuation() const noexcept { return att; }
527 
529  const Eigen::RowVector3d& dispersion() const noexcept { return dis; }
530 
532  Eigen::RowVector4d& attenuation() noexcept { return att; }
533 
535  Eigen::RowVector3d& dispersion() noexcept { return dis; }
536 
541  Eigen::Matrix4d matrix() const noexcept {
542  return (Eigen::Matrix4d() << att[0],
543  att[1],
544  att[2],
545  att[3],
546  att[1],
547  att[0],
548  dis[0],
549  dis[1],
550  att[2],
551  -dis[0],
552  att[0],
553  dis[2],
554  att[3],
555  -dis[1],
556  -dis[2],
557  att[0])
558  .finished();
559  }
560 };
561 
568  PolarizationVector sm, pi, sp;
569 };
570 
579  Numeric eta) noexcept {
580  const Numeric ST = std::sin(theta), CT = std::cos(theta), ST2 = ST * ST,
581  CT2 = CT * CT, ST2C2E = ST2 * std::cos(2 * eta),
582  ST2S2E = ST2 * std::sin(2 * eta);
583 
585  pv.sm = PolarizationVector(
586  1 + CT2, ST2C2E, ST2S2E, 2 * CT, 4 * CT, 2 * ST2S2E, -2 * ST2C2E);
587  pv.pi =
588  PolarizationVector(ST2, -ST2C2E, -ST2S2E, 0, 0, -2 * ST2S2E, 2 * ST2C2E);
589  pv.sp = PolarizationVector(
590  1 + CT2, ST2C2E, ST2S2E, -2 * CT, -4 * CT, 2 * ST2S2E, -2 * ST2C2E);
591  return pv;
592 }
593 
602  Numeric theta, const Numeric eta) noexcept {
603  const Numeric ST = std::sin(theta), CT = std::cos(theta),
604  C2E = std::cos(2 * eta), S2E = std::sin(2 * eta), dST = CT,
605  dST2 = 2 * ST * dST, dCT = -ST, dST2C2E = dST2 * C2E,
606  dST2S2E = dST2 * S2E, dCT2 = 2 * CT * dCT;
607 
609  pv.sm = PolarizationVector(
610  dCT2, dST2C2E, dST2S2E, 2 * dCT, 4 * dCT, 2 * dST2S2E, -2 * dST2C2E);
611  pv.pi = PolarizationVector(
612  dST2, -dST2C2E, -dST2S2E, 0, 0, -2 * dST2S2E, 2 * dST2C2E);
613  pv.sp = PolarizationVector(
614  dCT2, dST2C2E, dST2S2E, -2 * dCT, -4 * dCT, 2 * dST2S2E, -2 * dST2C2E);
615  return pv;
616 }
617 
626  Numeric eta) noexcept {
627  const Numeric ST = std::sin(theta), ST2 = ST * ST, C2E = std::cos(2 * eta),
628  S2E = std::sin(2 * eta), dST2C2E = -2 * ST2 * S2E,
629  dST2S2E = 2 * ST2 * C2E;
630 
632  pv.sm =
633  PolarizationVector(0, dST2C2E, dST2S2E, 0, 0, 2 * dST2S2E, -2 * dST2C2E);
634  pv.pi = PolarizationVector(
635  0, -dST2C2E, -dST2S2E, 0, 0, -2 * dST2S2E, 2 * dST2C2E);
636  pv.sp =
637  PolarizationVector(0, dST2C2E, dST2S2E, 0, 0, 2 * dST2S2E, -2 * dST2C2E);
638  return pv;
639 }
640 
647  const AllPolarizationVectors& data, Polarization type) noexcept {
648  switch (type) {
650  return data.sm;
651  case Polarization::Pi:
652  return data.pi;
654  return data.sp;
655  }
656  std::terminate();
657 }
658 
667 struct Derived {
668  Numeric H, theta, eta, dH_du, dH_dv, dH_dw, dtheta_du, dtheta_dv, dtheta_dw,
669  deta_du, deta_dv, deta_dw;
670 };
671 
702 Derived FromGrids(Numeric u, Numeric v, Numeric w, Numeric z, Numeric a) noexcept;
703 
713  Numeric theta,
714  Numeric eta) noexcept {
715  return {H, theta, eta, 0, 0, 0, 0, 0, 0, 0, 0, 0};
716 }
717 }; // namespace Zeeman
718 
719 // Typedef to make it easier to use
720 typedef Zeeman::Model ZeemanModel;
721 
722 #endif /* zeemandata_h */
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
Numeric Strength(Rational Ju, Rational Jl, Polarization type, Index n) const
Gives the strength of one subline of a given polarization.
Definition: zeemandata.h:414
#define N
Definition: rng.cc:164
constexpr Numeric Splitting(Rational Ju, Rational Jl, Polarization type, Index n) const noexcept
Gives the splitting of one subline of a given polarization.
Definition: zeemandata.h:436
Main Zeeman Model.
Definition: zeemandata.h:358
#define C(a, b)
Definition: Faddeeva.cc:255
constexpr bool GoodHundData(const QuantumNumbers &qns) noexcept
Checks if the quantum numbers are good for this transition.
Definition: zeemandata.h:212
const Eigen::RowVector4d & attenuation() const noexcept
Returns the attenuation vector.
Definition: zeemandata.h:526
std::ostream & operator<<(std::ostream &os, const Model &m)
Definition: zeemandata.h:483
Eigen::RowVector3d dis
Definition: zeemandata.h:512
Constants of physical expressions as constexpr.
constexpr Model(SplittingData gs={NAN, NAN}) noexcept
Default copy/init of Model from its only private variable.
Definition: zeemandata.h:364
Numeric & gu() noexcept
Returns the upper state g.
Definition: zeemandata.h:384
PolarizationVector for each Polarization.
Definition: zeemandata.h:567
const PolarizationVector & SelectPolarization(const AllPolarizationVectors &data, Polarization type) noexcept
Selects the polarization vector depending on polarization type.
Definition: zeemandata.h:646
Model GetAdvancedModel(const QuantumIdentifier &qid) noexcept
Returns an advanced Zeeman model.
Definition: zeemandata.cc:105
cmplx FADDEEVA() w(cmplx z, double relerr)
Definition: Faddeeva.cc:680
constexpr Rational Mu(Rational Ju, Rational Jl, Polarization type, Index n) noexcept
Gives the upper state M value at an index.
Definition: zeemandata.h:152
void gl(Numeric x) noexcept
Sets the lower state g.
Definition: zeemandata.h:393
constexpr Numeric gl() const noexcept
Returns the lower state g.
Definition: zeemandata.h:399
This file contains basic functions to handle ASCII files.
#define min(a, b)
constexpr Numeric SimpleGCaseA(Rational Omega, Rational J, Rational Lambda, Rational Sigma, Numeric GS, Numeric GL) noexcept
Computes the Zeeman splitting coefficient.
Definition: zeemandata.h:286
G0 G2 FVC Y DV Numeric Numeric Numeric Zeeman LowerQuantumNumbers void * data
AllPolarizationVectors AllPolarization_deta(Numeric theta, Numeric eta) noexcept
The derivative of AllPolarization wrt eta.
Definition: zeemandata.h:625
constexpr T pow2(T x)
power of two
Definition: constants.h:64
Wigner symbol interactions.
Eigen::RowVector4d & attenuation() noexcept
Returns the attenuation vector.
Definition: zeemandata.h:532
Model GetSimpleModel(const QuantumIdentifier &qid) noexcept
Returns a simple Zeeman model.
Definition: zeemandata.cc:33
const Eigen::RowVector3d & dispersion() const noexcept
Returns the dispersion vector.
Definition: zeemandata.h:529
Implements Zeeman modeling.
Definition: zeemandata.h:40
Eigen::Matrix4d matrix() const noexcept
Returns the true propagation matrix.
Definition: zeemandata.h:541
Hund
Enum for Hund cases.
Definition: quantum.h:219
constexpr Numeric PolarizationFactor(Polarization type) noexcept
The renormalization factor of a polarization type.
Definition: zeemandata.h:191
SplittingData mdata
Definition: zeemandata.h:360
Binary output file stream class.
Definition: bifstream.h:42
Implements rational numbers to work with other ARTS types.
Definition: rational.h:54
Eigen::RowVector3d & dispersion() noexcept
Returns the dispersion vector.
Definition: zeemandata.h:535
Class to identify and match lines by their quantum numbers.
Definition: quantum.h:390
Contains derived values useful for Zeeman calculations.
Definition: zeemandata.h:667
std::istream & operator>>(std::istream &is, Model &m)
Definition: zeemandata.h:488
PolarizationVector(Numeric a=1, Numeric b=0, Numeric c=0, Numeric d=0, Numeric u=0, Numeric v=0, Numeric w=0) noexcept
Default init of class.
Definition: zeemandata.h:516
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
constexpr Derived FromPreDerived(Numeric H, Numeric theta, Numeric eta) noexcept
Sets Derived from predefined Derived parameters.
Definition: zeemandata.h:712
constexpr Numeric toNumeric() const
Converts this to a Numeric.
Definition: rational.h:146
Container class for Quantum Numbers.
Definition: quantum.h:222
constexpr Index nelem(Rational Ju, Rational Jl, Polarization type) noexcept
Gives the number of elements of the polarization type of this transition.
Definition: zeemandata.h:135
Polarization
Zeeman polarization selection.
Definition: zeemandata.h:43
Zeeman::Model ZeemanModel
Definition: zeemandata.h:717
void gu(Numeric x) noexcept
Sets the upper state g.
Definition: zeemandata.h:390
Eigen::RowVector4d att
Definition: zeemandata.h:511
#define max(a, b)
constexpr Numeric gu() const noexcept
Returns the upper state g.
Definition: zeemandata.h:396
Numeric wigner3j(const Rational j1, const Rational j2, const Rational j3, const Rational m1, const Rational m2, const Rational m3)
Wigner 3J symbol.
Main storage for Zeeman splitting coefficients.
Definition: zeemandata.h:347
Binary output file stream class.
Definition: bofstream.h:42
constexpr Rational start(Rational Ju, Rational Jl, Polarization type) noexcept
Gives the lowest M for a polarization type of this transition.
Definition: zeemandata.h:77
Derived FromGrids(Numeric u, Numeric v, Numeric w, Numeric z, Numeric a) noexcept
Computes the derived plane from ARTS grids.
Definition: zeemandata.cc:236
constexpr Numeric SimpleGCaseB(Rational N, Rational J, Rational Lambda, Rational S, Numeric GS, Numeric GL) noexcept
Computes the Zeeman splitting coefficient.
Definition: zeemandata.h:249
Polarization vector for Zeeman Propagation Matrix.
Definition: zeemandata.h:509
bool empty() const noexcept
Returns true if the Model represents no Zeeman effect.
Definition: zeemandata.h:379
constexpr Numeric SimpleG(const QuantumNumbers &qns, const Numeric &GS, const Numeric &GL) noexcept
Computes the Zeeman splitting coefficient.
Definition: zeemandata.h:315
constexpr Rational Ml(Rational Ju, Rational Jl, Polarization type, Index n) noexcept
Gives the lower state M value at an index.
Definition: zeemandata.h:173
AllPolarizationVectors AllPolarization_dtheta(Numeric theta, const Numeric eta) noexcept
The derivative of AllPolarization wrt theta.
Definition: zeemandata.h:601
constexpr Rational end(Rational Ju, Rational Jl, Polarization type) noexcept
Gives the largest M for a polarization type of this transition.
Definition: zeemandata.h:108
Numeric & gl() noexcept
Returns the lower state g.
Definition: zeemandata.h:387
Input manipulator class for doubles to enable nan and inf parsing.
Definition: file.h:117
AllPolarizationVectors AllPolarization(Numeric theta, Numeric eta) noexcept
Computes the polarization of each polarization type.
Definition: zeemandata.h:578
This file contains the definition of String, the ARTS string class.
constexpr Index dM(Polarization type) noexcept
Gives the change of M given a polarization type.
Definition: zeemandata.h:51