ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
LineSampler Struct Reference

#include <ERF_SampleData.H>

Collaboration diagram for LineSampler:

Public Member Functions

 LineSampler ()
 
amrex::Box getIndexBox (const amrex::RealBox &real_box, const amrex::Geometry &geom)
 
void write_coords (amrex::Vector< std::unique_ptr< amrex::MultiFab > > &z_phys_cc, amrex::Vector< amrex::Geometry > &geom)
 
void get_sample_data (amrex::Vector< amrex::Geometry > &geom, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars_new, const amrex::Vector< amrex::MultiFab * > &tau13_lev={}, const amrex::Vector< amrex::MultiFab * > &tau23_lev={}, const amrex::Vector< amrex::MultiFab * > &hfx3_lev={}, const amrex::Vector< int > &prognostic_tke_available={})
 
void write_sample_data (amrex::Vector< double > &time, amrex::Vector< int > &level_steps, amrex::Vector< amrex::IntVect > &ref_ratio, amrex::Vector< amrex::Geometry > &geom)
 
void write_line_ascii (amrex::Vector< double > &time)
 
void write_line_plotfile (amrex::Vector< double > &time, amrex::Vector< int > &level_steps, amrex::Vector< amrex::IntVect > &ref_ratio, amrex::Vector< amrex::Geometry > &geom)
 

Public Attributes

amrex::Vector< int > m_dir
 
amrex::Vector< int > m_lev
 
amrex::Vector< amrex::Box > m_bnd_bx
 
amrex::Vector< amrex::RealBox > m_bnd_rbx
 
amrex::Vector< amrex::MultiFab > m_ls_mf
 
amrex::Vector< std::string > m_name
 
bool m_use_real_bx {false}
 
bool m_write_ascii {false}
 
amrex::Vector< std::string > m_varnames {"magvel","theta"}
 
amrex::Vector< std::unique_ptr< std::fstream > > m_datastream
 

Constructor & Destructor Documentation

◆ LineSampler()

LineSampler::LineSampler ( )
inline
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  if (containerHasElement(requested_vars, "sgs_tke")) {
185  m_varnames.push_back("sgs_tke");
186  amrex::Print() << " " << "sgs_tke";
187  }
188  if (containerHasElement(requested_vars, "sgs_tau13")) {
189  m_varnames.push_back("sgs_tau13");
190  amrex::Print() << " " << "sgs_tau13";
191  }
192  if (containerHasElement(requested_vars, "sgs_tau23")) {
193  m_varnames.push_back("sgs_tau23");
194  amrex::Print() << " " << "sgs_tau23";
195  }
196  if (containerHasElement(requested_vars, "sgs_hfx3")) {
197  m_varnames.push_back("sgs_hfx3");
198  amrex::Print() << " " << "sgs_hfx3";
199  }
200  amrex::Print() << std::endl;
201  }
202 
203  // Write outputs to text files, one file per variable, with all
204  // times appended to the same file
205  pp.queryAdd("line_sampling_text_output",m_write_ascii);
206  if (m_write_ascii && amrex::ParallelDescriptor::IOProcessor()) {
207  int nvar = static_cast<int>(m_varnames.size());
208  m_datastream.resize(nline * nvar);
209  int i = 0;
210  for (int iline(0); iline<nline; ++iline) {
211  for (int ivar(0); ivar<nvar; ++ivar) {
212  std::string filename = m_name[iline] + "." + m_varnames[ivar];
213  m_datastream[i] = std::make_unique<std::fstream>();
214  m_datastream[i]->open(filename.c_str(),std::ios::out|std::ios::app);
215  if (!m_datastream[i]->good()) {
216  amrex::FileOpenFailed(filename);
217  }
218  i++;
219  }
220  }
221  }
222  }
223  }
bool containerHasElement(const V &iterable, const T &query)
Definition: ERF_Container.H:5
ParmParse pp("prob")
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
amrex::Vector< std::string > m_varnames
Definition: ERF_SampleData.H:676
amrex::Vector< amrex::MultiFab > m_ls_mf
Definition: ERF_SampleData.H:671
amrex::Vector< std::unique_ptr< std::fstream > > m_datastream
Definition: ERF_SampleData.H:677
bool m_use_real_bx
Definition: ERF_SampleData.H:674
amrex::Vector< int > m_dir
Definition: ERF_SampleData.H:667
amrex::Vector< std::string > m_name
Definition: ERF_SampleData.H:672
amrex::Vector< amrex::Box > m_bnd_bx
Definition: ERF_SampleData.H:669
bool m_write_ascii
Definition: ERF_SampleData.H:675
amrex::Vector< amrex::RealBox > m_bnd_rbx
Definition: ERF_SampleData.H:670
amrex::Vector< int > m_lev
Definition: ERF_SampleData.H:668
Here is the call graph for this function:

