1 #ifndef SRC_SNAP_IMPLICIT_PERIODIC_FORWARD_BACKWARD_HPP_
2 #define SRC_SNAP_IMPLICIT_PERIODIC_FORWARD_BACKWARD_HPP_
14 template <
typename T1,
typename T2>
16 std::vector<T1> &diagL,
17 std::vector<T1> &diagU,
18 std::vector<T2> &corr, Real dt,
int k,
19 int j,
int il,
int iu) {
20 T1 sum_beta_gamma, phi;
21 T2 rhs, sum_beta_zeta;
22 std::vector<T1> beta(diag.size()), gamma(diag.size());
23 std::vector<T1> ainv(diag.size());
24 std::vector<T2> zeta(diag.size());
39 if (T2::RowsAtCompileTime == 3) {
40 rhs(0) =
du_(IDN, k,
j, il);
41 for (
int n = 1; n <= NVAPOR; ++n) rhs(0) +=
du_(n, k,
j, il);
44 rhs(2) =
du_(IEN, k,
j, il) / dt;
47 rhs(0) =
du_(IDN, k,
j, il);
48 for (
int n = 1; n <= NVAPOR; ++n) rhs(0) +=
du_(n, k,
j, il);
51 rhs(2) =
du_(IVX + (IVY - IVX +
mydir_) % 3, k,
j, il) / dt;
52 rhs(3) =
du_(IVX + (IVZ - IVX +
mydir_) % 3, k,
j, il) / dt;
53 rhs(4) =
du_(IEN, k,
j, il) / dt;
67 ainv[il] = diag[il].inverse().eval();
69 gamma[il] = diagL[il];
72 beta[il] = diagU[il - 1] * ainv[il];
75 sum_beta_gamma.setZero();
76 sum_beta_zeta.setZero();
78 RecvBuffer(ainv[il - 1], gamma[il - 1], beta[il - 1], zeta[il - 1],
79 sum_beta_gamma, sum_beta_zeta, k,
j,
bblock);
82 ainv[il] = diag[il] - diagL[il] * ainv[il - 1] * diagU[il - 1];
83 ainv[il] = ainv[il].inverse().eval();
86 gamma[il] = -diagL[il] * ainv[il - 1] * gamma[il - 1];
89 beta[il] = -beta[il - 1] * diagU[il - 1] * ainv[il];
92 zeta[il] = rhs - diagL[il] * ainv[il - 1] * zeta[il - 1];
95 for (
int i = il + 1; i <= iu; ++i) {
96 if (T2::RowsAtCompileTime == 3) {
97 rhs(0) =
du_(IDN, k,
j, i);
98 for (
int n = 1; n <= NVAPOR; ++n) rhs(0) +=
du_(n, k,
j, i);
101 rhs(2) =
du_(IEN, k,
j, i) / dt;
104 rhs(0) =
du_(IDN, k,
j, i);
105 for (
int n = 1; n <= NVAPOR; ++n) rhs(0) +=
du_(n, k,
j, i);
108 rhs(2) =
du_(IVX + (IVY - IVX +
mydir_) % 3, k,
j, i) / dt;
109 rhs(3) =
du_(IVX + (IVZ - IVX +
mydir_) % 3, k,
j, i) / dt;
110 rhs(4) =
du_(IEN, k,
j, i) / dt;
119 ainv[i] = diag[i] - diagL[i] * ainv[i - 1] * diagU[i - 1];
120 ainv[i] = ainv[i].inverse().eval();
123 gamma[i] = -diagL[i] * ainv[i - 1] * gamma[i - 1];
126 beta[i] = -beta[i - 1] * diagU[i - 1] * ainv[i];
129 zeta[i] = rhs - diagL[i] * ainv[i - 1] * zeta[i - 1];
136 diagU[iu - 1] - diagL[iu - 1] * ainv[iu - 2] * gamma[iu - 2];
139 beta[iu - 1] = (diagL[iu] - beta[iu - 2] * diagU[iu - 2]) * ainv[iu - 1];
140 for (
int i = il; i < iu; ++i) {
142 sum_beta_gamma += beta[i] * gamma[i];
144 sum_beta_zeta += beta[i] * zeta[i];
149 ainv[iu] = diag[iu] - sum_beta_gamma;
150 ainv[iu] = ainv[iu].inverse().eval();
154 zeta[iu] = rhs - sum_beta_zeta;
156 for (
int i = il; i <= iu; ++i) {
158 sum_beta_gamma += beta[i] * gamma[i];
160 sum_beta_zeta += beta[i] * zeta[i];
162 SendBuffer(ainv[iu], gamma[iu], beta[iu], zeta[iu], sum_beta_gamma,
175 template <
typename T1,
typename T2>
177 std::vector<T1> &diagU,
178 std::vector<T2> &delta,
179 int kl,
int ku,
int jl,
180 int ju,
int il,
int iu) {
182 std::vector<T1> gamma(diagU.size());
183 std::vector<T2> zeta(diagU.size());
185 for (
int k = kl; k <= ku; ++k)
186 for (
int j = jl;
j <= ju; ++
j) {
190 diagU[iu - 1].setZero();
193 delta[iu] = ainv[iu] * zeta[iu];
194 delta_last = delta[iu];
197 delta[iu] = ainv[iu] * (zeta[iu] - diagU[iu] * delta[iu + 1] -
198 gamma[iu] * delta_last);
202 for (
int i = iu - 1; i >= il; --i)
206 (zeta[i] - diagU[i] * delta[i + 1] - gamma[i] * delta_last);
209 for (
int i = il; i <= iu; ++i) {
210 if (T2::RowsAtCompileTime == 3) {
211 du_(IDN, k,
j, i) = delta[i](0);
213 du_(IEN, k,
j, i) = delta[i](2);
215 du_(IDN, k,
j, i) = delta[i](0);
217 du_(IVX + (IVY - IVX +
mydir_) % 3, k,
j, i) = delta[i](2);
218 du_(IVX + (IVZ - IVX +
mydir_) % 3, k,
j, i) = delta[i](3);
219 du_(IEN, k,
j, i) = delta[i](4);
221 for (
int n = 1; n <= NVAPOR; ++n)
du_(IDN, k,
j, i) -=
du_(n, k,
j, i);
231 for (
int k = kl; k <= ku; ++k)
232 for (
int j = jl;
j <= ju; ++
j) MPI_Wait(&req_send_data6_[k][
j], &status);
236 for (
int k = kl; k <= ku; ++k)
237 for (
int j = jl;
j <= ju; ++
j) MPI_Wait(&req_send_data2_[k][
j], &status);
void RecvBuffer(T &a, int k, int j, NeighborBlock nb)
CoordinateDirection mydir_
void PeriodicBackwardSubstitution(std::vector< T1 > &a, std::vector< T1 > &c, std::vector< T2 > &delta, int kl, int ku, int jl, int ju, int il, int iu)
void LoadCoefficients(std::vector< T1 > &a, std::vector< T2 > &b, int k, int j, int il, int iu)
void PeriodicForwardSweep(std::vector< T1 > &a, std::vector< T1 > &b, std::vector< T1 > &c, std::vector< T2 > &corr, Real dt, int k, int j, int il, int iu)
void SaveCoefficients(std::vector< T1 > &a, std::vector< T2 > &b, int k, int j, int il, int iu)
void SendBuffer(T const &a, int k, int j, NeighborBlock nb)