WarpX
JacobianFunctionMF.H
Go to the documentation of this file.
1 /* Copyright 2024 Justin Angus
2  *
3  * This file is part of WarpX.
4  *
5  * License: BSD-3-Clause-LBNL
6  */
7 #ifndef JacobianFunctionMF_H_
8 #define JacobianFunctionMF_H_
9 
17 template <class T, class Ops>
19 {
20  public:
21 
22  using RT = typename T::value_type;
23 
24  JacobianFunctionMF<T,Ops>() = default;
25  ~JacobianFunctionMF<T,Ops>() = default;
26 
27  // Default move and copy operations
31  JacobianFunctionMF& operator=(JacobianFunctionMF&&) noexcept = default;
32 
33  void apply ( T& a_dF, const T& a_dU );
34 
35  inline
36  void precond ( T& a_U, const T& a_X )
37  {
38  if (m_usePreCond) { a_U.zero(); }
39  else { a_U.Copy(a_X); }
40  }
41 
42  inline
43  void updatePreCondMat ( const T& a_X )
44  {
46  }
47 
48  inline
49  void create ( T& a_Z, const T& a_U )
50  {
51  a_Z.define(a_U);
52  }
53 
54  T makeVecLHS () const;
55  T makeVecRHS () const;
56 
57  inline
58  void assign( T& a_Z, const T& a_U ) {
59  a_Z.Copy(a_U);
60  }
61 
62  inline
63  void increment( T& a_Z, const T& a_U, RT a_scale )
64  {
65  a_Z.increment(a_U,a_scale);
66  }
67 
68  inline
69  void scale ( T& a_U, RT a_scale )
70  {
71  a_U.scale(a_scale);
72  }
73 
74  inline
75  void linComb ( T& a_U, RT a, const T& X, RT b, const T& Y )
76  {
77  a_U.linComb( a, X, b, Y );
78  }
79 
80  inline
81  void setToZero ( T& a_U )
82  {
83  a_U.zero();
84  }
85 
86  inline
87  void setVal ( T& a_U, RT a_val )
88  {
89  a_U.setVal(a_val);
90  }
91 
92  inline
93  RT dotProduct( const T& a_X, const T& a_Y )
94  {
95  return( a_X.dotProduct(a_Y) );
96  }
97 
98  inline
99  RT norm2( const T& a_U )
100  {
101  return ( a_U.norm2() );
102  }
103 
104  [[nodiscard]] inline
105  bool isDefined() const { return m_is_defined; }
106 
107  inline
108  void setBaseSolution ( const T& a_U )
109  {
110  m_Y0.Copy(a_U);
111  m_normY0 = norm2(m_Y0);
112  }
113 
114  inline
115  void setBaseRHS ( const T& a_R )
116  {
117  m_R0.Copy(a_R);
118  }
119 
120  inline
121  void setJFNKEps ( RT a_eps )
122  {
123  m_epsJFNK = a_eps;
124  }
125 
126  inline
127  void setIsLinear ( bool a_isLinear )
128  {
129  m_is_linear = a_isLinear;
130  }
131 
132  inline
133  void curTime ( RT a_time )
134  {
135  m_cur_time = a_time;
136  }
137 
138  inline
139  void curTimeStep ( RT a_dt )
140  {
141  m_dt = a_dt;
142  }
143 
144  void define( const T&, Ops* );
145 
146  private:
147 
148  bool m_is_defined = false;
149  bool m_is_linear = false;
150  bool m_usePreCond = false;
151  RT m_epsJFNK = RT(1.0e-6);
154  std::string m_pc_type;
155 
156  T m_Z, m_Y0, m_R0, m_R;
157  Ops* m_ops;
158 
159 };
160 
161 template <class T, class Ops>
163  Ops* a_ops )
164 {
165  m_Z.Define(a_U);
166  m_Y0.Define(a_U);
167  m_R0.Define(a_U);
168  m_R.Define(a_U);
169 
170  m_ops = a_ops;
171 
172  m_is_defined = true;
173 }
174 
175 template <class T, class Ops>
177 {
178  T Vec;
179  Vec.Define(m_R);
180  return Vec;
181 }
182 
183 template <class T, class Ops>
185 {
186  T Vec;
187  Vec.Define(m_R);
188  return Vec;
189 }
190 
191 template <class T, class Ops>
192 void JacobianFunctionMF<T,Ops>::apply (T& a_dF, const T& a_dU)
193 {
194  BL_PROFILE("JacobianFunctionMF::apply()");
195  using namespace amrex::literals;
196  RT const normY = norm2(a_dU); // always 1 when called from GMRES
197 
199  isDefined(),
200  "JacobianFunction::apply() called on undefined JacobianFunction");
201 
202  if (normY < 1.0e-15) { a_dF.zero(); }
203  else {
204 
205  RT eps;
206  if (m_is_linear) {
207  eps = 1.0_rt;
208  } else {
209  /* eps = error_rel * sqrt(1 + ||Y0||) / ||dU||
210  * M. Pernice and H. F. Walker, "NITSOL: A Newton Iterative Solver for
211  * Nonlinear Systems", SIAM J. Sci. Stat. Comput., 1998, vol 19,
212  * pp. 302--318. */
213  if (m_normY0==0.0) { eps = m_epsJFNK * norm2(m_R0) / normY; }
214  else {
215  // m_epsJFNK * sqrt(1.0 + m_normY0) / normY
216  // above commonly used form not recommend for poorly scaled Y0
217  eps = m_epsJFNK * m_normY0 / normY;
218  }
219  }
220  const RT eps_inv = 1.0_rt/eps;
221 
222  m_Z.linComb( 1.0, m_Y0, eps, a_dU ); // Z = Y0 + eps*dU
223  m_ops->ComputeRHS(m_R, m_Z, m_cur_time, m_dt, -1, true );
224 
225  // F(Y) = Y - b - R(Y) ==> dF = dF/dY*dU = [1 - dR/dY]*dU
226  // = dU - (R(Z)-R(Y0))/eps
227  a_dF.linComb( 1.0, a_dU, eps_inv, m_R0 );
228  a_dF.increment(m_R,-eps_inv);
229 
230  }
231 
232 }
233 
234 #endif
#define BL_PROFILE(a)
#define WARPX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition: TextMsg.H:13
This is a linear function class for computing the action of a Jacobian on a vector using a matrix-fre...
Definition: JacobianFunctionMF.H:19
RT m_cur_time
Definition: JacobianFunctionMF.H:153
bool m_is_defined
Definition: JacobianFunctionMF.H:148
void create(T &a_Z, const T &a_U)
Definition: JacobianFunctionMF.H:49
void scale(T &a_U, RT a_scale)
Definition: JacobianFunctionMF.H:69
void setToZero(T &a_U)
Definition: JacobianFunctionMF.H:81
T m_R0
Definition: JacobianFunctionMF.H:156
void setBaseRHS(const T &a_R)
Definition: JacobianFunctionMF.H:115
RT norm2(const T &a_U)
Definition: JacobianFunctionMF.H:99
void setBaseSolution(const T &a_U)
Definition: JacobianFunctionMF.H:108
bool isDefined() const
Definition: JacobianFunctionMF.H:105
void increment(T &a_Z, const T &a_U, RT a_scale)
Definition: JacobianFunctionMF.H:63
void setIsLinear(bool a_isLinear)
Definition: JacobianFunctionMF.H:127
T m_Z
Definition: JacobianFunctionMF.H:156
void setVal(T &a_U, RT a_val)
Definition: JacobianFunctionMF.H:87
void apply(T &a_dF, const T &a_dU)
Definition: JacobianFunctionMF.H:192
JacobianFunctionMF(const JacobianFunctionMF &)=default
RT m_normY0
Definition: JacobianFunctionMF.H:152
void define(const T &, Ops *)
Definition: JacobianFunctionMF.H:162
void curTimeStep(RT a_dt)
Definition: JacobianFunctionMF.H:139
RT m_dt
Definition: JacobianFunctionMF.H:153
void curTime(RT a_time)
Definition: JacobianFunctionMF.H:133
std::string m_pc_type
Definition: JacobianFunctionMF.H:154
void assign(T &a_Z, const T &a_U)
Definition: JacobianFunctionMF.H:58
bool m_is_linear
Definition: JacobianFunctionMF.H:149
T m_Y0
Definition: JacobianFunctionMF.H:156
void setJFNKEps(RT a_eps)
Definition: JacobianFunctionMF.H:121
void updatePreCondMat(const T &a_X)
Definition: JacobianFunctionMF.H:43
RT m_epsJFNK
Definition: JacobianFunctionMF.H:151
T makeVecRHS() const
Definition: JacobianFunctionMF.H:176
typename T::value_type RT
Definition: JacobianFunctionMF.H:22
Ops * m_ops
Definition: JacobianFunctionMF.H:157
JacobianFunctionMF & operator=(const JacobianFunctionMF &)=default
RT dotProduct(const T &a_X, const T &a_Y)
Definition: JacobianFunctionMF.H:93
bool m_usePreCond
Definition: JacobianFunctionMF.H:150
void precond(T &a_U, const T &a_X)
Definition: JacobianFunctionMF.H:36
JacobianFunctionMF(JacobianFunctionMF &&) noexcept=default
T m_R
Definition: JacobianFunctionMF.H:156
T makeVecLHS() const
Definition: JacobianFunctionMF.H:184
void linComb(T &a_U, RT a, const T &X, RT b, const T &Y)
Definition: JacobianFunctionMF.H:75
constexpr double eps
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ignore_unused(const Ts &...)
default
Definition: run_alltests.py:113