Member Function Documentation

◆ get_sample_data()

void LineSampler::get_sample_data ( amrex::Vector< amrex::Geometry > &  geom,
amrex::Vector< amrex::Vector< amrex::MultiFab >> &  vars_new,
const amrex::Vector< amrex::MultiFab * > &  tau13_lev = {},
const amrex::Vector< amrex::MultiFab * > &  tau23_lev = {},
const amrex::Vector< amrex::MultiFab * > &  hfx3_lev = {},
const amrex::Vector< int > &  prognostic_tke_available = {} 
)
inline
297  {},
298  const amrex::Vector<amrex::MultiFab*>& tau23_lev = {},
299  const amrex::Vector<amrex::MultiFab*>& hfx3_lev = {},
300  const amrex::Vector<int>& prognostic_tke_available = {})
301  {
302  int nlev = static_cast<int>(vars_new.size());
303  int nline = static_cast<int>(m_bnd_bx.size());
304  int ncomp = static_cast<int>(m_varnames.size());
305 
306  int qv_comp = -1;
307 
308  // Loop over each line
309  for (int iline(0); iline<nline; ++iline) {
310  int dir = m_dir[iline];
311 
312  // Search each level to get the finest data possible
313  for (int ilev(nlev-1); ilev>=0; --ilev) {
314  amrex::Box bnd_bx = (m_use_real_bx)
315  ? getIndexBox(m_bnd_rbx[iline], geom[ilev])
316  : m_bnd_bx[iline];
317  amrex::IntVect cell = bnd_bx.smallEnd();
318 
319  // Construct CC velocities
320  amrex::MultiFab mf_cc_vel;
321  auto ba = vars_new[ilev][Vars::cons].boxArray();
322  auto dm = vars_new[ilev][Vars::cons].DistributionMap();
323  mf_cc_vel.define(ba, dm, AMREX_SPACEDIM, amrex::IntVect(1,1,1));
324  average_face_to_cellcenter(mf_cc_vel,0,
325  amrex::Array<const amrex::MultiFab*,3>{&vars_new[ilev][Vars::xvel],
326  &vars_new[ilev][Vars::yvel],
327  &vars_new[ilev][Vars::zvel]});
328 
329  // Construct MultiFab holding requested variables
330  amrex::MultiFab mf_cc_data;
331  mf_cc_data.define(ba, dm, ncomp, 1);
332 
333  int mf_comp = 0;
334 
335  if (containerHasElement(m_varnames, "density")) {
336  amrex::MultiFab::Copy(mf_cc_data, vars_new[ilev][Vars::cons], Rho_comp, mf_comp, 1, 0);
337  mf_comp += 1;
338  }
339 
340  if (containerHasElement(m_varnames, "x_velocity")) {
341  amrex::MultiFab::Copy(mf_cc_data, mf_cc_vel, 0, mf_comp, 1, 0);
342  mf_comp += 1;
343  }
344  if (containerHasElement(m_varnames, "y_velocity")) {
345  amrex::MultiFab::Copy(mf_cc_data, mf_cc_vel, 1, mf_comp, 1, 0);
346  mf_comp += 1;
347  }
348  if (containerHasElement(m_varnames, "z_velocity")) {
349  amrex::MultiFab::Copy(mf_cc_data, mf_cc_vel, 2, mf_comp, 1, 0);
350  mf_comp += 1;
351  }
352 
353  if (containerHasElement(m_varnames, "magvel")) {
354 #ifdef _OPENMP
355 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
356 #endif
357  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
358  const amrex::Box& tbx = mfi.tilebox();
359  auto const& dfab = mf_cc_data.array(mfi);
360  auto const& vfab = mf_cc_vel.array(mfi);
361 
362  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
363  {
364  dfab(i,j,k,mf_comp) = std::sqrt(vfab(i,j,k,0)*vfab(i,j,k,0)
365  + vfab(i,j,k,1)*vfab(i,j,k,1)
366  + vfab(i,j,k,2)*vfab(i,j,k,2)) ;
367  });
368  }
369  mf_comp += 1;
370  }
371 
372  if (containerHasElement(m_varnames, "theta")) {
373 #ifdef _OPENMP
374 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
375 #endif
376  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
377  const amrex::Box& tbx = mfi.tilebox();
378  auto const& dfab = mf_cc_data.array(mfi);
379  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
380 
381  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
382  {
383  dfab(i,j,k,mf_comp) = cfab(i,j,k,RhoTheta_comp) / cfab(i,j,k,Rho_comp);
384  });
385  }
386  mf_comp += 1;
387  }
388 
389  if (containerHasElement(m_varnames, "qv")) {
390  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(vars_new[ilev][Vars::cons].nComp() > RhoQ1_comp,
391  "qv sampling requested but moisture components not present in state");
392  if (qv_comp >= 0) AMREX_ALWAYS_ASSERT(qv_comp == mf_comp);
393  qv_comp = mf_comp;
394 #ifdef _OPENMP
395 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
396 #endif
397  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
398  const amrex::Box& tbx = mfi.tilebox();
399  auto const& dfab = mf_cc_data.array(mfi);
400  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
401 
402  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
403  {
404  dfab(i,j,k,mf_comp) = cfab(i,j,k,RhoQ1_comp) / cfab(i,j,k,Rho_comp);
405  });
406  }
407  mf_comp += 1;
408  }
409  if (containerHasElement(m_varnames, "qc")) {
410  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(vars_new[ilev][Vars::cons].nComp() > RhoQ2_comp,
411  "qc sampling requested but moisture components not present in state");
412 #ifdef _OPENMP
413 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
414 #endif
415  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
416  const amrex::Box& tbx = mfi.tilebox();
417  auto const& dfab = mf_cc_data.array(mfi);
418  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
419 
420  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
421  {
422  dfab(i,j,k,mf_comp) = cfab(i,j,k,RhoQ2_comp) / cfab(i,j,k,Rho_comp);
423  });
424  }
425  mf_comp += 1;
426  }
427 
428  if (containerHasElement(m_varnames, "pressure")) {
429  if (vars_new[ilev][Vars::cons].nComp() > RhoQ1_comp) {
430  // moist pressure: use qv from dfab if already sampled, else compute inline
431 #ifdef _OPENMP
432 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
433 #endif
434  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
435  const amrex::Box& tbx = mfi.tilebox();
436  auto const& dfab = mf_cc_data.array(mfi);
437  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
438 
439  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
440  {
441  amrex::Real qv_val = (qv_comp >= 0) ? dfab(i,j,k,qv_comp)
442  : cfab(i,j,k,RhoQ1_comp) / cfab(i,j,k,Rho_comp);
443  dfab(i,j,k,mf_comp) = getPgivenRTh(cfab(i,j,k,RhoTheta_comp), qv_val);
444  });
445  }
446  } else {
447  // dry pressure
448 #ifdef _OPENMP
449 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
450 #endif
451  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
452  const amrex::Box& tbx = mfi.tilebox();
453  auto const& dfab = mf_cc_data.array(mfi);
454  auto const& cfab = vars_new[ilev][Vars::cons].array(mfi);
455 
456  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
457  {
458  dfab(i,j,k,mf_comp) = getPgivenRTh(cfab(i,j,k,RhoTheta_comp));
459  });
460  }
461  }
462  mf_comp += 1;
463  }
464 
465  if (containerHasElement(m_varnames, "sgs_tke")) {
466  const bool tke_available =
467  ilev < static_cast<int>(prognostic_tke_available.size()) &&
468  prognostic_tke_available[ilev] != 0;
469  if (!tke_available) {
470  mf_cc_data.setVal(amrex::Real(0.0), mf_comp, 1, 0);
471  } else {
472 #ifdef _OPENMP
473 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
474 #endif
475  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
476  const amrex::Box& tbx = mfi.tilebox();
477  const auto& out = mf_cc_data.array(mfi);
478  const auto& state = vars_new[ilev][Vars::cons].const_array(mfi);
479  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
480  out(i,j,k,mf_comp) = state(i,j,k,RhoKE_comp) / state(i,j,k,Rho_comp);
481  });
482  }
483  }
484  mf_comp += 1;
485  }
486 
487  if (containerHasElement(m_varnames, "sgs_tau13")) {
488  amrex::MultiFab* tau13 = ilev < static_cast<int>(tau13_lev.size())
489  ? tau13_lev[ilev] : nullptr;
490  if (tau13 != nullptr) {
491 #ifdef _OPENMP
492 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
493 #endif
494  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
495  const amrex::Box& tbx = mfi.tilebox();
496  const auto& out = mf_cc_data.array(mfi);
497  const auto& tau = tau13->const_array(mfi);
498  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
499  out(i,j,k,mf_comp) = amrex::Real(0.25) *
500  (tau(i,j,k) + tau(i+1,j,k) +
501  tau(i,j,k+1) + tau(i+1,j,k+1));
502  });
503  }
504  } else {
505  mf_cc_data.setVal(0.0, mf_comp, 1, 0);
506  }
507  mf_comp += 1;
508  }
509 
510  if (containerHasElement(m_varnames, "sgs_tau23")) {
511  amrex::MultiFab* tau23 = ilev < static_cast<int>(tau23_lev.size())
512  ? tau23_lev[ilev] : nullptr;
513  if (tau23 != nullptr) {
514 #ifdef _OPENMP
515 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
516 #endif
517  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
518  const amrex::Box& tbx = mfi.tilebox();
519  const auto& out = mf_cc_data.array(mfi);
520  const auto& tau = tau23->const_array(mfi);
521  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
522  out(i,j,k,mf_comp) = amrex::Real(0.25) *
523  (tau(i,j,k) + tau(i,j+1,k) +
524  tau(i,j,k+1) + tau(i,j+1,k+1));
525  });
526  }
527  } else {
528  mf_cc_data.setVal(0.0, mf_comp, 1, 0);
529  }
530  mf_comp += 1;
531  }
532 
533  if (containerHasElement(m_varnames, "sgs_hfx3")) {
534  amrex::MultiFab* hfx3 = ilev < static_cast<int>(hfx3_lev.size())
535  ? hfx3_lev[ilev] : nullptr;
536  if (hfx3 != nullptr) {
537 #ifdef _OPENMP
538 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
539 #endif
540  for (amrex::MFIter mfi(mf_cc_data, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
541  const amrex::Box& tbx = mfi.tilebox();
542  const auto& out = mf_cc_data.array(mfi);
543  const auto& hfx = hfx3->const_array(mfi);
544  amrex::ParallelFor(tbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
545  out(i,j,k,mf_comp) = amrex::Real(0.5) * (hfx(i,j,k) + hfx(i,j,k+1));
546  });
547  }
548  } else {
549  mf_cc_data.setVal(0.0, mf_comp, 1, 0);
550  }
551  mf_comp += 1;
552  }
553 
554  m_lev[iline] = ilev;
555  m_ls_mf[iline] = get_line_data(mf_cc_data, dir, cell, bnd_bx);
556 
557  // We can stop if we got the entire line
558  auto min_bnd_bx = m_ls_mf[iline].boxArray().minimalBox();
559  if (bnd_bx == min_bnd_bx) { break; }
560 
561  } // ilev
562 
563  // Fill bnd_bx if use_rbx
564  if (m_use_real_bx) {
565  m_bnd_bx[iline] = m_ls_mf[iline].boxArray().minimalBox();
566  }
567 
568  }// iline
569  }
@ tau23
Definition: ERF_DataStruct.H:39
@ tau13
Definition: ERF_DataStruct.H:39
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
#define Rho_comp
Definition: ERF_IndexDefines.H:39
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:40
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:46
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:45
#define RhoKE_comp
Definition: ERF_IndexDefines.H:41
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::Real Real
Definition: ERF_ShocInterface.H:19
@ xvel
Definition: ERF_IndexDefines.H:215
@ cons
Definition: ERF_IndexDefines.H:214
@ zvel
Definition: ERF_IndexDefines.H:217
@ yvel
Definition: ERF_IndexDefines.H:216
amrex::Box getIndexBox(const amrex::RealBox &real_box, const amrex::Geometry &geom)
Definition: ERF_SampleData.H:226

