WarpX
WarpXSolverVec.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 WarpXSolverVec_H_
8 #define WarpXSolverVec_H_
9 
10 #include "Utils/TextMsg.H"
11 
14 
15 #include <AMReX.H>
16 #include <AMReX_Array.H>
17 #include <AMReX_BLassert.H>
18 #include <AMReX_Geometry.H>
19 #include <AMReX_IntVect.H>
20 #include <AMReX_LayoutData.H>
21 #include <AMReX_MultiFab.H>
22 #include <AMReX_iMultiFab.H>
23 #include <AMReX_ParmParse.H>
24 #include <AMReX_Print.H>
25 #include <AMReX_REAL.H>
26 #include <AMReX_Utility.H>
27 #include <AMReX_Vector.H>
28 
29 #include <algorithm>
30 #include <array>
31 #include <memory>
32 #include <ostream>
33 #include <vector>
34 
48 {
49 public:
50 
51  WarpXSolverVec() = default;
52 
53  WarpXSolverVec(const WarpXSolverVec&) = delete;
54 
55  ~WarpXSolverVec() = default;
56 
57  using value_type = amrex::Real;
58  using RT = value_type;
59 
60  [[nodiscard]] inline bool IsDefined () const { return m_is_defined; }
61 
62  inline
63  void Define (const WarpXSolverVec& a_vec)
64  {
66  a_vec.IsDefined(),
67  "WarpXSolverVec::Define(a_vec) called with undefined a_vec");
68  Define( a_vec.getVec() );
69  }
70 
71  inline
72  void Define ( const amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3 > >& a_solver_vec )
73  {
75  !IsDefined(),
76  "WarpXSolverVec::Define() called on undefined WarpXSolverVec");
78  const int lev = 0;
79  for (int n=0; n<3; n++) {
80  const amrex::MultiFab& mf_model = *a_solver_vec[lev][n];
81  m_field_vec[lev][n] = std::make_unique<amrex::MultiFab>( mf_model.boxArray(), mf_model.DistributionMap(),
82  mf_model.nComp(), amrex::IntVect::TheZeroVector() );
83  }
84  m_is_defined = true;
85  }
86 
87  void SetDotMask( const amrex::Vector<amrex::Geometry>& a_Geom );
88  [[nodiscard]] RT dotProduct( const WarpXSolverVec& a_X ) const;
89 
90  inline
91  void Copy ( const amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3 > >& a_solver_vec )
92  {
94  IsDefined(),
95  "WarpXSolverVec::Copy() called on undefined WarpXSolverVec");
96  for (int lev = 0; lev < m_num_amr_levels; ++lev) {
97  for (int n = 0; n < 3; ++n) {
98  amrex::MultiFab::Copy(*m_field_vec[lev][n], *a_solver_vec[lev][n], 0, 0, m_ncomp, amrex::IntVect::TheZeroVector() );
99  }
100  }
101  }
102 
103  inline
104  void Copy ( const WarpXSolverVec& a_vec )
105  {
107  a_vec.IsDefined(),
108  "WarpXSolverVec::Copy(a_vec) called with undefined a_vec");
109  if (!IsDefined()) { Define(a_vec); }
110  const amrex::Vector<std::array< std::unique_ptr<amrex::MultiFab>, 3 > >& field_vec = a_vec.getVec();
111  Copy(field_vec);
112  }
113 
114  // Prohibit Copy assignment operator
115  WarpXSolverVec& operator= ( const WarpXSolverVec& a_vec ) = delete;
116 
117  // Move assignment operator
119  WarpXSolverVec& operator= ( WarpXSolverVec&& a_vec ) noexcept
120  {
121  if (this != &a_vec) {
122  m_field_vec = std::move(a_vec.m_field_vec);
123  m_is_defined = true;
124  }
125  return *this;
126  }
127 
128  inline
129  void operator+= ( const WarpXSolverVec& a_vec )
130  {
131  for (int lev = 0; lev < m_num_amr_levels; ++lev) {
132  for (int n=0; n<3; n++) {
133  m_field_vec[lev][n]->plus(*(a_vec.getVec()[lev][n]), 0, 1, 0);
134  }
135  }
136  }
137 
138  inline
139  void operator-= (const WarpXSolverVec& a_vec)
140  {
141  for (int lev = 0; lev < m_num_amr_levels; ++lev) {
142  for (int n=0; n<3; n++) {
143  m_field_vec[lev][n]->minus(*(a_vec.getVec()[lev][n]), 0, 1, 0);
144  }
145  }
146  }
147 
151  inline
152  void linComb (const RT a, const WarpXSolverVec& X, const RT b, const WarpXSolverVec& Y)
153  {
154  for (int lev = 0; lev < m_num_amr_levels; ++lev) {
155  for (int n=0; n<3; n++) {
156  amrex::MultiFab::LinComb(*m_field_vec[lev][n], a, *X.getVec()[lev][n], 0,
157  b, *Y.getVec()[lev][n], 0,
158  0, 1, 0);
159  }
160  }
161  }
162 
166  void increment (const WarpXSolverVec& X, const RT a)
167  {
168  for (int lev = 0; lev < m_num_amr_levels; ++lev) {
169  for (int n=0; n<3; n++) {
170  amrex::MultiFab::Saxpy( *m_field_vec[lev][n], a, *X.getVec()[lev][n],
171  0, 0, 1, amrex::IntVect::TheZeroVector() );
172  }
173  }
174  }
175 
179  inline
180  void scale (RT a_a)
181  {
182  for (int lev = 0; lev < m_num_amr_levels; ++lev) {
183  for (int n=0; n<3; n++) {
184  m_field_vec[lev][n]->mult(a_a, 0, 1);
185  }
186  }
187  }
188 
189  inline
190  void zero () { setVal(0.0); }
191 
192  inline
193  void setVal ( const RT a_val )
194  {
196  IsDefined(),
197  "WarpXSolverVec::ones() called on undefined WarpXSolverVec");
198  for (int lev = 0; lev < m_num_amr_levels; ++lev) {
199  for (int n=0; n<3; n++) {
200  m_field_vec[lev][n]->setVal(a_val);
201  }
202  }
203  }
204 
205  [[nodiscard]] inline RT norm2 () const
206  {
207  auto const norm = dotProduct(*this);
208  return std::sqrt(norm);
209  }
210 
213 
214  // clearDotMask() must be called by the highest class that owns WarpXSolverVec()
215  // after it is done being used ( typically in the destructor ) to avoid the
216  // following error message after the simulation finishes:
217  // malloc_consolidate(): unaligned fastbin chunk detected
218  static void clearDotMask() { m_dotMask.clear(); }
219 
220 private:
221 
222  bool m_is_defined = false;
224 
225  static constexpr int m_ncomp = 1;
226  static constexpr int m_num_amr_levels = 1;
227 
228  inline static bool m_dot_mask_defined = false;
230 
231 };
232 
233 #endif
#define AMREX_ASSERT_WITH_MESSAGE(EX, MSG)
#define WARPX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition: TextMsg.H:13
This is a wrapper class around a Vector of array of pointers to MultiFabs that contains basic math op...
Definition: WarpXSolverVec.H:48
amrex::Vector< std::array< std::unique_ptr< amrex::MultiFab >, 3 > > m_field_vec
Definition: WarpXSolverVec.H:223
static amrex::Vector< std::array< std::unique_ptr< amrex::iMultiFab >, 3 > > m_dotMask
Definition: WarpXSolverVec.H:229
WarpXSolverVec(WarpXSolverVec &&) noexcept=default
bool m_is_defined
Definition: WarpXSolverVec.H:222
WarpXSolverVec()=default
void operator+=(const WarpXSolverVec &a_vec)
Definition: WarpXSolverVec.H:129
amrex::Vector< std::array< std::unique_ptr< amrex::MultiFab >, 3 > > & getVec()
Definition: WarpXSolverVec.H:212
static void clearDotMask()
Definition: WarpXSolverVec.H:218
const amrex::Vector< std::array< std::unique_ptr< amrex::MultiFab >, 3 > > & getVec() const
Definition: WarpXSolverVec.H:211
static constexpr int m_num_amr_levels
Definition: WarpXSolverVec.H:226
static constexpr int m_ncomp
Definition: WarpXSolverVec.H:225
void SetDotMask(const amrex::Vector< amrex::Geometry > &a_Geom)
Definition: WarpXSolverVec.cpp:9
void Define(const amrex::Vector< std::array< std::unique_ptr< amrex::MultiFab >, 3 > > &a_solver_vec)
Definition: WarpXSolverVec.H:72
value_type RT
Definition: WarpXSolverVec.H:58
void linComb(const RT a, const WarpXSolverVec &X, const RT b, const WarpXSolverVec &Y)
Y = a*X + b*Y.
Definition: WarpXSolverVec.H:152
void scale(RT a_a)
Scale Y by a (Y *= a)
Definition: WarpXSolverVec.H:180
bool IsDefined() const
Definition: WarpXSolverVec.H:60
void zero()
Definition: WarpXSolverVec.H:190
void Copy(const WarpXSolverVec &a_vec)
Definition: WarpXSolverVec.H:104
void Define(const WarpXSolverVec &a_vec)
Definition: WarpXSolverVec.H:63
RT dotProduct(const WarpXSolverVec &a_X) const
Definition: WarpXSolverVec.cpp:32
void Copy(const amrex::Vector< std::array< std::unique_ptr< amrex::MultiFab >, 3 > > &a_solver_vec)
Definition: WarpXSolverVec.H:91
~WarpXSolverVec()=default
amrex::Real value_type
Definition: WarpXSolverVec.H:57
WarpXSolverVec & operator=(const WarpXSolverVec &a_vec)=delete
void setVal(const RT a_val)
Definition: WarpXSolverVec.H:193
void operator-=(const WarpXSolverVec &a_vec)
Definition: WarpXSolverVec.H:139
void increment(const WarpXSolverVec &X, const RT a)
Increment Y by a*X (Y += a*X)
Definition: WarpXSolverVec.H:166
RT norm2() const
Definition: WarpXSolverVec.H:205
static bool m_dot_mask_defined
Definition: WarpXSolverVec.H:228
WarpXSolverVec(const WarpXSolverVec &)=delete
const BoxArray & boxArray() const noexcept
const DistributionMapping & DistributionMap() const noexcept
int nComp() const noexcept
AMREX_GPU_HOST_DEVICE static constexpr AMREX_FORCE_INLINE IntVectND< dim > TheZeroVector() noexcept
static void LinComb(MultiFab &dst, Real a, const MultiFab &x, int xcomp, Real b, const MultiFab &y, int ycomp, int dstcomp, int numcomp, int nghost)
static void Saxpy(MultiFab &dst, Real a, const MultiFab &src, int srccomp, int dstcomp, int numcomp, int nghost)
static void Copy(MultiFab &dst, const MultiFab &src, int srccomp, int dstcomp, int numcomp, int nghost)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T norm(const GpuComplex< T > &a_z) noexcept
default
Definition: run_alltests.py:113