WarpX
PML.H
Go to the documentation of this file.
1 /* Copyright 2019 Andrew Myers, Aurore Blelly, Axel Huebl
2  * Maxence Thevenet, Remi Lehe, Weiqun Zhang
3  *
4  *
5  * This file is part of WarpX.
6  *
7  * License: BSD-3-Clause-LBNL
8  */
9 #ifndef WARPX_PML_H_
10 #define WARPX_PML_H_
11 
12 #include "PML_fwd.H"
13 
14 #ifdef WARPX_USE_PSATD
16 #endif
17 
18 #include <AMReX_MultiFab.H>
19 #include <AMReX_BoxArray.H>
20 #include <AMReX_Config.H>
21 #include <AMReX_FabArray.H>
22 #include <AMReX_FabFactory.H>
23 #include <AMReX_GpuContainers.H>
24 #include <AMReX_IntVect.H>
25 #include <AMReX_REAL.H>
26 #include <AMReX_Vector.H>
27 
28 #include <AMReX_BaseFwd.H>
29 
30 #include <array>
31 #include <memory>
32 #include <optional>
33 #include <string>
34 #include <vector>
35 
36 struct Sigma : amrex::Gpu::DeviceVector<amrex::Real>
37 {
38  int lo() const { return m_lo; }
39  int hi() const { return m_hi; }
40  int m_lo, m_hi;
41 };
42 
43 struct SigmaBox
44 {
45  SigmaBox (const amrex::Box& box, const amrex::BoxArray& grids,
46  const amrex::Real* dx, const amrex::IntVect& ncell, const amrex::IntVect& delta,
47  const amrex::Box& regdomain, amrex::Real v_sigma);
48 
49  void define_single (const amrex::Box& regdomain, const amrex::IntVect& ncell,
51  amrex::Real v_sigma);
52  void define_multiple (const amrex::Box& box, const amrex::BoxArray& grids,
53  const amrex::IntVect& ncell,
55  amrex::Real v_sigma);
56 
57  void ComputePMLFactorsB (const amrex::Real* dx, amrex::Real dt);
58  void ComputePMLFactorsE (const amrex::Real* dx, amrex::Real dt);
59 
60  using SigmaVect = std::array<Sigma,AMREX_SPACEDIM>;
61 
62  using value_type = void; // needed by amrex::FabArray
63 
72  amrex::Real v_sigma;
73 
74 };
75 
77  : public amrex::FabFactory<SigmaBox>
78 {
79 public:
80  SigmaBoxFactory (const amrex::BoxArray& grid_ba, const amrex::Real* dx,
81  const amrex::IntVect& ncell, const amrex::IntVect& delta,
82  const amrex::Box& regular_domain, const amrex::Real v_sigma_sb)
83  : m_grids(grid_ba), m_dx(dx), m_ncell(ncell), m_delta(delta), m_regdomain(regular_domain), m_v_sigma_sb(v_sigma_sb) {}
84  ~SigmaBoxFactory () override = default;
85 
86  SigmaBoxFactory (const SigmaBoxFactory&) = default;
88 
89  SigmaBoxFactory () = delete;
90  SigmaBoxFactory& operator= (const SigmaBoxFactory&) = delete;
91  SigmaBoxFactory& operator= (SigmaBoxFactory&&) = delete;
92 
93  SigmaBox* create (const amrex::Box& box, int /*ncomps*/,
94  const amrex::FabInfo& /*info*/, int /*box_index*/) const final
95  { return new SigmaBox(box, m_grids, m_dx, m_ncell, m_delta, m_regdomain, m_v_sigma_sb); }
96  void destroy (SigmaBox* fab) const final {
97  delete fab;
98  }
99  SigmaBoxFactory* clone () const final {
100  return new SigmaBoxFactory(*this);
101  }
102 private:
104  const amrex::Real* m_dx;
108  amrex::Real m_v_sigma_sb;
109 };
110 
112  : public amrex::FabArray<SigmaBox>
113 {
114 public:
116  const amrex::BoxArray& grid_ba, const amrex::Real* dx,
117  const amrex::IntVect& ncell, const amrex::IntVect& delta,
118  const amrex::Box& regular_domain, amrex::Real v_sigma_sb);
119  void ComputePMLFactorsB (const amrex::Real* dx, amrex::Real dt);
120  void ComputePMLFactorsE (const amrex::Real* dx, amrex::Real dt);
121 private:
122  amrex::Real dt_B = -1.e10;
123  amrex::Real dt_E = -1.e10;
124 };
125 
126 enum struct PatchType : int;
127 
128 class PML
129 {
130 public:
131  PML (int lev,
132  const amrex::BoxArray& ba, const amrex::DistributionMapping& dm,
133  const amrex::Geometry* geom, const amrex::Geometry* cgeom,
134  int ncell, int delta, amrex::IntVect ref_ratio,
135  amrex::Real dt, int nox_fft, int noy_fft, int noz_fft, short grid_type,
136  int do_moving_window, int pml_has_particles, int do_pml_in_domain,
137  int psatd_solution_type, int J_in_time, int rho_in_time,
138  bool do_pml_dive_cleaning, bool do_pml_divb_cleaning,
139  const amrex::IntVect& fill_guards_fields,
140  const amrex::IntVect& fill_guards_current,
141  int max_guard_EB, amrex::Real v_sigma_sb,
144 
145  void ComputePMLFactors (amrex::Real dt);
146 
147  std::array<amrex::MultiFab*,3> GetE_fp ();
148  std::array<amrex::MultiFab*,3> GetB_fp ();
149  std::array<amrex::MultiFab*,3> Getj_fp ();
150  std::array<amrex::MultiFab*,3> GetE_cp ();
151  std::array<amrex::MultiFab*,3> GetB_cp ();
152  std::array<amrex::MultiFab*,3> Getj_cp ();
153  std::array<amrex::MultiFab*,3> Get_edge_lengths ();
154  std::array<amrex::MultiFab*,3> Get_face_areas ();
155 
156  // Used when WarpX::do_pml_dive_cleaning = true
159 
160  // Used when WarpX::do_pml_divb_cleaning = true
163 
165  { return *sigba_fp; }
166 
168  { return *sigba_cp; }
169 
170 #ifdef WARPX_USE_PSATD
171  void PushPSATD (int lev);
172 #endif
173 
174  void CopyJtoPMLs (const std::array<amrex::MultiFab*,3>& j_fp,
175  const std::array<amrex::MultiFab*,3>& j_cp);
176 
177  void Exchange (const std::array<amrex::MultiFab*,3>& mf_pml,
178  const std::array<amrex::MultiFab*,3>& mf,
179  const PatchType& patch_type,
180  int do_pml_in_domain);
181 
182  void CopyJtoPMLs (PatchType patch_type,
183  const std::array<amrex::MultiFab*,3>& jp);
184 
185  void ExchangeF (amrex::MultiFab* F_fp, amrex::MultiFab* F_cp, int do_pml_in_domain);
186  void ExchangeF (PatchType patch_type, amrex::MultiFab* Fp, int do_pml_in_domain);
187 
188  void ExchangeG (amrex::MultiFab* G_fp, amrex::MultiFab* G_cp, int do_pml_in_domain);
189  void ExchangeG (PatchType patch_type, amrex::MultiFab* Gp, int do_pml_in_domain);
190 
191  void FillBoundaryE (PatchType patch_type, std::optional<bool> nodal_sync=std::nullopt);
192  void FillBoundaryB (PatchType patch_type, std::optional<bool> nodal_sync=std::nullopt);
193  void FillBoundaryF (PatchType patch_type, std::optional<bool> nodal_sync=std::nullopt);
194  void FillBoundaryG (PatchType patch_type, std::optional<bool> nodal_sync=std::nullopt);
195 
196  bool ok () const { return m_ok; }
197 
198  void CheckPoint (const std::string& dir) const;
199  void Restart (const std::string& dir);
200 
201  static void Exchange (amrex::MultiFab& pml, amrex::MultiFab& reg, const amrex::Geometry& geom, int do_pml_in_domain);
202 
203 private:
204  bool m_ok;
205 
208 
211 
214 
215  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_E_fp;
216  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_B_fp;
217  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_j_fp;
218 
219  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_edge_lengths;
220 
221  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_E_cp;
222  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_B_cp;
223  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_j_cp;
224 
225  // Used when WarpX::do_pml_dive_cleaning = true
226  std::unique_ptr<amrex::MultiFab> pml_F_fp;
227  std::unique_ptr<amrex::MultiFab> pml_F_cp;
228 
229  // Used when WarpX::do_pml_divb_cleaning = true
230  std::unique_ptr<amrex::MultiFab> pml_G_fp;
231  std::unique_ptr<amrex::MultiFab> pml_G_cp;
232 
233  std::unique_ptr<MultiSigmaBox> sigba_fp;
234  std::unique_ptr<MultiSigmaBox> sigba_cp;
235 
236 #ifdef WARPX_USE_PSATD
237  std::unique_ptr<SpectralSolver> spectral_solver_fp;
238  std::unique_ptr<SpectralSolver> spectral_solver_cp;
239 #endif
240 
241  // Factory for field data
242  std::unique_ptr<amrex::FabFactory<amrex::FArrayBox> > pml_field_factory;
243 
245  return *pml_field_factory;
246  }
247 #ifdef AMREX_USE_EB
248  amrex::EBFArrayBoxFactory const& fieldEBFactory () const noexcept {
249  return static_cast<amrex::EBFArrayBoxFactory const&>(*pml_field_factory);
250  }
251 #endif
252 
253  static amrex::BoxArray MakeBoxArray (bool single_box_domain,
254  const amrex::Box& regular_domain,
255  const amrex::Geometry& geom,
256  const amrex::BoxArray& grid_ba,
257  const amrex::IntVect& ncell,
258  int do_pml_in_domain,
259  const amrex::IntVect& do_pml_Lo,
260  const amrex::IntVect& do_pml_Hi);
261 
262  static amrex::BoxArray MakeBoxArray_single (const amrex::Box& regular_domain,
263  const amrex::BoxArray& grid_ba,
264  const amrex::IntVect& ncell,
265  const amrex::IntVect& do_pml_Lo,
266  const amrex::IntVect& do_pml_Hi);
267 
268  static amrex::BoxArray MakeBoxArray_multiple (const amrex::Geometry& geom,
269  const amrex::BoxArray& grid_ba,
270  const amrex::IntVect& ncell,
271  int do_pml_in_domain,
272  const amrex::IntVect& do_pml_Lo,
273  const amrex::IntVect& do_pml_Hi);
274 
275  static void CopyToPML (amrex::MultiFab& pml, amrex::MultiFab& reg, const amrex::Geometry& geom);
276 };
277 
278 #ifdef WARPX_USE_PSATD
279 void PushPMLPSATDSinglePatch( int lev,
280  SpectralSolver& solver,
281  std::array<std::unique_ptr<amrex::MultiFab>,3>& pml_E,
282  std::array<std::unique_ptr<amrex::MultiFab>,3>& pml_B,
283  std::unique_ptr<amrex::MultiFab>& pml_F,
284  std::unique_ptr<amrex::MultiFab>& pml_G,
285  const amrex::IntVect& fill_guards);
286 #endif
287 
288 #endif
void PushPMLPSATDSinglePatch(int lev, SpectralSolver &solver, std::array< std::unique_ptr< amrex::MultiFab >, 3 > &pml_E, std::array< std::unique_ptr< amrex::MultiFab >, 3 > &pml_B, std::unique_ptr< amrex::MultiFab > &pml_F, std::unique_ptr< amrex::MultiFab > &pml_G, const amrex::IntVect &fill_guards)
Definition: PML.cpp:1357
PatchType
Definition: WarpX.H:78
Definition: PML.H:113
amrex::Real dt_E
Definition: PML.H:123
void ComputePMLFactorsE(const amrex::Real *dx, amrex::Real dt)
Definition: PML.cpp:530
void ComputePMLFactorsB(const amrex::Real *dx, amrex::Real dt)
Definition: PML.cpp:514
amrex::Real dt_B
Definition: PML.H:122
MultiSigmaBox(const amrex::BoxArray &ba, const amrex::DistributionMapping &dm, const amrex::BoxArray &grid_ba, const amrex::Real *dx, const amrex::IntVect &ncell, const amrex::IntVect &delta, const amrex::Box &regular_domain, amrex::Real v_sigma_sb)
Definition: PML.cpp:505
Definition: PML.H:129
const MultiSigmaBox & GetMultiSigmaBox_fp() const
Definition: PML.H:164
const amrex::Geometry * m_geom
Definition: PML.H:212
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_edge_lengths
Definition: PML.H:219
void ComputePMLFactors(amrex::Real dt)
Definition: PML.cpp:992
amrex::MultiFab * GetG_cp()
Definition: PML.cpp:1066
std::unique_ptr< amrex::FabFactory< amrex::FArrayBox > > pml_field_factory
Definition: PML.H:242
std::unique_ptr< amrex::MultiFab > pml_F_fp
Definition: PML.H:226
const amrex::IntVect m_fill_guards_fields
Definition: PML.H:209
void PushPSATD(int lev)
Definition: PML.cpp:1347
std::array< amrex::MultiFab *, 3 > GetE_fp()
Definition: PML.cpp:1005
std::array< amrex::MultiFab *, 3 > Getj_cp()
Definition: PML.cpp:1035
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_B_fp
Definition: PML.H:216
amrex::MultiFab * GetF_fp()
Definition: PML.cpp:1048
std::unique_ptr< MultiSigmaBox > sigba_fp
Definition: PML.H:233
const amrex::Geometry * m_cgeom
Definition: PML.H:213
bool ok() const
Definition: PML.H:196
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_j_fp
Definition: PML.H:217
amrex::FabFactory< amrex::FArrayBox > const & fieldFactory() const noexcept
Definition: PML.H:244
void Exchange(const std::array< amrex::MultiFab *, 3 > &mf_pml, const std::array< amrex::MultiFab *, 3 > &mf, const PatchType &patch_type, int do_pml_in_domain)
Definition: PML.cpp:1071
bool m_divb_cleaning
Definition: PML.H:207
bool m_ok
Definition: PML.H:204
std::array< amrex::MultiFab *, 3 > Getj_fp()
Definition: PML.cpp:1017
std::array< amrex::MultiFab *, 3 > Get_edge_lengths()
Definition: PML.cpp:1041
bool m_dive_cleaning
Definition: PML.H:206
PML(int lev, const amrex::BoxArray &ba, const amrex::DistributionMapping &dm, const amrex::Geometry *geom, const amrex::Geometry *cgeom, int ncell, int delta, amrex::IntVect ref_ratio, amrex::Real dt, int nox_fft, int noy_fft, int noz_fft, short grid_type, int do_moving_window, int pml_has_particles, int do_pml_in_domain, int psatd_solution_type, int J_in_time, int rho_in_time, bool do_pml_dive_cleaning, bool do_pml_divb_cleaning, const amrex::IntVect &fill_guards_fields, const amrex::IntVect &fill_guards_current, int max_guard_EB, amrex::Real v_sigma_sb, amrex::IntVect do_pml_Lo=amrex::IntVect::TheUnitVector(), amrex::IntVect do_pml_Hi=amrex::IntVect::TheUnitVector())
Definition: PML.cpp:545
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_B_cp
Definition: PML.H:222
amrex::MultiFab * GetF_cp()
Definition: PML.cpp:1054
amrex::MultiFab * GetG_fp()
Definition: PML.cpp:1060
const MultiSigmaBox & GetMultiSigmaBox_cp() const
Definition: PML.H:167
const amrex::IntVect m_fill_guards_current
Definition: PML.H:210
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_E_cp
Definition: PML.H:221
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_j_cp
Definition: PML.H:223
std::unique_ptr< MultiSigmaBox > sigba_cp
Definition: PML.H:234
std::array< amrex::MultiFab *, 3 > GetE_cp()
Definition: PML.cpp:1023
std::unique_ptr< amrex::MultiFab > pml_F_cp
Definition: PML.H:227
std::array< amrex::MultiFab *, 3 > Get_face_areas()
std::unique_ptr< SpectralSolver > spectral_solver_cp
Definition: PML.H:238
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_E_fp
Definition: PML.H:215
std::unique_ptr< SpectralSolver > spectral_solver_fp
Definition: PML.H:237
std::array< amrex::MultiFab *, 3 > GetB_fp()
Definition: PML.cpp:1011
std::array< amrex::MultiFab *, 3 > GetB_cp()
Definition: PML.cpp:1029
void CopyJtoPMLs(const std::array< amrex::MultiFab *, 3 > &j_fp, const std::array< amrex::MultiFab *, 3 > &j_cp)
Definition: PML.cpp:1101
std::unique_ptr< amrex::MultiFab > pml_G_fp
Definition: PML.H:230
std::unique_ptr< amrex::MultiFab > pml_G_cp
Definition: PML.H:231
Definition: PML.H:78
SigmaBoxFactory(const amrex::BoxArray &grid_ba, const amrex::Real *dx, const amrex::IntVect &ncell, const amrex::IntVect &delta, const amrex::Box &regular_domain, const amrex::Real v_sigma_sb)
Definition: PML.H:80
amrex::IntVect m_delta
Definition: PML.H:106
SigmaBoxFactory(SigmaBoxFactory &&) noexcept=default
amrex::IntVect m_ncell
Definition: PML.H:105
amrex::Box m_regdomain
Definition: PML.H:107
SigmaBoxFactory(const SigmaBoxFactory &)=default
SigmaBoxFactory * clone() const final
Definition: PML.H:99
amrex::Real m_v_sigma_sb
Definition: PML.H:108
SigmaBoxFactory()=delete
void destroy(SigmaBox *fab) const final
Definition: PML.H:96
SigmaBox * create(const amrex::Box &box, int, const amrex::FabInfo &, int) const final
Definition: PML.H:93
const amrex::BoxArray & m_grids
Definition: PML.H:103
~SigmaBoxFactory() override=default
const amrex::Real * m_dx
Definition: PML.H:104
Top-level class for the electromagnetic spectral solver.
Definition: SpectralSolver.H:33
AMREX_GPU_HOST_DEVICE static constexpr AMREX_FORCE_INLINE IntVect TheUnitVector() noexcept
const int[]
std::array< T, N > Array
default
Definition: run_alltests.py:113
float dt
Definition: stencil.py:442
tuple dx
lab frame
Definition: stencil.py:429
Definition: PML.H:44
SigmaVect sigma_star_cumsum_fac
Definition: PML.H:71
void define_multiple(const amrex::Box &box, const amrex::BoxArray &grids, const amrex::IntVect &ncell, const amrex::Array< amrex::Real, AMREX_SPACEDIM > &fac, amrex::Real v_sigma)
Definition: PML.cpp:238
SigmaVect sigma_star
Definition: PML.H:66
std::array< Sigma, AMREX_SPACEDIM > SigmaVect
Definition: PML.H:60
SigmaVect sigma_star_fac
Definition: PML.H:70
SigmaVect sigma_cumsum
Definition: PML.H:65
SigmaVect sigma_star_cumsum
Definition: PML.H:67
void ComputePMLFactorsB(const amrex::Real *dx, amrex::Real dt)
Definition: PML.cpp:438
void value_type
Definition: PML.H:62
SigmaVect sigma_cumsum_fac
Definition: PML.H:69
SigmaVect sigma_fac
Definition: PML.H:68
SigmaBox(const amrex::Box &box, const amrex::BoxArray &grids, const amrex::Real *dx, const amrex::IntVect &ncell, const amrex::IntVect &delta, const amrex::Box &regdomain, amrex::Real v_sigma)
Definition: PML.cpp:145
void ComputePMLFactorsE(const amrex::Real *dx, amrex::Real dt)
Definition: PML.cpp:472
void define_single(const amrex::Box &regdomain, const amrex::IntVect &ncell, const amrex::Array< amrex::Real, AMREX_SPACEDIM > &fac, amrex::Real v_sigma)
Definition: PML.cpp:195
SigmaVect sigma
Definition: PML.H:64
amrex::Real v_sigma
Definition: PML.H:72
Definition: PML.H:37
int m_lo
Definition: PML.H:40
int lo() const
Definition: PML.H:38
int hi() const
Definition: PML.H:39
int m_hi
Definition: PML.H:40