ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_SampleData.H
Go to the documentation of this file.
1 /**
2  * \file ERF_SampleData.H
3  */
4 #ifndef ERF_SAMPLEDATA_H
5 #define ERF_SAMPLEDATA_H
6 
7 #include <memory>
8 
9 #include <AMReX_ParmParse.H>
10 #include <AMReX_MultiFab.H>
11 #include <AMReX_MultiFabUtil.H>
12 #include <AMReX_PlotFileUtil.H>
13 
14 #include <ERF_IndexDefines.H>
15 #include <ERF_EOS.H>
16 #include <ERF_Container.H>
17 
18 #include <iostream>
19 
21 {
23  {
24  amrex::ParmParse pp("erf");
25 
26  bool has_line_idx = pp.contains("sample_line_lo") || pp.contains("sample_line_hi");
27  bool has_line_real = pp.contains("sample_line_lo_real") || pp.contains("sample_line_hi_real");
28  if (has_line_idx && has_line_real) {
29  amrex::Abort("Specify only one of erf.sample_line_lo/hi or erf.sample_line_lo_real/hi_real");
30  }
31 
32  // Count number of lo and hi points define the line
33  int n_line_lo = pp.countval("sample_line_lo") / AMREX_SPACEDIM;
34  int n_line_hi = pp.countval("sample_line_hi") / AMREX_SPACEDIM;
35  int n_line_lo_real = pp.countval("sample_line_lo_real") / AMREX_SPACEDIM;
36  int n_line_hi_real = pp.countval("sample_line_hi_real") / AMREX_SPACEDIM;
37  int n_line_dir = pp.countval("sample_line_dir");
38  if (has_line_idx) {
39  AMREX_ALWAYS_ASSERT( (n_line_lo==n_line_hi ) &&
40  (n_line_lo==n_line_dir) );
41  } else if (has_line_real) {
42  AMREX_ALWAYS_ASSERT( (n_line_lo_real==n_line_hi_real ) &&
43  (n_line_lo_real==n_line_dir) );
44  }
45 
46  // Parse the data
47  int nline = 0;
48  if (has_line_idx) {
49  nline = n_line_lo;
50  if (nline > 0) {
51  // Parse lo
52  amrex::Vector<int> idx_lo; idx_lo.resize(nline*AMREX_SPACEDIM);
53  amrex::Vector<amrex::IntVect> iv_lo; iv_lo.resize(nline);
54  pp.queryarr("sample_line_lo",idx_lo,0,nline*AMREX_SPACEDIM);
55  for (int i(0); i < nline; i++) {
56  amrex::IntVect iv(idx_lo[AMREX_SPACEDIM*i+0],
57  idx_lo[AMREX_SPACEDIM*i+1],
58  idx_lo[AMREX_SPACEDIM*i+2]);
59  iv_lo[i] = iv;
60  }
61 
62  // Parse hi
63  amrex::Vector<int> idx_hi; idx_hi.resize(nline*AMREX_SPACEDIM);
64  amrex::Vector<amrex::IntVect> iv_hi; iv_hi.resize(nline);
65  pp.queryarr("sample_line_hi",idx_hi,0,nline*AMREX_SPACEDIM);
66  for (int i(0); i < nline; i++) {
67  amrex::IntVect iv(idx_hi[AMREX_SPACEDIM*i+0],
68  idx_hi[AMREX_SPACEDIM*i+1],
69  idx_hi[AMREX_SPACEDIM*i+2]);
70  iv_hi[i] = iv;
71  }
72 
73  // Construct vector of bounding boxes
74  m_bnd_bx.resize(nline);
75  for (int i = 0; i < nline; i++){
76  amrex::Box lbx(iv_lo[i],iv_hi[i]);
77  m_bnd_bx[i] = lbx;
78  }
79  }
80  } else if (has_line_real) {
81  m_use_real_bx = true;
82  nline = n_line_lo_real;
83  if (nline > 0) {
84  // Parse lo
85  amrex::Vector<amrex::Real> real_lo; real_lo.resize(nline*AMREX_SPACEDIM);
86  amrex::Vector<amrex::Vector<amrex::Real>> rv_lo;
87  pp.queryarr("sample_line_lo_real",real_lo,0,nline*AMREX_SPACEDIM);
88  for (int i(0); i < nline; i++) {
89  amrex::Vector<amrex::Real> rv = {real_lo[AMREX_SPACEDIM*i+0],
90  real_lo[AMREX_SPACEDIM*i+1],
91  real_lo[AMREX_SPACEDIM*i+2]};
92  rv_lo.push_back(rv);
93  }
94 
95  // Parse hi
96  amrex::Vector<amrex::Real> real_hi; real_hi.resize(nline*AMREX_SPACEDIM);
97  amrex::Vector<amrex::Vector<amrex::Real>> rv_hi;
98  pp.queryarr("sample_line_hi_real",real_hi,0,nline*AMREX_SPACEDIM);
99  for (int i(0); i < nline; i++) {
100  amrex::Vector<amrex::Real> rv = {real_hi[AMREX_SPACEDIM*i+0],
101  real_hi[AMREX_SPACEDIM*i+1],
102  real_hi[AMREX_SPACEDIM*i+2]};
103  rv_hi.push_back(rv);
104  }
105 
106  // Construct vector of bounding real boxes
107  m_bnd_rbx.resize(nline);
108  for (int i = 0; i < nline; i++){
109  amrex::RealBox rbx(rv_lo[i].data(),rv_hi[i].data());
110  m_bnd_rbx[i] = rbx;
111  }
112 
113  // Construct vector of bounding boxes
114  m_bnd_bx.resize(nline);
115  }
116  }
117 
118  if (nline > 0) {
119  // Parse directionality
120  m_dir.resize(n_line_dir);
121  pp.queryarr("sample_line_dir",m_dir,0,n_line_dir);
122 
123  // Parse names
124  std::string name_base = "plt_line_";
125  m_name.resize(nline);
126  int n_names = pp.countval("sample_line_name");
127  if (n_names > 0) {
128  AMREX_ALWAYS_ASSERT( n_names==nline );
129  pp.queryarr("sample_line_name",m_name,0,n_names);
130  } else {
131  for (int iline(0); iline<nline; ++iline) {
132  m_name[iline] = amrex::Concatenate(name_base, iline , 5);
133  }
134  }
135 
136  // Allocate space for level indicator
137  m_lev.resize(n_line_dir,0);
138 
139  // Allocate space for MF pointers
140  m_ls_mf.resize(nline);
141 
142  // Get requested vars
143  if (pp.countval("line_sampling_vars") > 0) {
144  m_varnames.clear();
145  amrex::Vector<std::string> requested_vars;
146  pp.queryarr("line_sampling_vars",requested_vars);
147  amrex::Print() << "Selected line sampling vars :";
148  if (containerHasElement(requested_vars, "density")) {
149  m_varnames.push_back("density");
150  amrex::Print() << " " << "density";
151  }
152  if (containerHasElement(requested_vars, "x_velocity")) {
153  m_varnames.push_back("x_velocity");
154  amrex::Print() << " " << "x_velocity";
155  }
156  if (containerHasElement(requested_vars, "y_velocity")) {
157  m_varnames.push_back("y_velocity");
158  amrex::Print() << " " << "y_velocity";
159  }
160  if (containerHasElement(requested_vars, "z_velocity")) {
161  m_varnames.push_back("z_velocity");
162  amrex::Print() << " " << "z_velocity";
163  }
164  if (containerHasElement(requested_vars, "magvel")) {
165  m_varnames.push_back("magvel");
166  amrex::Print() << " " << "magvel";
167  }
168  if (containerHasElement(requested_vars, "theta")) {
169  m_varnames.push_back("theta");
170  amrex::Print() << " " << "theta";
171  }
172  if (containerHasElement(requested_vars, "qv")) {
173  m_varnames.push_back("qv");
174  amrex::Print() << " " << "qv";
175  }
176  if (containerHasElement(requested_vars, "qc")) {
177  m_varnames.push_back("qc");
178  amrex::Print() << " " << "qc";
179  }
180  if (containerHasElement(requested_vars, "pressure")) {
181  m_varnames.push_back("pressure");
182  amrex::Print() << " " << "pressure";
183  }
184  amrex::Print() << std::endl;
185  }
186 
187  // Write outputs to text files, one file per variable, with all
188  // times appended to the same file
189  pp.query("line_sampling_text_output",m_write_ascii);
190  if (m_write_ascii && amrex::ParallelDescriptor::IOProcessor()) {
191  int nvar = static_cast<int>(m_varnames.size());
192  m_datastream.resize(nline * nvar);
193  int i = 0;
194  for (int iline(0); iline<nline; ++iline) {
195  for (int ivar(0); ivar<nvar; ++ivar) {
196  std::string filename = m_name[iline] + "." + m_varnames[ivar];
197  m_datastream[i] = std::make_unique<std::fstream>();
198  m_datastream[i]->open(filename.c_str(),std::ios::out|std::ios::app);
199  if (!m_datastream[i]->good()) {
200  amrex::FileOpenFailed(filename);
201  }
202  i++;
203  }
204  }
205  }
206  }
207  }
208 
209  amrex::Box
210  getIndexBox (const amrex::RealBox& real_box,
211  const amrex::Geometry& geom) {
212  amrex::IntVect slice_lo, slice_hi;
213 
214  AMREX_D_TERM(slice_lo[0]=static_cast<int>(std::floor((real_box.lo(0) - geom.ProbLo(0))/geom.CellSize(0)));,
215  slice_lo[1]=static_cast<int>(std::floor((real_box.lo(1) - geom.ProbLo(1))/geom.CellSize(1)));,
216  slice_lo[2]=static_cast<int>(std::floor((real_box.lo(2) - geom.ProbLo(2))/geom.CellSize(2))););
217 
218  AMREX_D_TERM(slice_hi[0]=static_cast<int>(std::floor((real_box.hi(0) - geom.ProbLo(0))/geom.CellSize(0)));,
219  slice_hi[1]=static_cast<int>(std::floor((real_box.hi(1) - geom.ProbLo(1))/geom.CellSize(1)));,
220  slice_hi[2]=static_cast<int>(std::floor((real_box.hi(2) - geom.ProbLo(2))/geom.CellSize(2))););
221 
222  return amrex::Box(slice_lo, slice_hi) & geom.Domain();
223  }
224 
225  void
226  write_coords (amrex::Vector<std::unique_ptr<amrex::MultiFab> >& z_phys_cc,
227  amrex::Vector<amrex::Geometry>& geom)
228  {
229  if (!m_write_ascii) return;
230 
231  amrex::Print() << "Writing out line coordinates to text" << std::endl;
232 
233  for (int lev(0); lev < z_phys_cc.size(); ++lev) {
234  // Write one text file per level
235  std::ofstream outfile;
236  if (amrex::ParallelDescriptor::IOProcessor()) {
237  std::string fname = amrex::Concatenate("plt_line_lev", lev, 1);
238  fname += ".zcc";
239  outfile.open(fname);
240 
241  if (!outfile.is_open()) {
242  amrex::AllPrint() << "Could not open " << fname << std::endl;
243  }
244  }
245 
246  // Loop over each line
247  int nline = static_cast<int>(m_ls_mf.size());
248  for (int iline(0); iline<nline; ++iline) {
249  int dir = m_dir[iline];
250  amrex::Box bnd_bx = (m_use_real_bx)
251  ? getIndexBox(m_bnd_rbx[iline], geom[lev])
252  : m_bnd_bx[iline];
253  amrex::IntVect first_cell = bnd_bx.smallEnd();
254 
255  // Create multifab with "sampled" z_phys values
256  amrex::MultiFab line_coords_mf = get_line_data(
257  *z_phys_cc[lev], dir, first_cell, bnd_bx
258  );
259 
260  // Convert multifab to vector
261  amrex::Gpu::HostVector<amrex::Real> vec = sumToLine(
262  line_coords_mf, 0, 1, bnd_bx, dir
263  );
264 
265  // Append to file
266  if (amrex::ParallelDescriptor::IOProcessor()) {
267  for (const auto& zval : vec) {
268  outfile << " " << zval;
269  }
270  outfile << std::endl;
271  }
272  } // line loop
273 
274  outfile.close();
275  } // level loop
276  }
277 
278  void
279  get_sample_data (amrex::Vector<amrex::Geometry>& geom,
280  amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars_new)
281  {
282  int nlev = static_cast<int>(vars_new.size());
283  int nline = static_cast<int>(m_bnd_bx.size());
284  int ncomp = static_cast<int>(m_varnames.size());
285 
286  int qv_comp = -1;
287 
288  // Loop over each line
289  for (int iline(0); iline<nline; ++iline) {
290  int dir = m_dir[iline];
291 
292  // Search each level to get the finest data possible
293  for (int ilev(nlev-1); ilev>=0; --ilev) {
294  amrex::Box bnd_bx = (m_use_real_bx)
295  ? getIndexBox(m_bnd_rbx[iline], geom[ilev])
296  : m_bnd_bx[iline];
297  amrex::IntVect cell = bnd_bx.smallEnd();
298 
299  // Construct CC velocities
300  amrex::MultiFab mf_cc_vel;
301  auto ba = vars_new[ilev][Vars::cons].boxArray();
302  auto dm = vars_new[ilev][Vars::cons].DistributionMap();
303  mf_cc_vel.define(ba, dm, AMREX_SPACEDIM, amrex::IntVect(1,1,1));
304  average_face_to_cellcenter(mf_cc_vel,0,
305  amrex::Array<const amrex::MultiFab*,3>{&vars_new[ilev][Vars::xvel],
306  &vars_new[ilev][Vars::yvel],
307  &vars_new[ilev][Vars::zvel]});
308 
309  // Construct MultiFab holding requested variables
310  amrex::MultiFab mf_cc_data;
311  mf_cc_data.define(ba, dm, ncomp, 1);
312 
313  int mf_comp = 0;
314 
315  if (containerHasElement(m_varnames, "density")) {
316  amrex::MultiFab::Copy(mf_cc_data, vars_new[ilev][Vars::cons], Rho_comp, mf_comp, 1, 0);
317  mf_comp += 1;
318  }
319 
320  if (containerHasElement(m_varnames, "x_velocity")) {
321  amrex::MultiFab::Copy(mf_cc_data, mf_cc_vel, 0, mf_comp, 1, 0);
322  mf_comp += 1;
323  }
324  if (containerHasElement(m_varnames, "y_velocity")) {
325  amrex::MultiFab::Copy(mf_cc_data, mf_cc_vel, 1, mf_comp, 1, 0);
326  mf_comp += 1;
327  }
328  if (containerHasElement(m_varnames, "z_velocity")) {
329  amrex::MultiFab::Copy(mf_cc_data, mf_cc_vel, 2, mf_comp, 1, 0);
330  mf_comp += 1;
331  }
332 
333  if (containerHasElement(m_varnames, "magvel")) {
334 #ifdef _OPENMP
335 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
336 #endif
337  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
338  const amrex::Box& tbx = mfi.tilebox();
339  auto const& dfab = mf_cc_data.array(mfi);
340  auto const& vfab = mf_cc_vel.array(mfi);
341 
342  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
343  {
344  dfab(i,j,k,mf_comp) = std::sqrt(vfab(i,j,k,0)*vfab(i,j,k,0)
345  + vfab(i,j,k,1)*vfab(i,j,k,1)
346  + vfab(i,j,k,2)*vfab(i,j,k,2)) ;
347  });
348  }
349  mf_comp += 1;
350  }
351 
352  if (containerHasElement(m_varnames, "theta")) {
353 #ifdef _OPENMP
354 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
355 #endif
356  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
357  const amrex::Box& tbx = mfi.tilebox();
358  auto const& dfab = mf_cc_data.array(mfi);
359  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
360 
361  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
362  {
363  dfab(i,j,k,mf_comp) = cfab(i,j,k,RhoTheta_comp) / cfab(i,j,k,Rho_comp);
364  });
365  }
366  mf_comp += 1;
367  }
368 
369  if (containerHasElement(m_varnames, "qv")) {
370  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(vars_new[ilev][Vars::cons].nComp() > RhoQ1_comp,
371  "qv sampling requested but moisture components not present in state");
372  if (qv_comp >= 0) AMREX_ALWAYS_ASSERT(qv_comp == mf_comp);
373  qv_comp = mf_comp;
374 #ifdef _OPENMP
375 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
376 #endif
377  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
378  const amrex::Box& tbx = mfi.tilebox();
379  auto const& dfab = mf_cc_data.array(mfi);
380  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
381 
382  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
383  {
384  dfab(i,j,k,mf_comp) = cfab(i,j,k,RhoQ1_comp) / cfab(i,j,k,Rho_comp);
385  });
386  }
387  mf_comp += 1;
388  }
389  if (containerHasElement(m_varnames, "qc")) {
390  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(vars_new[ilev][Vars::cons].nComp() > RhoQ2_comp,
391  "qc sampling requested but moisture components not present in state");
392 #ifdef _OPENMP
393 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
394 #endif
395  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
396  const amrex::Box& tbx = mfi.tilebox();
397  auto const& dfab = mf_cc_data.array(mfi);
398  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
399 
400  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
401  {
402  dfab(i,j,k,mf_comp) = cfab(i,j,k,RhoQ2_comp) / cfab(i,j,k,Rho_comp);
403  });
404  }
405  mf_comp += 1;
406  }
407 
408  if (containerHasElement(m_varnames, "pressure")) {
409  if (vars_new[ilev][Vars::cons].nComp() > RhoQ1_comp) {
410  // moist pressure: use qv from dfab if already sampled, else compute inline
411 #ifdef _OPENMP
412 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
413 #endif
414  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
415  const amrex::Box& tbx = mfi.tilebox();
416  auto const& dfab = mf_cc_data.array(mfi);
417  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
418 
419  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
420  {
421  amrex::Real qv_val = (qv_comp >= 0) ? dfab(i,j,k,qv_comp)
422  : cfab(i,j,k,RhoQ1_comp) / cfab(i,j,k,Rho_comp);
423  dfab(i,j,k,mf_comp) = getPgivenRTh(cfab(i,j,k,RhoTheta_comp), qv_val);
424  });
425  }
426  } else {
427  // dry pressure
428 #ifdef _OPENMP
429 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
430 #endif
431  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
432  const amrex::Box& tbx = mfi.tilebox();
433  auto const& dfab = mf_cc_data.array(mfi);
434  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
435 
436  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
437  {
438  dfab(i,j,k,mf_comp) = getPgivenRTh(cfab(i,j,k,RhoTheta_comp));
439  });
440  }
441  }
442  mf_comp += 1;
443  }
444 
445  m_lev[iline] = ilev;
446  m_ls_mf[iline] = get_line_data(mf_cc_data, dir, cell, bnd_bx);
447 
448  // We can stop if we got the entire line
449  auto min_bnd_bx = m_ls_mf[iline].boxArray().minimalBox();
450  if (bnd_bx == min_bnd_bx) { break; }
451 
452  } // ilev
453 
454  // Fill bnd_bx if use_rbx
455  if (m_use_real_bx) {
456  m_bnd_bx[iline] = m_ls_mf[iline].boxArray().minimalBox();
457  }
458 
459  }// iline
460  }
461 
462  void
463  write_sample_data (amrex::Vector<double>& time,
464  amrex::Vector<int>& level_steps,
465  amrex::Vector<amrex::IntVect>& ref_ratio,
466  amrex::Vector<amrex::Geometry>& geom)
467  {
468  if (m_write_ascii) {
469  write_line_ascii(time);
470  } else {
471  write_line_plotfile(time, level_steps, ref_ratio, geom);
472  }
473  }
474 
475  void
476  write_line_ascii (amrex::Vector<double>& time)
477  {
478  // same as definitions in ERF.H
479  constexpr int datwidth = 14;
480  constexpr int datprecision = 6;
481  constexpr int timeprecision = 13;
482 
483  int nline = static_cast<int>(m_ls_mf.size());
484  int nvar = static_cast<int>(m_varnames.size());
485  for (int iline(0); iline<nline; ++iline) {
486  int dir = m_dir[iline];
487  int lev = m_lev[iline];
488  double m_time = time[lev];
489  amrex::Box m_dom = m_bnd_bx[iline];
490 
491  for (int ivar(0); ivar<nvar; ++ivar) {
492  // Convert multifab to vector
493  amrex::Gpu::HostVector<amrex::Real> vec = sumToLine(m_ls_mf[iline], ivar, 1, m_dom, dir);
494 
495  if (amrex::ParallelDescriptor::IOProcessor()) {
496  int ifile = iline*nvar + ivar;
497  std::ostream& fs = *m_datastream[ifile];
498  fs << std::setw(datwidth) << std::setprecision(timeprecision) << m_time
499  << std::setw(datwidth) << std::setprecision(datprecision);
500  for (const auto& val : vec) {
501  fs << " " << val;
502  }
503  fs << std::endl;
504  }
505  }
506  }
507  }
508 
509  void
510  write_line_plotfile (amrex::Vector<double>& time,
511  amrex::Vector<int>& level_steps,
512  amrex::Vector<amrex::IntVect>& ref_ratio,
513  amrex::Vector<amrex::Geometry>& geom)
514  {
515  int nline = static_cast<int>(m_ls_mf.size());
516  for (int iline(0); iline<nline; ++iline) {
517  // Data members that can be used as-is
518  int dir = m_dir[iline];
519  int lev = m_lev[iline];
520  double m_time = time[lev];
521  amrex::Vector<int> m_level_steps = {level_steps[lev]};
522  amrex::Vector<amrex::IntVect> m_ref_ratio = {ref_ratio[lev]};
523 
524  // Create modified geometry object corresponding to the line
525  auto plo = geom[lev].ProbLo();
526  auto dx = geom[lev].CellSize();
527  amrex::Vector<amrex::Geometry> m_geom; m_geom.resize(1);
528  amrex::Vector<int> is_per(AMREX_SPACEDIM,0);
529  amrex::Box m_dom = m_bnd_bx[iline];
530  amrex::RealBox m_rb;
531  for (int d(0); d<AMREX_SPACEDIM; ++d) {
532  amrex::Real offset = (d==dir) ? 0 : myhalf;
533  amrex::Real lo = plo[d] + ( m_dom.smallEnd(d) - offset ) * dx[d];
534  amrex::Real hi = plo[d] + ( m_dom.bigEnd(d) + offset ) * dx[d];
535 
536  m_rb.setLo(d,lo);
537  m_rb.setHi(d,hi);
538 
539  is_per[d] = geom[lev].isPeriodic(d);
540  }
541  m_geom[0].define(m_dom, &m_rb, geom[lev].Coord(), is_per.data());
542 
543  // Create plotfile name
544  std::string name_line = m_name[iline];
545  name_line += "_step_";
546  std::string plotfilename = amrex::Concatenate(name_line, m_level_steps[0], 5);
547 
548  // Get the data
549  amrex::Vector<const amrex::MultiFab*> mf = {&(m_ls_mf[iline])};
550 
551  // Write each line
552  WriteMultiLevelPlotfile(plotfilename, 1, mf,
553  m_varnames, m_geom, static_cast<amrex::Real>(m_time),
554  m_level_steps, m_ref_ratio);
555  }
556  }
557 
558  amrex::Vector<int> m_dir;
559  amrex::Vector<int> m_lev;
560  amrex::Vector<amrex::Box> m_bnd_bx;
561  amrex::Vector<amrex::RealBox> m_bnd_rbx;
562  amrex::Vector<amrex::MultiFab> m_ls_mf;
563  amrex::Vector<std::string> m_name;
564 
565  bool m_use_real_bx{false};
566  bool m_write_ascii{false};
567  amrex::Vector<std::string> m_varnames {"magvel","theta"};
568  amrex::Vector<std::unique_ptr<std::fstream> > m_datastream;
569 };
570 
571 
573 {
575  {
576  amrex::ParmParse pp("erf");
577 
578  // Count number of lo and hi points define the plane
579  int n_plane_lo = pp.countval("sample_plane_lo") / AMREX_SPACEDIM;
580  int n_plane_hi = pp.countval("sample_plane_hi") / AMREX_SPACEDIM;
581  int n_plane_dir = pp.countval("sample_plane_dir");
582  AMREX_ALWAYS_ASSERT( (n_plane_lo==n_plane_hi ) &&
583  (n_plane_lo==n_plane_dir) );
584 
585  // Parse the data
586  if (n_plane_lo > 0) {
587  // Parse lo
588  amrex::Vector<amrex::Real> r_lo; r_lo.resize(n_plane_lo*AMREX_SPACEDIM);
589  amrex::Vector<amrex::Vector<amrex::Real>> rv_lo;
590  pp.queryarr("sample_plane_lo",r_lo,0,n_plane_lo*AMREX_SPACEDIM);
591  for (int i(0); i < n_plane_lo; i++) {
592  amrex::Vector<amrex::Real> rv = {r_lo[AMREX_SPACEDIM*i+0],
593  r_lo[AMREX_SPACEDIM*i+1],
594  r_lo[AMREX_SPACEDIM*i+2]};
595  rv_lo.push_back(rv);
596  }
597 
598  // Parse hi
599  amrex::Vector<amrex::Real> r_hi; r_hi.resize(n_plane_hi*AMREX_SPACEDIM);
600  amrex::Vector<amrex::Vector<amrex::Real>> rv_hi;
601  pp.queryarr("sample_plane_hi",r_hi,0,n_plane_hi*AMREX_SPACEDIM);
602  for (int i(0); i < n_plane_hi; i++) {
603  amrex::Vector<amrex::Real> rv = {r_hi[AMREX_SPACEDIM*i+0],
604  r_hi[AMREX_SPACEDIM*i+1],
605  r_hi[AMREX_SPACEDIM*i+2]};
606  rv_hi.push_back(rv);
607  }
608 
609  // Construct vector of bounding real boxes
610  m_bnd_rbx.resize(n_plane_lo);
611  for (int i(0); i < n_plane_hi; i++){
612  amrex::RealBox rbx(rv_lo[i].data(),rv_hi[i].data());
613  m_bnd_rbx[i] = rbx;
614  }
615 
616  // Parse directionality
617  m_dir.resize(n_plane_dir);
618  pp.queryarr("sample_plane_dir",m_dir,0,n_plane_dir);
619 
620  // Parse names
621  std::string name_base = "plt_plane_";
622  m_name.resize(n_plane_lo);
623  int n_names = pp.countval("sample_plane_name");
624  if (n_names > 0) {
625  AMREX_ALWAYS_ASSERT( n_names==n_plane_lo );
626  pp.queryarr("sample_plane_name",m_name,0,n_names);
627  } else {
628  for (int iplane(0); iplane<n_plane_lo; ++iplane) {
629  m_name[iplane] = amrex::Concatenate(name_base, iplane , 5);
630  }
631  }
632 
633  // Optional cap on the finest level written (-1 => all intersecting levels)
634  pp.query("plane_sampling_max_level", m_max_level);
635 
636  // Allocate per-plane vectors of per-level MF pointers
637  m_ps_mf.resize(n_plane_lo);
638 
639  // Get requested vars
640  if (pp.countval("plane_sampling_vars") > 0) {
641  m_varnames.clear();
642  amrex::Vector<std::string> requested_vars;
643  pp.queryarr("plane_sampling_vars",requested_vars);
644  amrex::Print() << "Selected plane sampling vars :";
645  if (containerHasElement(requested_vars, "density")) {
646  m_varnames.push_back("density");
647  amrex::Print() << " " << "density";
648  }
649  if (containerHasElement(requested_vars, "x_velocity")) {
650  m_varnames.push_back("x_velocity");
651  amrex::Print() << " " << "x_velocity";
652  }
653  if (containerHasElement(requested_vars, "y_velocity")) {
654  m_varnames.push_back("y_velocity");
655  amrex::Print() << " " << "y_velocity";
656  }
657  if (containerHasElement(requested_vars, "z_velocity")) {
658  m_varnames.push_back("z_velocity");
659  amrex::Print() << " " << "z_velocity";
660  }
661  if (containerHasElement(requested_vars, "magvel")) {
662  m_varnames.push_back("magvel");
663  amrex::Print() << " " << "magvel";
664  }
665  if (containerHasElement(requested_vars, "theta")) {
666  m_varnames.push_back("theta");
667  amrex::Print() << " " << "theta";
668  }
669  if (containerHasElement(requested_vars, "qv")) {
670  m_varnames.push_back("qv");
671  amrex::Print() << " " << "qv";
672  }
673  if (containerHasElement(requested_vars, "qc")) {
674  m_varnames.push_back("qc");
675  amrex::Print() << " " << "qc";
676  }
677  if (containerHasElement(requested_vars, "pressure")) {
678  m_varnames.push_back("pressure");
679  amrex::Print() << " " << "pressure";
680  }
681  amrex::Print() << std::endl;
682  }
683  }
684  }
685 
686  // This must match what is in AMReX_MultiFabUtil.H
687  amrex::Box
688  getIndexBox (const amrex::RealBox& real_box,
689  const amrex::Geometry& geom) {
690  amrex::IntVect slice_lo, slice_hi;
691 
692  AMREX_D_TERM(slice_lo[0]=static_cast<int>(std::floor((real_box.lo(0) - geom.ProbLo(0))/geom.CellSize(0)));,
693  slice_lo[1]=static_cast<int>(std::floor((real_box.lo(1) - geom.ProbLo(1))/geom.CellSize(1)));,
694  slice_lo[2]=static_cast<int>(std::floor((real_box.lo(2) - geom.ProbLo(2))/geom.CellSize(2))););
695 
696  AMREX_D_TERM(slice_hi[0]=static_cast<int>(std::floor((real_box.hi(0) - geom.ProbLo(0))/geom.CellSize(0)));,
697  slice_hi[1]=static_cast<int>(std::floor((real_box.hi(1) - geom.ProbLo(1))/geom.CellSize(1)));,
698  slice_hi[2]=static_cast<int>(std::floor((real_box.hi(2) - geom.ProbLo(2))/geom.CellSize(2))););
699 
700  return amrex::Box(slice_lo, slice_hi) & geom.Domain();
701  }
702 
703  void
704  get_sample_data (amrex::Vector<amrex::Geometry>& geom,
705  amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars_new)
706  {
707  int nlev = static_cast<int>(vars_new.size());
708  int nplane = static_cast<int>(m_bnd_rbx.size());
709  int ncomp = static_cast<int>(m_varnames.size());
710  bool interpolate = true;
711 
712  int qv_comp = -1;
713 
714  // Loop over each plane
715  for (int iplane(0); iplane<nplane; ++iplane) {
716  int dir = m_dir[iplane];
717  amrex::RealBox bnd_rbx = m_bnd_rbx[iplane];
718  amrex::Real point = bnd_rbx.lo(dir);
719 
720  // Collect every level 0..lev_cap whose grids intersect the plane.
721  int lev_cap = (m_max_level >= 0 && m_max_level < nlev-1) ? m_max_level : nlev-1;
722  m_ps_mf[iplane].clear();
723 
724  for (int ilev(0); ilev<=lev_cap; ++ilev) {
725 
726  // Stop ascending once a level's grids no longer touch the flattened plane
727  {
728  amrex::Box plane_bx = getIndexBox(bnd_rbx, geom[ilev]);
729  int k_l = static_cast<int>(std::floor((point - geom[ilev].ProbLo(dir))
730  / geom[ilev].CellSize(dir)));
731  plane_bx.setSmall(dir, k_l); plane_bx.setBig(dir, k_l);
732  if (!vars_new[ilev][Vars::cons].boxArray().intersects(plane_bx)) { break; }
733  }
734 
735  // Construct CC velocities
736  amrex::MultiFab mf_cc_vel;
737  auto ba = vars_new[ilev][Vars::cons].boxArray();
738  auto dm = vars_new[ilev][Vars::cons].DistributionMap();
739  mf_cc_vel.define(ba, dm, AMREX_SPACEDIM, amrex::IntVect(1,1,1));
740  average_face_to_cellcenter(mf_cc_vel,0,
741  amrex::Array<const amrex::MultiFab*,3>{&vars_new[ilev][Vars::xvel],
742  &vars_new[ilev][Vars::yvel],
743  &vars_new[ilev][Vars::zvel]});
744 
745  // Construct MultiFab holding requested variables
746  amrex::MultiFab mf_cc_data;
747  mf_cc_data.define(ba, dm, ncomp, 1);
748 
749  int mf_comp = 0;
750 
751  if (containerHasElement(m_varnames, "density")) {
752  amrex::MultiFab::Copy(mf_cc_data, vars_new[ilev][Vars::cons], Rho_comp, mf_comp, 1, 0);
753  mf_comp += 1;
754  }
755 
756  if (containerHasElement(m_varnames, "x_velocity")) {
757  amrex::MultiFab::Copy(mf_cc_data, mf_cc_vel, 0, mf_comp, 1, 0);
758  mf_comp += 1;
759  }
760  if (containerHasElement(m_varnames, "y_velocity")) {
761  amrex::MultiFab::Copy(mf_cc_data, mf_cc_vel, 1, mf_comp, 1, 0);
762  mf_comp += 1;
763  }
764  if (containerHasElement(m_varnames, "z_velocity")) {
765  amrex::MultiFab::Copy(mf_cc_data, mf_cc_vel, 2, mf_comp, 1, 0);
766  mf_comp += 1;
767  }
768 
769  if (containerHasElement(m_varnames, "magvel")) {
770 #ifdef _OPENMP
771 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
772 #endif
773  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
774  const amrex::Box& tbx = mfi.tilebox();
775  auto const& dfab = mf_cc_data.array(mfi);
776  auto const& vfab = mf_cc_vel.array(mfi);
777 
778  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
779  {
780  dfab(i,j,k,mf_comp) = std::sqrt(vfab(i,j,k,0)*vfab(i,j,k,0)
781  + vfab(i,j,k,1)*vfab(i,j,k,1)
782  + vfab(i,j,k,2)*vfab(i,j,k,2));
783  });
784  }
785  mf_comp += 1;
786  }
787 
788  if (containerHasElement(m_varnames, "theta")) {
789 #ifdef _OPENMP
790 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
791 #endif
792  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
793  const amrex::Box& tbx = mfi.tilebox();
794  auto const& dfab = mf_cc_data.array(mfi);
795  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
796 
797  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
798  {
799  dfab(i,j,k,mf_comp) = cfab(i,j,k,RhoTheta_comp) / cfab(i,j,k,Rho_comp);
800  });
801  }
802  mf_comp += 1;
803  }
804 
805  if (containerHasElement(m_varnames, "qv")) {
806  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(vars_new[ilev][Vars::cons].nComp() > RhoQ1_comp,
807  "qv sampling requested but moisture components not present in state");
808  if (qv_comp >= 0) AMREX_ALWAYS_ASSERT(qv_comp == mf_comp);
809  qv_comp = mf_comp;
810 #ifdef _OPENMP
811 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
812 #endif
813  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
814  const amrex::Box& tbx = mfi.tilebox();
815  auto const& dfab = mf_cc_data.array(mfi);
816  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
817 
818  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
819  {
820  dfab(i,j,k,mf_comp) = cfab(i,j,k,RhoQ1_comp) / cfab(i,j,k,Rho_comp);
821  });
822  }
823  mf_comp += 1;
824  }
825  if (containerHasElement(m_varnames, "qc")) {
826  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(vars_new[ilev][Vars::cons].nComp() > RhoQ2_comp,
827  "qc sampling requested but moisture components not present in state");
828 #ifdef _OPENMP
829 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
830 #endif
831  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
832  const amrex::Box& tbx = mfi.tilebox();
833  auto const& dfab = mf_cc_data.array(mfi);
834  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
835 
836  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
837  {
838  dfab(i,j,k,mf_comp) = cfab(i,j,k,RhoQ2_comp) / cfab(i,j,k,Rho_comp);
839  });
840  }
841  mf_comp += 1;
842  }
843 
844  if (containerHasElement(m_varnames, "pressure")) {
845  if (vars_new[ilev][Vars::cons].nComp() > RhoQ1_comp) {
846  // moist pressure: use qv from dfab if already sampled, else compute inline
847 #ifdef _OPENMP
848 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
849 #endif
850  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
851  const amrex::Box& tbx = mfi.tilebox();
852  auto const& dfab = mf_cc_data.array(mfi);
853  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
854 
855  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
856  {
857  amrex::Real qv_val = (qv_comp >= 0) ? dfab(i,j,k,qv_comp)
858  : cfab(i,j,k,RhoQ1_comp) / cfab(i,j,k,Rho_comp);
859  dfab(i,j,k,mf_comp) = getPgivenRTh(cfab(i,j,k,RhoTheta_comp), qv_val);
860  });
861  }
862  } else {
863  // dry pressure
864 #ifdef _OPENMP
865 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
866 #endif
867  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
868  const amrex::Box& tbx = mfi.tilebox();
869  auto const& dfab = mf_cc_data.array(mfi);
870  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
871 
872  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
873  {
874  dfab(i,j,k,mf_comp) = getPgivenRTh(cfab(i,j,k,RhoTheta_comp));
875  });
876  }
877  }
878  mf_comp += 1;
879  }
880 
881  auto slice = get_slice_data(dir, point, mf_cc_data, geom[ilev],
882  0, ncomp, interpolate, bnd_rbx);
883 
884  // Defensive: an empty return means nothing was actually sampled.
885  if (!slice || slice->boxArray().size() == 0) { break; }
886 
887  // Broadcast the single sampled plane across 2^ilev cells in dir so
888  // every level shares an isotropic refinement ratio. The dir extent
889  // becomes [0, 2^ilev-1]; each cell holds the interpolated plane value
890  // replicated across the shared level-0 slab thickness.
891  const int rr_l = 1 << ilev;
892  const int k_slice = slice->boxArray().minimalBox().smallEnd(dir);
893  const int l_dir = dir;
894 
895  amrex::BoxList bl;
896  const amrex::BoxArray& slice_ba = slice->boxArray();
897  for (int ib(0); ib<static_cast<int>(slice_ba.size()); ++ib) {
898  amrex::Box b = slice_ba[ib];
899  b.setSmall(dir, 0);
900  b.setBig(dir, rr_l - 1);
901  bl.push_back(b);
902  }
903  amrex::BoxArray out_ba(std::move(bl));
904  auto out_mf = std::make_unique<amrex::MultiFab>(out_ba, slice->DistributionMap(),
905  ncomp, 0);
906 
907  for (amrex::MFIter mfi(*out_mf); mfi.isValid(); ++mfi) {
908  const amrex::Box& obx = mfi.validbox();
909  auto const& ofab = out_mf->array(mfi);
910  auto const& sfab = slice->array(mfi);
911  amrex::ParallelFor(obx, ncomp, [=] AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept
912  {
913  int si = i, sj = j, sk = k;
914  if (l_dir == 0) { si = k_slice; }
915  else if (l_dir == 1) { sj = k_slice; }
916  else { sk = k_slice; }
917  ofab(i,j,k,n) = sfab(si,sj,sk,n);
918  });
919  }
920 
921  m_ps_mf[iplane].push_back(std::move(out_mf));
922 
923  } // ilev
924  }// iplane
925  }
926 
927  void
928  write_sample_data (amrex::Vector<double>& time,
929  amrex::Vector<int>& level_steps,
930  amrex::Vector<amrex::IntVect>& ref_ratio,
931  amrex::Vector<amrex::Geometry>& geom)
932  {
933  amrex::ignore_unused(ref_ratio);
934  int nplane = m_ps_mf.size();
935  for (int iplane(0); iplane<nplane; ++iplane) {
936  int nlev_c = static_cast<int>(m_ps_mf[iplane].size());
937  if (nlev_c == 0) { continue; }
938 
939  int dir = m_dir[iplane];
940  amrex::RealBox bnd_rbx = m_bnd_rbx[iplane];
941  amrex::Real point = bnd_rbx.lo(dir);
942 
943  // One shared physical RealBox for every level: full in-plane extent of the
944  // requested plane, and a dir-slab of level-0 thickness centered on the plane.
945  // Level 0 supplies prob_lo/hi to the writer, so this object must be shared.
946  amrex::Real dx0 = geom[0].CellSize(dir);
947  amrex::RealBox shared_rbx = bnd_rbx;
948  shared_rbx.setLo(dir, point - myhalf*dx0);
949  shared_rbx.setHi(dir, point + myhalf*dx0);
950 
951  amrex::Vector<int> is_per(AMREX_SPACEDIM,0);
952  for (int d(0); d<AMREX_SPACEDIM; ++d) { is_per[d] = geom[0].isPeriodic(d); }
953 
954  // Build the index chain by refining the level-0 plane box so that
955  // Domain_l == refine(Domain_{l-1},2) holds exactly in every axis.
956  amrex::Box B0 = getIndexBox(bnd_rbx, geom[0]);
957 
958  amrex::Vector<const amrex::MultiFab*> mf(nlev_c);
959  amrex::Vector<amrex::Geometry> m_geom(nlev_c);
960  amrex::Vector<int> m_level_steps(nlev_c);
961  amrex::Vector<amrex::IntVect> m_ref_ratio(nlev_c-1, amrex::IntVect(2));
962 
963  for (int l(0); l<nlev_c; ++l) {
964  const int rr_l = 1 << l;
965 
966  // The nested plane plotfile stores a single scalar refinement
967  // ratio per level, so multi-level output requires factor-2
968  // isotropic refinement.
969  for (int d(0); d<AMREX_SPACEDIM; ++d) {
970  amrex::Real ratio = geom[0].CellSize(d) / geom[l].CellSize(d);
972  std::abs(ratio - static_cast<amrex::Real>(rr_l)) < amrex::Real(1.e-6) * rr_l,
973  "PlaneSampler multi-level output requires factor-2 isotropic refinement (amr.ref_ratio = 2 2 2)");
974  }
975 
976  amrex::Box domain_l = amrex::refine(B0, rr_l);
977  domain_l.setSmall(dir, 0);
978  domain_l.setBig(dir, rr_l - 1);
979 
980  mf[l] = m_ps_mf[iplane][l].get();
981  m_geom[l].define(domain_l, &shared_rbx, geom[l].Coord(), is_per.data());
982  m_level_steps[l] = level_steps[l];
983  AMREX_ASSERT(domain_l.contains(mf[l]->boxArray().minimalBox()));
984  }
985 
986  // Create plotfile name
987  std::string name_plane = m_name[iplane];
988  name_plane += "_step_";
989  std::string plotfilename = amrex::Concatenate(name_plane, m_level_steps[0], 5);
990 
991  // Write the nested multi-level plane plotfile
992  WriteMultiLevelPlotfile(plotfilename, nlev_c, mf,
993  m_varnames, m_geom, static_cast<amrex::Real>(time[0]),
994  m_level_steps, m_ref_ratio);
995  } // iplane
996  }
997 
998  int m_max_level = -1;
999  amrex::Vector<int> m_dir;
1000  amrex::Vector<amrex::RealBox> m_bnd_rbx;
1001  amrex::Vector<amrex::Vector<std::unique_ptr<amrex::MultiFab>>> m_ps_mf;
1002  amrex::Vector<std::string> m_name;
1003 
1004  amrex::Vector<std::string> m_varnames {"magvel","theta"};
1005 };
1006 #endif
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13
bool containerHasElement(const V &iterable, const T &query)
Definition: ERF_Container.H:5
Coord
Coordinate-axis selector.
Definition: ERF_DataStruct.H:143
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:81
struct @28 out
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:43
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
ParmParse pp("prob")
const Real dx
Definition: ERF_InitCustomPert_ABL.H:23
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
ParallelFor(fab_box, [=] AMREX_GPU_DEVICE(int i, int j, int k) { qrcuten_arr(i, j, k)=Real(0);qscuten_arr(i, j, k)=Real(0);qicuten_arr(i, j, k)=Real(0);})
AMREX_FORCE_INLINE IntVect offset(const int face_dir, const int normal)
Definition: ERF_ReadBndryPlanes.cpp:31
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ fs
Definition: ERF_AdvanceMorrison.cpp:122
@ xvel
Definition: ERF_IndexDefines.H:177
@ cons
Definition: ERF_IndexDefines.H:176
@ zvel
Definition: ERF_IndexDefines.H:179
@ yvel
Definition: ERF_IndexDefines.H:178
Definition: ERF_SampleData.H:21
void write_line_plotfile(amrex::Vector< double > &time, amrex::Vector< int > &level_steps, amrex::Vector< amrex::IntVect > &ref_ratio, amrex::Vector< amrex::Geometry > &geom)
Definition: ERF_SampleData.H:510
amrex::Vector< std::string > m_varnames
Definition: ERF_SampleData.H:567
amrex::Vector< amrex::MultiFab > m_ls_mf
Definition: ERF_SampleData.H:562
void write_coords(amrex::Vector< std::unique_ptr< amrex::MultiFab > > &z_phys_cc, amrex::Vector< amrex::Geometry > &geom)
Definition: ERF_SampleData.H:226
void write_sample_data(amrex::Vector< double > &time, amrex::Vector< int > &level_steps, amrex::Vector< amrex::IntVect > &ref_ratio, amrex::Vector< amrex::Geometry > &geom)
Definition: ERF_SampleData.H:463
amrex::Vector< std::unique_ptr< std::fstream > > m_datastream
Definition: ERF_SampleData.H:568
bool m_use_real_bx
Definition: ERF_SampleData.H:565
void write_line_ascii(amrex::Vector< double > &time)
Definition: ERF_SampleData.H:476
amrex::Vector< int > m_dir
Definition: ERF_SampleData.H:558
amrex::Vector< std::string > m_name
Definition: ERF_SampleData.H:563
LineSampler()
Definition: ERF_SampleData.H:22
amrex::Vector< amrex::Box > m_bnd_bx
Definition: ERF_SampleData.H:560
void get_sample_data(amrex::Vector< amrex::Geometry > &geom, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars_new)
Definition: ERF_SampleData.H:279
amrex::Box getIndexBox(const amrex::RealBox &real_box, const amrex::Geometry &geom)
Definition: ERF_SampleData.H:210
bool m_write_ascii
Definition: ERF_SampleData.H:566
amrex::Vector< amrex::RealBox > m_bnd_rbx
Definition: ERF_SampleData.H:561
amrex::Vector< int > m_lev
Definition: ERF_SampleData.H:559
Definition: ERF_SampleData.H:573
amrex::Vector< int > m_dir
Definition: ERF_SampleData.H:999
amrex::Box getIndexBox(const amrex::RealBox &real_box, const amrex::Geometry &geom)
Definition: ERF_SampleData.H:688
void write_sample_data(amrex::Vector< double > &time, amrex::Vector< int > &level_steps, amrex::Vector< amrex::IntVect > &ref_ratio, amrex::Vector< amrex::Geometry > &geom)
Definition: ERF_SampleData.H:928
int m_max_level
Definition: ERF_SampleData.H:998
amrex::Vector< std::string > m_name
Definition: ERF_SampleData.H:1002
amrex::Vector< amrex::Vector< std::unique_ptr< amrex::MultiFab > > > m_ps_mf
Definition: ERF_SampleData.H:1001
amrex::Vector< amrex::RealBox > m_bnd_rbx
Definition: ERF_SampleData.H:1000
PlaneSampler()
Definition: ERF_SampleData.H:574
amrex::Vector< std::string > m_varnames
Definition: ERF_SampleData.H:1004
void get_sample_data(amrex::Vector< amrex::Geometry > &geom, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars_new)
Definition: ERF_SampleData.H:704