Skip to content

Commit 368832e

Browse files
authored
Implement and explain linear in tau RT approximation as WIP (#1075)
This is still a bit of a WIP. But I have implemented linear in tau approximation in fully polarized form. I also took the time to clean up some documentation. I specifically fixed some weirdities in the description of the Jacobian calculations. (It's now more 1-to-1 with how the code works.) I also describes the new implementation, but this part specifically is not tested. The forwards is, but only for a few cases. I need this merged because I need to be able to think of abstractions around the RTE. Currently, this adds variables, which breaks workspace. I could introduce a class to wrap a lot of the RTE, like we did for the atmosphere, but it's still not beautiful to me how that would work.
2 parents 7341354 + 1b37f0e commit 368832e

13 files changed

Lines changed: 791 additions & 180 deletions

doc/arts/concept.radiative_transfer.rst

Lines changed: 272 additions & 124 deletions
Large diffs are not rendered by default.

src/core/rtepack/rtepack_mueller_matrix.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,25 @@ struct muelmat final : mat44 {
127127
a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33};
128128
}
129129

130+
constexpr muelmat operator-() const {
131+
return muelmat{-data[0],
132+
-data[1],
133+
-data[2],
134+
-data[3],
135+
-data[4],
136+
-data[5],
137+
-data[6],
138+
-data[7],
139+
-data[8],
140+
-data[9],
141+
-data[10],
142+
-data[11],
143+
-data[12],
144+
-data[13],
145+
-data[14],
146+
-data[15]};
147+
}
148+
130149
[[nodiscard]] constexpr bool is_polarized() const noexcept {
131150
return data[1] != 0.0 or data[2] != 0.0 or data[3] != 0.0 or
132151
data[4] != 0.0 or data[6] != 0.0 or data[7] != 0.0 or

src/core/rtepack/rtepack_multitype.h

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include "configtypes.h"
34
#include "rtepack_concepts.h"
45
#include "rtepack_mueller_matrix.h"
56
#include "rtepack_propagation_matrix.h"
@@ -20,33 +21,40 @@ constexpr stokvec absvec(const propmat &k) {
2021
//! Treat a list of propagation matrices as a list of Stokes (absorption) vectors
2122
stokvec_vector absvec(const propmat_vector_const_view &k);
2223

23-
//! Get the inverse of a propagation matrix as a Mueller matrix
24-
constexpr muelmat inv(const propmat &k) {
24+
constexpr muelmat adj(const propmat &k) {
2525
const auto &[a, b, c, d, u, v, w] = k.data;
2626

27-
const Numeric div =
28-
1.0 / (a * a * (a * a - b * b - c * c - d * d + u * u + v * v + w * w) -
29-
b * w * (b * w - 2 * c * v + 2 * d * u) +
30-
c * v * (-c * v + 2 * d * u) - d * d * u * u);
31-
32-
return {a * (a * a + u * u + v * v + w * w) * div,
33-
-(a * (a * b + c * u + d * v) + w * (b * w - c * v + d * u)) * div,
34-
(a * (-a * c + b * u - d * w) + v * (b * w - c * v + d * u)) * div,
35-
(a * (-a * d + b * v + c * w) - u * (b * w - c * v + d * u)) * div,
36-
(a * (-a * b + c * u + d * v) - w * (b * w - c * v + d * u)) * div,
37-
a * (a * a - c * c - d * d + w * w) * div,
38-
(d * (b * w - c * v + d * u) - a * (a * u - b * c + v * w)) * div,
39-
(a * (-a * v + b * d + u * w) - c * (b * w - c * v + d * u)) * div,
40-
(v * (b * w - c * v + d * u) - a * (a * c + b * u - d * w)) * div,
41-
(a * (a * u + b * c - v * w) - d * (b * w - c * v + d * u)) * div,
42-
a * (a * a - b * b - d * d + v * v) * div,
43-
(b * (b * w - c * v + d * u) - a * (a * w - c * d + u * v)) * div,
44-
-(a * (a * d + b * v + c * w) + u * (b * w - c * v + d * u)) * div,
45-
(a * (a * v + b * d + u * w) + c * (b * w - c * v + d * u)) * div,
46-
-(a * (-a * w - c * d + u * v) + b * (b * w - c * v + d * u)) * div,
47-
a * (a * a - b * b - c * c + u * u) * div};
27+
const Numeric a2 = a * a;
28+
const Numeric b2 = b * b;
29+
const Numeric c2 = c * c;
30+
const Numeric d2 = d * d;
31+
const Numeric u2 = u * u;
32+
const Numeric v2 = v * v;
33+
const Numeric w2 = w * w;
34+
35+
const Numeric C = b * w - c * v + d * u;
36+
37+
return muelmat{a * (a2 + u2 + v2 + w2),
38+
-a * (a * b + c * u + d * v) - w * C,
39+
a * (-a * c + b * u - d * w) + v * C,
40+
a * (-a * d + b * v + c * w) - u * C,
41+
a * (-a * b + c * u + d * v) - w * C,
42+
a * (a2 - c2 - d2 + w2),
43+
d * C - a * (a * u - b * c + v * w),
44+
a * (-a * v + b * d + u * w) - c * C,
45+
v * C - a * (a * c + b * u - d * w),
46+
a * (a * u + b * c - v * w) - d * C,
47+
a * (a2 - b2 - d2 + v2),
48+
b * C - a * (a * w - c * d + u * v),
49+
-a * (a * d + b * v + c * w) - u * C,
50+
a * (a * v + b * d + u * w) + c * C,
51+
-a * (-a * w - c * d + u * v) - b * C,
52+
a * (a2 - b2 - c2 + u2)};
4853
}
4954

55+
//! Get the inverse of a propagation matrix as a Mueller matrix
56+
constexpr muelmat inv(const propmat &k) { return adj(k) / det(k); }
57+
5058
//! muelmat matrix multiplied by a stokvec vector
5159
constexpr stokvec operator*(const muelmat &a, const stokvec &b) {
5260
const auto

src/core/rtepack/rtepack_propagation_matrix.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,22 @@ constexpr propmat operator/(propmat a, const propmat &b) {
7474
return a;
7575
}
7676

77+
constexpr Numeric det(const propmat &k) {
78+
const auto &[a, b, c, d, u, v, w] = k.data;
79+
80+
const Numeric a2 = a * a;
81+
const Numeric b2 = b * b;
82+
const Numeric c2 = c * c;
83+
const Numeric d2 = d * d;
84+
const Numeric u2 = u * u;
85+
const Numeric v2 = v * v;
86+
const Numeric w2 = w * w;
87+
88+
const Numeric C = b * w - c * v + d * u;
89+
90+
return a2 * (a2 - b2 - c2 - d2 + u2 + v2 + w2) - C * C;
91+
}
92+
7793
//! Take the average of two propmat matrixes
7894
constexpr propmat avg(propmat a, const propmat &b) {
7995
a += b;

src/core/rtepack/rtepack_rtestep.cc

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,22 +76,77 @@ void two_level_linear_emission_step_by_step_full(
7676
for (Size iv = 0; iv < nv; iv++) {
7777
stokvec &Iv = I[iv];
7878
for (Size i = N - 2; i < N; i--) {
79+
const muelmat &T = Ts[i + 1][iv];
7980
const stokvec Jv = avg(Js[i][iv], Js[i + 1][iv]);
8081

8182
Iv -= Jv;
8283

8384
for (Index iq = 0; iq < nq; iq++) {
8485
dI[i][iq, iv] +=
85-
Pi[i][iv] *
86-
(dTs[i][0, iq, iv] * Iv +
87-
0.5 * (dJs[i][iq, iv] - Ts[i + 1][iv] * dJs[i][iq, iv]));
86+
Pi[i][iv] * (dTs[i][0, iq, iv] * Iv +
87+
0.5 * (dJs[i][iq, iv] - T * dJs[i][iq, iv]));
88+
dI[i + 1][iq, iv] +=
89+
Pi[i][iv] * (dTs[i + 1][1, iq, iv] * Iv +
90+
0.5 * (dJs[i + 1][iq, iv] - T * dJs[i + 1][iq, iv]));
91+
}
92+
93+
Iv = T * Iv + Jv;
94+
}
95+
}
96+
}
97+
98+
void two_level_linear_in_J_step_by_step_full(
99+
stokvec_vector &I,
100+
std::vector<stokvec_matrix> &dI,
101+
const std::vector<muelmat_vector> &Ts,
102+
const std::vector<muelmat_vector> &Ls,
103+
const std::vector<muelmat_vector> &Pi,
104+
const std::vector<muelmat_tensor3> &dTs,
105+
const std::vector<muelmat_tensor3> &dLs,
106+
const std::vector<stokvec_vector> &Js,
107+
const std::vector<stokvec_matrix> &dJs,
108+
const stokvec_vector &I0) {
109+
const Size nv = I0.size();
110+
const Size N = Ts.size();
111+
112+
//! FIXME: Add error checks for dLs and Ls sizes
113+
114+
I = I0;
115+
dI.resize(N);
116+
117+
const Index nq = dJs[0].nrows();
118+
119+
for (auto &x : dI) {
120+
x.resize(nq, nv);
121+
x = 0.0;
122+
}
123+
124+
if (N == 0) return;
125+
126+
#pragma omp parallel for if (not arts_omp_in_parallel())
127+
for (Size iv = 0; iv < nv; iv++) {
128+
stokvec &IM = I[iv];
129+
for (Size i = N - 2; i < N; i--) {
130+
const stokvec &JN = Js[i + 1][iv];
131+
const stokvec &JM = Js[i][iv];
132+
const muelmat &T = Ts[i + 1][iv];
133+
const muelmat &L = Ls[i + 1][iv];
134+
135+
const stokvec IMmJM = IM - JM;
136+
const stokvec JMmJN = JM - JN;
137+
138+
for (Index iq = 0; iq < nq; iq++) {
139+
dI[i][iq, iv] +=
140+
Pi[i][iv] * (dJs[i][iq, iv] - L * dJs[i][iq, iv] +
141+
dTs[i][0, iq, iv] * IMmJM + dLs[i][0, iq, iv] * JMmJN);
142+
88143
dI[i + 1][iq, iv] +=
89144
Pi[i][iv] *
90-
(dTs[i + 1][1, iq, iv] * Iv +
91-
0.5 * (dJs[i + 1][iq, iv] - Ts[i + 1][iv] * dJs[i + 1][iq, iv]));
145+
(dTs[i + 1][1, iq, iv] * IMmJM + dLs[i + 1][1, iq, iv] * JMmJN +
146+
L * dJs[i + 1][iq, iv] - T * dJs[i + 1][iq, iv]);
92147
}
93148

94-
Iv = Ts[i + 1][iv] * Iv + Jv;
149+
IM = T * IMmJM + L * JMmJN + JN;
95150
}
96151
}
97152
}

src/core/rtepack/rtepack_rtestep.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ void two_level_linear_emission_step_by_step_full(
4545
const std::vector<stokvec_matrix> &dJs,
4646
const stokvec_vector &I0);
4747

48+
void two_level_linear_in_J_step_by_step_full(
49+
stokvec_vector &I,
50+
std::vector<stokvec_matrix> &dI,
51+
const std::vector<muelmat_vector> &Ts,
52+
const std::vector<muelmat_vector> &Ls,
53+
const std::vector<muelmat_vector> &Pi,
54+
const std::vector<muelmat_tensor3> &dTs,
55+
const std::vector<muelmat_tensor3> &dLs,
56+
const std::vector<stokvec_vector> &Js,
57+
const std::vector<stokvec_matrix> &dJs,
58+
const stokvec_vector &I0);
59+
4860
void two_level_linear_emission_step_by_step_full(
4961
std::vector<stokvec_vector> &Is,
5062
const std::vector<muelmat_vector> &Ts,

0 commit comments

Comments
 (0)