ARTEMIS
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 <string>
33 #include <vector>
34 
35 struct Sigma : amrex::Gpu::DeviceVector<amrex::Real>
36 {
37  int lo() const { return m_lo; }
38  int hi() const { return m_hi; }
39  int m_lo, m_hi;
40 };
41 
42 struct SigmaBox
43 {
44  SigmaBox (const amrex::Box& box, const amrex::BoxArray& grids,
45  const amrex::Real* dx, const amrex::IntVect& ncell, const amrex::IntVect& delta,
46  const amrex::Box& regdomain, const amrex::Real v_sigma);
47 
48  void define_single (const amrex::Box& regdomain, const amrex::IntVect& ncell,
50  const amrex::Real v_sigma);
51  void define_multiple (const amrex::Box& box, const amrex::BoxArray& grids,
52  const amrex::IntVect& ncell,
54  const amrex::Real v_sigma);
55 
56  void ComputePMLFactorsB (const amrex::Real* dx, amrex::Real dt);
57  void ComputePMLFactorsE (const amrex::Real* dx, amrex::Real dt);
58 
59  using SigmaVect = std::array<Sigma,AMREX_SPACEDIM>;
60 
61  using value_type = void; // needed by amrex::FabArray
62 
71  amrex::Real v_sigma;
72 
73 };
74 
76  : public amrex::FabFactory<SigmaBox>
77 {
78 public:
79  SigmaBoxFactory (const amrex::BoxArray& grid_ba, const amrex::Real* dx,
80  const amrex::IntVect& ncell, const amrex::IntVect& delta,
81  const amrex::Box& regular_domain, const amrex::Real v_sigma_sb)
82  : m_grids(grid_ba), m_dx(dx), m_ncell(ncell), m_delta(delta), m_regdomain(regular_domain), m_v_sigma_sb(v_sigma_sb) {}
83  virtual ~SigmaBoxFactory () = default;
84 
85  SigmaBoxFactory (const SigmaBoxFactory&) = default;
87 
88  SigmaBoxFactory () = delete;
89  SigmaBoxFactory& operator= (const SigmaBoxFactory&) = delete;
90  SigmaBoxFactory& operator= (SigmaBoxFactory&&) = delete;
91 
92  virtual SigmaBox* create (const amrex::Box& box, int /*ncomps*/,
93  const amrex::FabInfo& /*info*/, int /*box_index*/) const final
94  { return new SigmaBox(box, m_grids, m_dx, m_ncell, m_delta, m_regdomain, m_v_sigma_sb); }
95  virtual void destroy (SigmaBox* fab) const final {
96  delete fab;
97  }
98  virtual SigmaBoxFactory* clone () const final {
99  return new SigmaBoxFactory(*this);
100  }
101 private:
103  const amrex::Real* m_dx;
107  amrex::Real m_v_sigma_sb;
108 };
109 
111  : public amrex::FabArray<SigmaBox>
112 {
113 public:
115  const amrex::BoxArray& grid_ba, const amrex::Real* dx,
116  const amrex::IntVect& ncell, const amrex::IntVect& delta,
117  const amrex::Box& regular_domain, const amrex::Real v_sigma_sb);
118  void ComputePMLFactorsB (const amrex::Real* dx, amrex::Real dt);
119  void ComputePMLFactorsE (const amrex::Real* dx, amrex::Real dt);
120 private:
121  amrex::Real dt_B = -1.e10;
122  amrex::Real dt_E = -1.e10;
123 };
124 
125 enum struct PatchType : int;
126 
127 class PML
128 {
129 public:
130  PML (const int lev,
131  const amrex::BoxArray& ba, const amrex::DistributionMapping& dm,
132  const amrex::Geometry* geom, const amrex::Geometry* cgeom,
133  int ncell, int delta, amrex::IntVect ref_ratio,
134  amrex::Real dt, int nox_fft, int noy_fft, int noz_fft, short grid_type,
135  int do_moving_window, int pml_has_particles, int do_pml_in_domain,
136  const int psatd_solution_type, const int J_in_time, const int rho_in_time,
137  const bool do_pml_dive_cleaning, const bool do_pml_divb_cleaning,
138  const amrex::IntVect& fill_guards_fields,
139  const amrex::IntVect& fill_guards_current,
140  int max_guard_EB, amrex::Real v_sigma_sb,
141  const amrex::IntVect do_pml_Lo = amrex::IntVect::TheUnitVector(),
142  const amrex::IntVect do_pml_Hi = amrex::IntVect::TheUnitVector());
143 
144  void ComputePMLFactors (amrex::Real dt);
145 
146  std::array<amrex::MultiFab*,3> GetE_fp ();
147  std::array<amrex::MultiFab*,3> GetPEC_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 #ifdef WARPX_MAG_LLG
156  std::array<amrex::MultiFab*,3> GetH_fp ();
157  std::array<amrex::MultiFab*,3> GetH_cp ();
158 #endif
163  amrex::MultiFab* GetE_fp (int comp);
164  amrex::MultiFab* GetPEC_fp (int comp);
165 
166  // Used when WarpX::do_pml_dive_cleaning = true
169 
170  // return macroscopic pml multifabs
177  // Used when WarpX::do_pml_divb_cleaning = true
180 
182  { return *sigba_fp; }
183 
185  { return *sigba_cp; }
186 
187 #ifdef WARPX_USE_PSATD
188  void PushPSATD (const int lev);
189 #endif
190 
191  void CopyJtoPMLs (const std::array<amrex::MultiFab*,3>& j_fp,
192  const std::array<amrex::MultiFab*,3>& j_cp);
193 
194  void Exchange (const std::array<amrex::MultiFab*,3>& mf_pml,
195  const std::array<amrex::MultiFab*,3>& mf,
196  const PatchType& patch_type,
197  const int do_pml_in_domain);
198 
199  void CopyJtoPMLs (PatchType patch_type,
200  const std::array<amrex::MultiFab*,3>& jp);
201 
202  void ExchangeF (amrex::MultiFab* F_fp, amrex::MultiFab* F_cp, int do_pml_in_domain);
203  void ExchangeF (PatchType patch_type, amrex::MultiFab* Fp, int do_pml_in_domain);
204 
205 #ifdef WARPX_MAG_LLG
206  void ExchangeH (const std::array<amrex::MultiFab*,3>& H_fp,
207  const std::array<amrex::MultiFab*,3>& H_cp, int do_pml_in_domain);
208  void ExchangeH (PatchType patch_type,
209  const std::array<amrex::MultiFab*,3>& Hp, int do_pml_in_domain);
210 #endif
211  void ExchangeG (amrex::MultiFab* G_fp, amrex::MultiFab* G_cp, int do_pml_in_domain);
212  void ExchangeG (PatchType patch_type, amrex::MultiFab* Gp, int do_pml_in_domain);
213 
214  void FillBoundary ();
215  void FillBoundaryE ();
216  void FillBoundaryB ();
217  void FillBoundaryF ();
218  void FillBoundaryG ();
219  void FillBoundaryE (PatchType patch_type);
220  void FillBoundaryB (PatchType patch_type);
221  void FillBoundaryF (PatchType patch_type);
222 #ifdef WARPX_MAG_LLG
223  void FillBoundaryH ();
224  void FillBoundaryH (PatchType patch_type);
225 #endif
226  void FillBoundaryG (PatchType patch_type);
227 
228  bool ok () const { return m_ok; }
229 
230  void CheckPoint (const std::string& dir) const;
231  void Restart (const std::string& dir);
232 
233  static void Exchange (amrex::MultiFab& pml, amrex::MultiFab& reg, const amrex::Geometry& geom, int do_pml_in_domain);
234 
235  ~PML () = default;
236 
237 private:
238  bool m_ok;
239 
242 
245 
248 
249  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_E_fp;
250  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_B_fp;
251  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_j_fp;
252 
253  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_PEC_fp;
254 
255  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_edge_lengths;
256 
257  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_E_cp;
258  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_B_cp;
259  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_j_cp;
260 
261  // Used when WarpX::do_pml_dive_cleaning = true
262  std::unique_ptr<amrex::MultiFab> pml_F_fp;
263  std::unique_ptr<amrex::MultiFab> pml_F_cp;
264 
265 #ifdef WARPX_MAG_LLG
266  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_H_fp;
267  std::array<std::unique_ptr<amrex::MultiFab>,3> pml_H_cp;
268 #endif
269 
270  // macroproperties in PML, eps-permittivity, mu-permeability, sigma-condictivity
271  std::unique_ptr<amrex::MultiFab> pml_eps_fp;
272  std::unique_ptr<amrex::MultiFab> pml_mu_fp;
273  std::unique_ptr<amrex::MultiFab> pml_sigma_fp;
274  std::unique_ptr<amrex::MultiFab> pml_eps_cp;
275  std::unique_ptr<amrex::MultiFab> pml_mu_cp;
276  std::unique_ptr<amrex::MultiFab> pml_sigma_cp;
277  // Used when WarpX::do_pml_divb_cleaning = true
278  std::unique_ptr<amrex::MultiFab> pml_G_fp;
279  std::unique_ptr<amrex::MultiFab> pml_G_cp;
280 
281  std::unique_ptr<MultiSigmaBox> sigba_fp;
282  std::unique_ptr<MultiSigmaBox> sigba_cp;
283 
284 #ifdef WARPX_USE_PSATD
285  std::unique_ptr<SpectralSolver> spectral_solver_fp;
286  std::unique_ptr<SpectralSolver> spectral_solver_cp;
287 #endif
288 
289  // Factory for field data
290  std::unique_ptr<amrex::FabFactory<amrex::FArrayBox> > pml_field_factory;
291 
293  return *pml_field_factory;
294  }
295 #ifdef AMREX_USE_EB
296  amrex::EBFArrayBoxFactory const& fieldEBFactory () const noexcept {
297  return static_cast<amrex::EBFArrayBoxFactory const&>(*pml_field_factory);
298  }
299 #endif
300 
301  static amrex::BoxArray MakeBoxArray (bool single_box_domain,
302  const amrex::Box& regular_domain,
303  const amrex::Geometry& geom,
304  const amrex::BoxArray& grid_ba,
305  const amrex::IntVect& ncell,
306  int do_pml_in_domain,
307  const amrex::IntVect& do_pml_Lo,
308  const amrex::IntVect& do_pml_Hi);
309 
310  static amrex::BoxArray MakeBoxArray_single (const amrex::Box& regular_domain,
311  const amrex::BoxArray& grid_ba,
312  const amrex::IntVect& ncell,
313  const amrex::IntVect& do_pml_Lo,
314  const amrex::IntVect& do_pml_Hi);
315 
316  static amrex::BoxArray MakeBoxArray_multiple (const amrex::Geometry& geom,
317  const amrex::BoxArray& grid_ba,
318  const amrex::IntVect& ncell,
319  int do_pml_in_domain,
320  const amrex::IntVect& do_pml_Lo,
321  const amrex::IntVect& do_pml_Hi);
322 
323  static void CopyToPML (amrex::MultiFab& pml, amrex::MultiFab& reg, const amrex::Geometry& geom);
324 };
325 
326 #ifdef WARPX_USE_PSATD
327 void PushPMLPSATDSinglePatch( const int lev,
328  SpectralSolver& solver,
329  std::array<std::unique_ptr<amrex::MultiFab>,3>& pml_E,
330  std::array<std::unique_ptr<amrex::MultiFab>,3>& pml_B,
331  std::unique_ptr<amrex::MultiFab>& pml_F,
332  std::unique_ptr<amrex::MultiFab>& pml_G,
333  const amrex::IntVect& fill_guards);
334 #endif
335 
336 #endif
void PushPMLPSATDSinglePatch(const 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:1689
PatchType
Definition: WarpX.H:74
Definition: PML.H:112
amrex::Real dt_E
Definition: PML.H:122
void ComputePMLFactorsE(const amrex::Real *dx, amrex::Real dt)
Definition: PML.cpp:533
void ComputePMLFactorsB(const amrex::Real *dx, amrex::Real dt)
Definition: PML.cpp:517
amrex::Real dt_B
Definition: PML.H:121
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, const amrex::Real v_sigma_sb)
Definition: PML.cpp:508
Definition: PML.H:128
amrex::MultiFab * Getmu_fp()
Definition: PML.cpp:1244
const MultiSigmaBox & GetMultiSigmaBox_fp() const
Definition: PML.H:181
amrex::MultiFab * Getsigma_fp()
Definition: PML.cpp:1250
const amrex::Geometry * m_geom
Definition: PML.H:246
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_edge_lengths
Definition: PML.H:255
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_PEC_fp
Definition: PML.H:253
std::unique_ptr< amrex::MultiFab > pml_eps_cp
Definition: PML.H:274
void ComputePMLFactors(amrex::Real dt)
Definition: PML.cpp:1135
amrex::MultiFab * GetG_cp()
Definition: PML.cpp:1280
std::unique_ptr< amrex::FabFactory< amrex::FArrayBox > > pml_field_factory
Definition: PML.H:290
std::unique_ptr< amrex::MultiFab > pml_F_fp
Definition: PML.H:262
const amrex::IntVect m_fill_guards_fields
Definition: PML.H:243
std::array< amrex::MultiFab *, 3 > GetE_fp()
Definition: PML.cpp:1148
std::array< amrex::MultiFab *, 3 > Getj_cp()
Definition: PML.cpp:1212
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_B_fp
Definition: PML.H:250
amrex::MultiFab * GetF_fp()
Definition: PML.cpp:1225
std::array< amrex::MultiFab *, 3 > GetPEC_fp()
Definition: PML.cpp:1160
std::unique_ptr< MultiSigmaBox > sigba_fp
Definition: PML.H:281
const amrex::Geometry * m_cgeom
Definition: PML.H:247
bool ok() const
Definition: PML.H:228
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_j_fp
Definition: PML.H:251
amrex::FabFactory< amrex::FArrayBox > const & fieldFactory() const noexcept
Definition: PML.H:292
amrex::MultiFab * Geteps_cp()
Definition: PML.cpp:1256
std::unique_ptr< amrex::MultiFab > pml_mu_fp
Definition: PML.H:272
bool m_divb_cleaning
Definition: PML.H:241
amrex::MultiFab * Geteps_fp()
Definition: PML.cpp:1238
bool m_ok
Definition: PML.H:238
std::array< amrex::MultiFab *, 3 > Getj_fp()
Definition: PML.cpp:1186
std::unique_ptr< amrex::MultiFab > pml_eps_fp
Definition: PML.H:271
PML(const 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, const int psatd_solution_type, const int J_in_time, const int rho_in_time, const bool do_pml_dive_cleaning, const 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, const amrex::IntVect do_pml_Lo=amrex::IntVect::TheUnitVector(), const amrex::IntVect do_pml_Hi=amrex::IntVect::TheUnitVector())
Definition: PML.cpp:548
std::array< amrex::MultiFab *, 3 > Get_edge_lengths()
Definition: PML.cpp:1218
bool m_dive_cleaning
Definition: PML.H:240
void PushPSATD(const int lev)
Definition: PML.cpp:1679
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_B_cp
Definition: PML.H:258
amrex::MultiFab * GetF_cp()
Definition: PML.cpp:1231
amrex::MultiFab * Getsigma_cp()
Definition: PML.cpp:1268
amrex::MultiFab * GetG_fp()
Definition: PML.cpp:1274
const MultiSigmaBox & GetMultiSigmaBox_cp() const
Definition: PML.H:184
std::unique_ptr< amrex::MultiFab > pml_sigma_cp
Definition: PML.H:276
const amrex::IntVect m_fill_guards_current
Definition: PML.H:244
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_E_cp
Definition: PML.H:257
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_j_cp
Definition: PML.H:259
std::unique_ptr< MultiSigmaBox > sigba_cp
Definition: PML.H:282
std::array< amrex::MultiFab *, 3 > GetE_cp()
Definition: PML.cpp:1192
std::unique_ptr< amrex::MultiFab > pml_mu_cp
Definition: PML.H:275
~PML()=default
amrex::MultiFab * Getmu_cp()
Definition: PML.cpp:1262
std::unique_ptr< amrex::MultiFab > pml_F_cp
Definition: PML.H:263
std::array< amrex::MultiFab *, 3 > Get_face_areas()
std::unique_ptr< SpectralSolver > spectral_solver_cp
Definition: PML.H:286
std::array< std::unique_ptr< amrex::MultiFab >, 3 > pml_E_fp
Definition: PML.H:249
void Exchange(const std::array< amrex::MultiFab *, 3 > &mf_pml, const std::array< amrex::MultiFab *, 3 > &mf, const PatchType &patch_type, const int do_pml_in_domain)
Definition: PML.cpp:1285
std::unique_ptr< amrex::MultiFab > pml_sigma_fp
Definition: PML.H:273
std::unique_ptr< SpectralSolver > spectral_solver_fp
Definition: PML.H:285
std::array< amrex::MultiFab *, 3 > GetB_fp()
Definition: PML.cpp:1172
std::array< amrex::MultiFab *, 3 > GetB_cp()
Definition: PML.cpp:1198
void CopyJtoPMLs(const std::array< amrex::MultiFab *, 3 > &j_fp, const std::array< amrex::MultiFab *, 3 > &j_cp)
Definition: PML.cpp:1346
std::unique_ptr< amrex::MultiFab > pml_G_fp
Definition: PML.H:278
std::unique_ptr< amrex::MultiFab > pml_G_cp
Definition: PML.H:279
Definition: PML.H:77
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:79
virtual SigmaBoxFactory * clone() const final
Definition: PML.H:98
amrex::IntVect m_delta
Definition: PML.H:105
SigmaBoxFactory(SigmaBoxFactory &&) noexcept=default
amrex::IntVect m_ncell
Definition: PML.H:104
amrex::Box m_regdomain
Definition: PML.H:106
SigmaBoxFactory(const SigmaBoxFactory &)=default
virtual void destroy(SigmaBox *fab) const final
Definition: PML.H:95
amrex::Real m_v_sigma_sb
Definition: PML.H:107
virtual ~SigmaBoxFactory()=default
SigmaBoxFactory()=delete
const amrex::BoxArray & m_grids
Definition: PML.H:102
virtual SigmaBox * create(const amrex::Box &box, int, const amrex::FabInfo &, int) const final
Definition: PML.H:92
const amrex::Real * m_dx
Definition: PML.H:103
Top-level class for the electromagnetic spectral solver.
Definition: SpectralSolver.H:33
AMREX_GPU_HOST_DEVICE static AMREX_FORCE_INLINE constexpr IntVectND< dim > TheUnitVector() noexcept
void FillBoundary(amrex::MultiFab &mf, amrex::IntVect ng, bool do_single_precision_comms, const amrex::Periodicity &period, std::optional< bool > nodal_sync)
Definition: Communication.cpp:65
std::array< T, N > Array
default
Definition: run_alltests.py:113
int dx
Definition: stencil.py:436
int dt
Definition: stencil.py:440
Definition: PML.H:43
SigmaVect sigma_star_cumsum_fac
Definition: PML.H:70
SigmaVect sigma_star
Definition: PML.H:65
std::array< Sigma, AMREX_SPACEDIM > SigmaVect
Definition: PML.H:59
SigmaVect sigma_star_fac
Definition: PML.H:69
SigmaVect sigma_cumsum
Definition: PML.H:64
SigmaVect sigma_star_cumsum
Definition: PML.H:66
void ComputePMLFactorsB(const amrex::Real *dx, amrex::Real dt)
Definition: PML.cpp:441
void value_type
Definition: PML.H:61
SigmaVect sigma_cumsum_fac
Definition: PML.H:68
SigmaVect sigma_fac
Definition: PML.H:67
void define_multiple(const amrex::Box &box, const amrex::BoxArray &grids, const amrex::IntVect &ncell, const amrex::Array< amrex::Real, AMREX_SPACEDIM > &fac, const amrex::Real v_sigma)
Definition: PML.cpp:240
void ComputePMLFactorsE(const amrex::Real *dx, amrex::Real dt)
Definition: PML.cpp:475
SigmaVect sigma
Definition: PML.H:63
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, const amrex::Real v_sigma)
Definition: PML.cpp:147
void define_single(const amrex::Box &regdomain, const amrex::IntVect &ncell, const amrex::Array< amrex::Real, AMREX_SPACEDIM > &fac, const amrex::Real v_sigma)
Definition: PML.cpp:197
amrex::Real v_sigma
Definition: PML.H:71
Definition: PML.H:36
int m_lo
Definition: PML.H:39
int lo() const
Definition: PML.H:37
int hi() const
Definition: PML.H:38
int m_hi
Definition: PML.H:39