Canoe
Comprehensive Atmosphere N' Ocean Engine
chemistry_solver.hpp
Go to the documentation of this file.
1 #ifndef SRC_MICROPHYSICS_CHEMISTRY_SOLVER_HPP
2 #define SRC_MICROPHYSICS_CHEMISTRY_SOLVER_HPP
3 
4 // Athena++ headers
5 #include <athena/athena.hpp>
6 
7 // Eigen header files
8 #include <Eigen/Core>
9 #include <Eigen/Dense>
10 #include <Eigen/LU>
11 
12 template <int N>
14  public:
15  // needed for Eigen small matrix
16  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
17 
18  // data
19  enum { Size = N };
20 
21  // functions
22  ChemistrySolver() { I_.setIdentity(); }
23 
24  template <typename T1, typename T2, typename T3>
25  T1 solveBDF1(T2 const& Rate, T3 const& Jac, Real dt) {
26  A_ = I_ / dt - Jac;
27  if (N <= 4) {
28  return A_.inverse() * Rate;
29  } else {
30  return A_.partialPivLu().solve(Rate);
31  }
32  }
33 
34  template <typename T1, typename T2, typename T3>
35  T1 solveTRBDF2(T2 const& Rate, T3 const& Jac, Real dt) {
36  A_ = I_ - gamma_ / 2. * dt * Jac;
37  B_ = dt * (1. - gamma_ / 2.) * Rate + dt * gamma_ / 2. * A_ * Rate;
38  A_ = A_ * A_;
39  if (N <= 4) {
40  return A_.inverse() * B_;
41  } else {
42  return A_.partialPivLu().solve(B_);
43  }
44  }
45 
46  template <typename T1, typename T2, typename T3>
47  T1 solveTRBDF2Blend(T2 const& Rate, T3 const& Jac, Real dt, Real const c[],
48  int const indx[]) {
49  // BDF1 solver
50  auto sol = solveBDF1<T1>(Rate, Jac, dt);
51  for (int n = 0; n < Size; ++n) S1_(n) = c[indx[n]] + sol(n);
52 
53  // TR-BDF2 solver
54  sol = solveTRBDF2<T1>(Rate, Jac, dt);
55  for (int n = 0; n < Size; ++n) S2_(n) = c[indx[n]] + sol(n);
56 
57  // Blend solutions
58  Real alpha = 1.;
59  for (int n = 0; n < Size; ++n) {
60  if (S2_(n) < S1_(n)) {
61  alpha = std::min(alpha, S1_(n) / (S1_(n) - S2_(n)));
62  }
63  }
64  alpha = std::max(alpha, 0.);
65 
66  for (int n = 0; n < Size; ++n)
67  sol(n) = (1. - alpha) * S1_(n) + alpha * S2_(n) - c[indx[n]];
68  return sol;
69  }
70 
71  private:
72  int gamma_ = 2. - sqrt(2.);
73 
74  // scratch array
75  Eigen::Matrix<Real, N, N> A_, I_;
76  Eigen::Matrix<Real, N, 1> B_, S1_, S2_;
77 };
78 
79 #endif
Eigen::Matrix< Real, N, 1 > B_
Eigen::Matrix< Real, N, 1 > S2_
T1 solveBDF1(T2 const &Rate, T3 const &Jac, Real dt)
T1 solveTRBDF2(T2 const &Rate, T3 const &Jac, Real dt)
Eigen::Matrix< Real, N, N > I_
T1 solveTRBDF2Blend(T2 const &Rate, T3 const &Jac, Real dt, Real const c[], int const indx[])
Eigen::Matrix< Real, N, 1 > S1_
Eigen::Matrix< Real, N, N > A_
double min(double x1, double x2, double x3)
Definition: core.h:16
double max(double x1, double x2, double x3)
Definition: core.h:19