◆ getIndexBox()

amrex::Box LineSampler::getIndexBox ( const amrex::RealBox &  real_box,
const amrex::Geometry &  geom 
)
inline
227  {
228  amrex::IntVect slice_lo, slice_hi;
229 
230  AMREX_D_TERM(slice_lo[0]=static_cast<int>(std::floor((real_box.lo(0) - geom.ProbLo(0))/geom.CellSize(0)));,
231  slice_lo[1]=static_cast<int>(std::floor((real_box.lo(1) - geom.ProbLo(1))/geom.CellSize(1)));,
232  slice_lo[2]=static_cast<int>(std::floor((real_box.lo(2) - geom.ProbLo(2))/geom.CellSize(2))););
233 
234  AMREX_D_TERM(slice_hi[0]=static_cast<int>(std::floor((real_box.hi(0) - geom.ProbLo(0))/geom.CellSize(0)));,
235  slice_hi[1]=static_cast<int>(std::floor((real_box.hi(1) - geom.ProbLo(1))/geom.CellSize(1)));,
236  slice_hi[2]=static_cast<int>(std::floor((real_box.hi(2) - geom.ProbLo(2))/geom.CellSize(2))););
237 
238  return amrex::Box(slice_lo, slice_hi) & geom.Domain();
239  }

