WarpX
Loading...
Searching...
No Matches
JacobiPC.H
Go to the documentation of this file.
1/* Copyright 2024 Debojyoti Ghosh
2 *
3 * This file is part of WarpX.
4 *
5 * License: BSD-3-Clause-LBNL
6 */
7#ifndef JACOBI_PC_H_
8#define JACOBI_PC_H_
9
10#include "Fields.H"
11#include "Utils/WarpXConst.H"
12#include "Preconditioner.H"
13
15
16#include <AMReX.H>
17#include <AMReX_ParmParse.H>
18#include <AMReX_Array.H>
19#include <AMReX_Vector.H>
20#include <AMReX_MultiFab.H>
21
45
46template <class T, class Ops>
47class JacobiPC : public Preconditioner<T,Ops>
48{
49 public:
50
51 using RT = typename T::value_type;
52
56 JacobiPC () = default;
57
61 ~JacobiPC () override = default;
62
63 // Prohibit move and copy operations
64 JacobiPC(const JacobiPC&) = delete;
65 JacobiPC& operator=(const JacobiPC&) = delete;
66 JacobiPC(JacobiPC&&) noexcept = delete;
67 JacobiPC& operator=(JacobiPC&&) noexcept = delete;
68
72 void Define (const T&, Ops* const) override;
73
77 void Update (const T& a_U) override;
78
86 void Apply (T&, const T&) override;
87
91 void printParameters() const override;
92
96 [[nodiscard]] inline bool IsDefined () const override { return m_is_defined; }
97
98 protected:
99
101
102 bool m_is_defined = false;
103
104 bool m_verbose = true;
105 int m_max_iter = 10;
106
107 RT m_atol = 1.0e-16;
108 RT m_rtol = 1.0e-4;
109
110 Ops* m_ops = nullptr;
111
117
119
123 void readParameters();
124
125 private:
126
127};
128
129template <class T, class Ops>
131{
132 using namespace amrex;
134 Print() << pc_name << " verbose: " << (m_verbose?"true":"false") << "\n";
135 Print() << pc_name << " max iter: " << m_max_iter << "\n";
136 Print() << pc_name << " absolute tolerance: " << m_atol << "\n";
137 Print() << pc_name << " relative tolerance: " << m_rtol << "\n";
138}
139
140template <class T, class Ops>
142{
144 pp.query("verbose", m_verbose);
145 pp.query("max_iter", m_max_iter);
146 pp.query("absolute_tolerance", m_atol);
147 pp.query("relative_tolerance", m_rtol);
148}
149
150template <class T, class Ops>
151void JacobiPC<T,Ops>::Define ( const T& a_U,
152 Ops* const a_ops )
153{
154 BL_PROFILE("JacobiPC::Define()");
155 using namespace amrex;
156
158 !IsDefined(),
159 "JacobiPC::Define() called on defined object" );
161 (a_ops != nullptr),
162 "JacobiPC::Define(): a_ops is nullptr" );
164 a_U.getArrayVecType()==warpx::fields::FieldType::Efield_fp,
165 "JacobiPC::Define() must be called with Efield_fp type");
166
168 m_ops = a_ops;
169 m_num_amr_levels = m_ops->numAMRLevels();
170 m_bcoefs = m_ops->GetMassMatricesCoeff();
171
172 // read preconditioner parameters
174
175 m_is_defined = true;
176}
177
178template <class T, class Ops>
179void JacobiPC<T,Ops>::Update (const T& a_U)
180{
181 BL_PROFILE("JacobiPC::Update()");
182 using namespace amrex;
183
185 IsDefined(),
186 "JacobiPC::Update() called on undefined object" );
187
188 // a_U is not needed for a linear operator
190
191 if (m_verbose) {
193 << ": theta*dt = " << this->m_dt << "\n";
194 }
195}
196
197template <class T, class Ops>
198void JacobiPC<T,Ops>::Apply (T& a_x, const T& a_b)
199{
200 // Given a right-hand-side b, solve:
201 // A x = b
202 // where A is the linear operator.
203
204 BL_PROFILE("JacobiPC::Apply()");
205 using namespace amrex;
206
208 IsDefined(),
209 "JacobiPC::Apply() called on undefined object" );
211 a_x.getArrayVecType()==warpx::fields::FieldType::Efield_fp,
212 "JacobiPC::Apply() - a_x must be Efield_fp type");
214 a_b.getArrayVecType()==warpx::fields::FieldType::Efield_fp,
215 "JacobiPC::Apply() - a_b must be Efield_fp type");
216
217 if (m_bcoefs == nullptr) {
218
219 a_x.Copy(a_b);
220
221 } else {
222
223 // Get the data vectors
224 auto& b_mfarrvec = a_b.getArrayVec();
225 auto& x_mfarrvec = a_x.getArrayVec();
227 ((b_mfarrvec.size() == m_num_amr_levels) && (x_mfarrvec.size() == m_num_amr_levels)),
228 "Error in JacobiPC::Apply() - mismatch in number of levels." );
229
230 // setting initial guess x = b/diag(A)
231 for (int n = 0; n < m_num_amr_levels; n++) {
232 for (int dim = 0; dim < 3; dim++) {
233 const auto& b_mf = *(b_mfarrvec[n][dim]);
234 const auto& a_mf = *((*m_bcoefs)[n][dim]);
235 auto& x_mf = *(x_mfarrvec[n][dim]);
236
237 for (MFIter mfi(x_mf,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
238 Box bx = mfi.tilebox();
239 auto x_arr = x_mf.array(mfi);
240 auto b_arr = b_mf.const_array(mfi);
241 auto a_arr = a_mf.const_array(mfi);
242
243 ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
244 {
245 x_arr(i,j,k) = b_arr(i,j,k) / a_arr(i,j,k);
246 });
247 }
248 }
249 }
250
251 // Jacobi iterations
252 // not yet implemented; will do after mass matrix has nondiagonal elements
253
254 }
255}
256
257#endif
#define BL_PROFILE(a)
#define AMREX_GPU_DEVICE
amrex::ParmParse pp
@ pc_jacobi
Definition Preconditioner.H:22
#define WARPX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition TextMsg.H:13
amrex::IntVect m_gv
Definition JacobiPC.H:116
bool m_is_defined
Definition JacobiPC.H:102
JacobiPC(JacobiPC &&) noexcept=delete
void Define(const T &, Ops *const) override
Define the preconditioner.
Definition JacobiPC.H:151
void Apply(T &, const T &) override
Apply (solve) the preconditioner given a RHS.
Definition JacobiPC.H:198
void printParameters() const override
Print parameters.
Definition JacobiPC.H:130
~JacobiPC() override=default
Default destructor.
RT m_rtol
Definition JacobiPC.H:108
amrex::Array< amrex::MultiFab, 3 > MFArr
Definition JacobiPC.H:100
const amrex::Vector< amrex::Array< amrex::MultiFab *, 3 > > * m_bcoefs
Definition JacobiPC.H:118
amrex::Vector< amrex::Geometry > m_geom
Definition JacobiPC.H:113
Ops * m_ops
Definition JacobiPC.H:110
JacobiPC(const JacobiPC &)=delete
typename T::value_type RT
Definition JacobiPC.H:51
JacobiPC()=default
Default constructor.
void Update(const T &a_U) override
Update the preconditioner.
Definition JacobiPC.H:179
int m_num_amr_levels
Definition JacobiPC.H:112
void readParameters()
Read parameters.
Definition JacobiPC.H:141
int m_max_iter
Definition JacobiPC.H:105
RT m_atol
Definition JacobiPC.H:107
JacobiPC & operator=(const JacobiPC &)=delete
bool m_verbose
Definition JacobiPC.H:104
amrex::Vector< amrex::DistributionMapping > m_dmap
Definition JacobiPC.H:115
amrex::Vector< amrex::BoxArray > m_grids
Definition JacobiPC.H:114
bool IsDefined() const override
Check if the nonlinear solver has been defined.
Definition JacobiPC.H:96
RT m_dt
Definition Preconditioner.H:125
Preconditioner()=default
Default constructor.
__host__ __device__ void ignore_unused(const Ts &...)
std::enable_if_t< std::is_integral_v< T > > ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
std::string getEnumNameString(T const &v)
BoxND< 3 > Box
IntVectND< 3 > IntVect
bool TilingIfNotGPU() noexcept
std::array< T, N > Array
@ Efield_fp
Definition Fields.H:94