ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_ReadCheckpointMF.H
Go to the documentation of this file.
1 #ifndef ERF_READ_CHECKPOINT_MF_H_
2 #define ERF_READ_CHECKPOINT_MF_H_
3 
4 #include <string>
5 
6 #include <AMReX_Geometry.H>
7 #include <AMReX_IntVect.H>
8 #include <AMReX_MultiFab.H>
9 #include <AMReX_Periodicity.H>
10 #include <AMReX_VisMF.H>
11 
12 namespace erf_checkpoint {
13 
14 /**
15  * The periodicity of geom in x and y only. For planar fields, and for the terrain heights,
16  * which are not periodic in z even when the domain is: in a domain periodic in z, the top
17  * node of a column is the image of the bottom one but its height is not.
18  */
19 inline amrex::Periodicity
20 lateral_periodicity (const amrex::Geometry& geom)
21 {
22  const amrex::Box& dom = geom.Domain();
23  return amrex::Periodicity(amrex::IntVect(AMREX_D_DECL(geom.isPeriodic(0) ? dom.length(0) : 0,
24  geom.isPeriodic(1) ? dom.length(1) : 0,
25  0)));
26 }
27 
28 /**
29  * Read one checkpoint MultiFab and deposit it into dst, which may live on different grids.
30  *
31  * The source is read into an undefined MultiFab, which VisMF::Read then defines on the
32  * BoxArray recorded in the file, so no caller needs to know the checkpoint's grids -- which
33  * is what lets a restart land a component's state on level-0 grids that moved (issue 4225).
34  *
35  * Only the VALID cells of the source are offered by default: a file's ghost cells are not
36  * guaranteed to agree with its valid data, and ParallelCopy intersects the grown source with
37  * the grown destination without any ordering guarantee between overlapping sources, so
38  * offering them can land stale values in valid cells. Pass src_ghosts = true for a field
39  * whose halo the checkpoint carries and whose ordinary restart has always restored it; the
40  * valid cells are then laid over the top in a second pass, so they win wherever they reach.
41  *
42  * @param[inout] dst destination, on the grids the run uses
43  * @param[in] mf_name the checkpoint MultiFab, as for VisMF::Read
44  * @param[in] scomp first component of the source to read
45  * @param[in] dcomp first component of dst to fill
46  * @param[in] ncomp number of components
47  * @param[in] dst_ghosts ghost cells of dst to fill (capped at what dst holds)
48  * @param[in] src_ghosts offer the file's ghost cells as well as its valid cells
49  * @param[in] period periodicity of the domain dst lives in
50  */
51 inline void
52 read_checkpoint_multifab (amrex::MultiFab& dst,
53  const std::string& mf_name,
54  int scomp, int dcomp, int ncomp,
55  const amrex::IntVect& dst_ghosts,
56  bool src_ghosts,
57  const amrex::Periodicity& period)
58 {
59  //
60  // Undefined on purpose: VisMF::Read defines it on the BoxArray the file records, which is
61  // the decomposition the checkpoint was written with and need not be this run's.
62  //
63  amrex::MultiFab src;
64  amrex::VisMF::Read(src, mf_name);
65 
66  //
67  // A file written with fewer ghost cells than the destination holds cannot fill more than
68  // it has, and the destination cannot take more than it holds.
69  //
70  const amrex::IntVect ng_dst = amrex::min(dst_ghosts, dst.nGrowVect());
71 
72  //
73  // The overwhelmingly common case: this level's grids ARE the grids the checkpoint was
74  // written on, so nothing has to move between boxes. Copy box to box, exactly as the
75  // reader did before the grids could differ, so that an ordinary restart stays
76  // byte-for-byte what it always was -- no periodic images, and no overlapping sources to
77  // be ambiguous about.
78  //
79  // The distribution still has to be matched: VisMF::Read gives the MultiFab it defines a
80  // DistributionMapping of its own, which is not this run's even when the BoxArray is.
81  // Redistribute is the box-to-box move for exactly that case.
82  //
83  if (src.boxArray() == dst.boxArray())
84  {
85  const amrex::IntVect ng_copy = src_ghosts ? amrex::min(ng_dst, src.nGrowVect())
86  : amrex::IntVect(0);
87 
88  if (src.DistributionMap() == dst.DistributionMap()) {
89  amrex::MultiFab::Copy(dst, src, scomp, dcomp, ncomp, ng_copy);
90  } else {
91  amrex::MultiFab aligned(src.boxArray(), dst.DistributionMap(), src.nComp(), src.nGrowVect());
92  aligned.Redistribute(src, 0, 0, src.nComp(), src.nGrowVect());
93  amrex::MultiFab::Copy(dst, aligned, scomp, dcomp, ncomp, ng_copy);
94  }
95  return;
96  }
97 
98  if (src_ghosts) {
99  //
100  // Two passes. The first offers the file's halo so that destination ghost cells OUTSIDE
101  // the domain -- which no valid cell can reach -- get the values the checkpoint recorded
102  // for them. But a file's halo is not guaranteed to agree with its valid data, and
103  // offering it alone would let a stale ghost cell land in a valid cell through a box
104  // overlap or a periodic image, with no ordering guarantee between overlapping sources.
105  // So the second pass copies the valid cells on top, and they win wherever they reach.
106  //
107  const amrex::IntVect ng_src = amrex::min(ng_dst, src.nGrowVect());
108  dst.ParallelCopy(src, scomp, dcomp, ncomp, ng_src, ng_dst, period);
109  dst.ParallelCopy(src, scomp, dcomp, ncomp, amrex::IntVect(0), ng_dst, period);
110  } else {
111  dst.ParallelCopy(src, scomp, dcomp, ncomp, amrex::IntVect(0), ng_dst, period);
112  }
113 }
114 
115 /**
116  * As read_checkpoint_multifab, for an integer field the checkpoint stores as a MultiFab,
117  * valid cells only. dst is (re)defined on ba/dm, which are the grids the run uses.
118  */
119 inline void
120 read_checkpoint_imultifab (amrex::iMultiFab& dst,
121  const amrex::BoxArray& ba,
122  const amrex::DistributionMapping& dm,
123  const std::string& mf_name,
124  const amrex::Periodicity& period)
125 {
126  amrex::MultiFab tmp(ba, dm, 1, 0);
127  read_checkpoint_multifab(tmp, mf_name, 0, 0, 1, amrex::IntVect(0), false, period);
128  dst = amrex::cast<amrex::iMultiFab>(tmp);
129 }
130 
131 } // namespace erf_checkpoint
132 
133 #endif
@ tmp
Definition: ERF_AdvanceWSM6.cpp:116
Definition: ERF_ReadCheckpointMF.H:12
void read_checkpoint_imultifab(amrex::iMultiFab &dst, const amrex::BoxArray &ba, const amrex::DistributionMapping &dm, const std::string &mf_name, const amrex::Periodicity &period)
Definition: ERF_ReadCheckpointMF.H:120
amrex::Periodicity lateral_periodicity(const amrex::Geometry &geom)
Definition: ERF_ReadCheckpointMF.H:20
void read_checkpoint_multifab(amrex::MultiFab &dst, const std::string &mf_name, int scomp, int dcomp, int ncomp, const amrex::IntVect &dst_ghosts, bool src_ghosts, const amrex::Periodicity &period)
Definition: ERF_ReadCheckpointMF.H:52