Referenced by write_coords().

Here is the caller graph for this function:

◆ write_coords()

void LineSampler::write_coords ( amrex::Vector< std::unique_ptr< amrex::MultiFab > > &  z_phys_cc,
amrex::Vector< amrex::Geometry > &  geom 
)
inline
244  {
245  if (!m_write_ascii) return;
246 
247  amrex::Print() << "Writing out line coordinates to text" << std::endl;
248 
249  for (int lev(0); lev < z_phys_cc.size(); ++lev) {
250  // Write one text file per level
251  std::ofstream outfile;
252  if (amrex::ParallelDescriptor::IOProcessor()) {
253  std::string fname = amrex::Concatenate("plt_line_lev", lev, 1);
254  fname += ".zcc";
255  outfile.open(fname);
256 
257  if (!outfile.is_open()) {
258  amrex::AllPrint() << "Could not open " << fname << std::endl;
259  }
260  }
261 
262  // Loop over each line
263  int nline = static_cast<int>(m_ls_mf.size());
264  for (int iline(0); iline<nline; ++iline) {
265  int dir = m_dir[iline];
266  amrex::Box bnd_bx = (m_use_real_bx)
267  ? getIndexBox(m_bnd_rbx[iline], geom[lev])
268  : m_bnd_bx[iline];
269  amrex::IntVect first_cell = bnd_bx.smallEnd();
270 
271  // Create multifab with "sampled" z_phys values
272  amrex::MultiFab line_coords_mf = get_line_data(
273  *z_phys_cc[lev], dir, first_cell, bnd_bx
274  );
275 
276  // Convert multifab to vector
277  amrex::Gpu::HostVector<amrex::Real> vec = sumToLine(
278  line_coords_mf, 0, 1, bnd_bx, dir
279  );
280 
281  // Append to file
282  if (amrex::ParallelDescriptor::IOProcessor()) {
283  for (const auto& zval : vec) {
284  outfile << " " << zval;
285  }
286  outfile << std::endl;
287  }
288  } // line loop
289 
290  outfile.close();
291  } // level loop
292  }
Here is the call graph for this function:

◆ write_line_ascii()

void LineSampler::write_line_ascii ( amrex::Vector< double > &  time)
inline
586  {
587  // same as definitions in ERF.H
588  constexpr int datwidth = 14;
589  constexpr int datprecision = 6;
590  constexpr int timeprecision = 13;
591 
592  int nline = static_cast<int>(m_ls_mf.size());
593  int nvar = static_cast<int>(m_varnames.size());
594  for (int iline(0); iline<nline; ++iline) {
595  int dir = m_dir[iline];
596  int lev = m_lev[iline];
597  double m_time = time[lev];
598  amrex::Box m_dom = m_bnd_bx[iline];
599 
600  for (int ivar(0); ivar<nvar; ++ivar) {
601  // Convert multifab to vector
602  amrex::Gpu::HostVector<amrex::Real> vec = sumToLine(m_ls_mf[iline], ivar, 1, m_dom, dir);
603 
604  if (amrex::ParallelDescriptor::IOProcessor()) {
605  int ifile = iline*nvar + ivar;
606  std::ostream& fs = *m_datastream[ifile];
607  fs << std::setw(datwidth) << std::setprecision(timeprecision) << m_time
608  << std::setw(datwidth) << std::setprecision(datprecision);
609  for (const auto& val : vec) {
610  fs << " " << val;
611  }
612  fs << std::endl;
613  }
614  }
615  }
616  }
@ fs
Definition: ERF_AdvanceMorrison.cpp:122

Referenced by write_sample_data().

Here is the caller graph for this function:

◆ write_line_plotfile()

void LineSampler::write_line_plotfile ( amrex::Vector< double > &  time,
amrex::Vector< int > &  level_steps,
amrex::Vector< amrex::IntVect > &  ref_ratio,
amrex::Vector< amrex::Geometry > &  geom 
)
inline
623  {
624  int nline = static_cast<int>(m_ls_mf.size());
625  for (int iline(0); iline<nline; ++iline) {
626  // Data members that can be used as-is
627  int dir = m_dir[iline];
628  int lev = m_lev[iline];
629  double m_time = time[lev];
630  amrex::Vector<int> m_level_steps = {level_steps[lev]};
631  amrex::Vector<amrex::IntVect> m_ref_ratio = {ref_ratio[lev]};
632 
633  // Create modified geometry object corresponding to the line
634  auto plo = geom[lev].ProbLo();
635  auto dx = geom[lev].CellSize();
636  amrex::Vector<amrex::Geometry> m_geom; m_geom.resize(1);
637  amrex::Vector<int> is_per(AMREX_SPACEDIM,0);
638  amrex::Box m_dom = m_bnd_bx[iline];
639  amrex::RealBox m_rb;
640  for (int d(0); d<AMREX_SPACEDIM; ++d) {
641  amrex::Real offset = (d==dir) ? 0 : myhalf;
642  amrex::Real lo = plo[d] + ( m_dom.smallEnd(d) - offset ) * dx[d];
643  amrex::Real hi = plo[d] + ( m_dom.bigEnd(d) + offset ) * dx[d];
644 
645  m_rb.setLo(d,lo);
646  m_rb.setHi(d,hi);
647 
648  is_per[d] = geom[lev].isPeriodic(d);
649  }
650  m_geom[0].define(m_dom, &m_rb, geom[lev].Coord(), is_per.data());
651 
652  // Create plotfile name
653  std::string name_line = m_name[iline];
654  name_line += "_step_";
655  std::string plotfilename = amrex::Concatenate(name_line, m_level_steps[0], 5);
656 
657  // Get the data
658  amrex::Vector<const amrex::MultiFab*> mf = {&(m_ls_mf[iline])};
659 
660  // Write each line
661  WriteMultiLevelPlotfile(plotfilename, 1, mf,
662  m_varnames, m_geom, static_cast<amrex::Real>(m_time),
663  m_level_steps, m_ref_ratio);
664  }
665  }
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13
Coord
Coordinate-axis selector.
Definition: ERF_DataStruct.H:144
const Real dx
Definition: ERF_InitCustomPert_ABL.H:44
AMREX_FORCE_INLINE IntVect offset(const int face_dir, const int normal)
Definition: ERF_ReadBndryPlanes.cpp:31

Referenced by write_sample_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ write_sample_data()

void LineSampler::write_sample_data ( amrex::Vector< double > &  time,
amrex::Vector< int > &  level_steps,
amrex::Vector< amrex::IntVect > &  ref_ratio,
amrex::Vector< amrex::Geometry > &  geom 
)
inline
576  {
577  if (m_write_ascii) {
578  write_line_ascii(time);
579  } else {
580  write_line_plotfile(time, level_steps, ref_ratio, geom);
581  }
582  }
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:619
void write_line_ascii(amrex::Vector< double > &time)
Definition: ERF_SampleData.H:585
Here is the call graph for this function:

Member Data Documentation

◆ m_bnd_bx

amrex::Vector<amrex::Box> LineSampler::m_bnd_bx

◆ m_bnd_rbx

amrex::Vector<amrex::RealBox> LineSampler::m_bnd_rbx

Referenced by LineSampler(), and write_coords().

◆ m_datastream

amrex::Vector<std::unique_ptr<std::fstream> > LineSampler::m_datastream

Referenced by LineSampler(), and write_line_ascii().

◆ m_dir

amrex::Vector<int> LineSampler::m_dir

◆ m_lev

amrex::Vector<int> LineSampler::m_lev

◆ m_ls_mf

amrex::Vector<amrex::MultiFab> LineSampler::m_ls_mf

◆ m_name

amrex::Vector<std::string> LineSampler::m_name

Referenced by LineSampler(), and write_line_plotfile().

◆ m_use_real_bx

bool LineSampler::m_use_real_bx {false}

Referenced by LineSampler(), and write_coords().

◆ m_varnames

amrex::Vector<std::string> LineSampler::m_varnames {"magvel","theta"}

◆ m_write_ascii

bool LineSampler::m_write_ascii {false}

The documentation for this struct was generated from the following file: