ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ReadBndryPlanes Class Reference

#include <ERF_ReadBndryPlanes.H>

Collaboration diagram for ReadBndryPlanes:

Public Member Functions

 ReadBndryPlanes (const amrex::Geometry &geom, const amrex::Real &rdOcp_in)
 
void define_level_data (int lev)
 
void read_time_file ()
 
void read_input_files (double time, double dt, amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NBCVAR_max > m_bc_extdir_vals)
 
void read_file (int idx, amrex::Vector< std::unique_ptr< PlaneVector >> &data_to_fill, amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NBCVAR_max > m_bc_extdir_vals)
 
amrex::Vector< std::unique_ptr< PlaneVector > > & interp_in_time (const double &time)
 
amrex::Vector< std::unique_ptr< PlaneVector > > & get_tendency (const double &time)
 
double tinterp () const
 
int ingested_velocity () const
 
int ingested_theta () const
 
int ingested_density () const
 
int ingested_scalar () const
 
int ingested_q1 () const
 
int ingested_q2 () const
 
int ingested_KE () const
 

Private Attributes

double m_tn
 The times for which we currently have data. More...
 
double m_tnp1
 
double m_tnp2
 
amrex::Vector< std::unique_ptr< PlaneVector > > m_data_n
 Data at time m_tn. More...
 
amrex::Vector< std::unique_ptr< PlaneVector > > m_data_np1
 Data at time m_tnp1. More...
 
amrex::Vector< std::unique_ptr< PlaneVector > > m_data_np2
 Data at time m_tnp2. More...
 
amrex::Vector< std::unique_ptr< PlaneVector > > m_data_interp
 Data interpolated to the time requested. More...
 
amrex::Vector< std::unique_ptr< PlaneVector > > m_data_tendency
 Tendency between the n and np1 data. More...
 
double m_tinterp {-1.0}
 Time for plane at interpolation. More...
 
amrex::Geometry m_geom
 Geometry at level 0. More...
 
std::string m_filename {""}
 File name for IO. More...
 
std::string m_time_file {""}
 File name for file holding timesteps and times. More...
 
amrex::Vector< double > m_in_times
 The timesteps / times that we read from time.dat. More...
 
amrex::Vector< int > m_in_timesteps
 
amrex::Vector< std::string > m_var_names
 Variables to be read in. More...
 
int m_in_rad = 1
 Controls extents on native bndry output. More...
 
const int m_out_rad = 1
 
const int m_extent_rad = 0
 
bool m_use_real_bcs = false
 Are real BCs being used? More...
 
const amrex::Real m_rdOcp
 R_d/c_p is needed for reading boundary files. More...
 
int is_velocity_read
 
int is_density_read
 
int is_temperature_read
 
int is_theta_read
 
int is_scalar_read
 
int is_q1_read
 
int is_q2_read
 
int is_KE_read
 
int last_file_read
 

Detailed Description

Collection of data structures and operations for reading data

This class contains the inlet data structures and operations to read and interpolate inflow data.

Constructor & Destructor Documentation

◆ ReadBndryPlanes()

ReadBndryPlanes::ReadBndryPlanes ( const amrex::Geometry &  geom,
const amrex::Real rdOcp_in 
)
explicit

ReadBndryPlanes class constructor. Handles initialization from inputs file parameters.

Parameters
geomGeometry for the domain
rdOcp_inReal constant for the Rhydberg constant ($R_d$) divided by the specific heat at constant pressure ($c_p$)
214 :
215  m_geom(geom),
216  m_rdOcp(rdOcp_in)
217 {
218  ParmParse pp("erf");
219 
220  // Get the radius inside the domain
221  pp.query("in_rad",m_in_rad);
222 
223  // Are we using real bcs?
224  pp.query("use_real_bcs", m_use_real_bcs);
225 
226  last_file_read = -1;
227 
228  m_tinterp = -1.0;
229 
230  // What folder will the time series of planes be read from
231  pp.get("bndry_file", m_filename);
232 
233  is_velocity_read = 0;
234  is_density_read = 0;
236  is_theta_read = 0;
237  is_scalar_read = 0;
238  is_q1_read = 0;
239  is_q2_read = 0;
240  is_KE_read = 0;
241 
242  if (pp.contains("bndry_input_var_names"))
243  {
244  int num_vars = pp.countval("bndry_input_var_names");
245  m_var_names.resize(num_vars);
246  pp.queryarr("bndry_input_var_names",m_var_names,0,num_vars);
247  for (int i = 0; i < m_var_names.size(); i++) {
248  if (m_var_names[i] == "velocity") is_velocity_read = 1;
249  if (m_var_names[i] == "density") is_density_read = 1;
250  if (m_var_names[i] == "temperature") is_temperature_read = 1;
251  if (m_var_names[i] == "theta") is_theta_read = 1;
252  if (m_var_names[i] == "scalar") is_scalar_read = 1;
253  if (m_var_names[i] == "qv") is_q1_read = 1;
254  if (m_var_names[i] == "qc") is_q2_read = 1;
255  if (m_var_names[i] == "ke") is_KE_read = 1;
256  }
257  }
258 
259  // time.dat will be in the same folder as the time series of data
260  m_time_file = m_filename + "/time.dat";
261 
262  // each pointer (at at given time) has 6 components, one for each orientation
263  // TODO: we really only need 4 not 6
264  int size = 2*AMREX_SPACEDIM;
265  m_data_n.resize(size);
266  m_data_np1.resize(size);
267  m_data_np2.resize(size);
268  m_data_interp.resize(size);
269  m_data_tendency.resize(size);
270 }
ParmParse pp("prob")
int is_velocity_read
Definition: ERF_ReadBndryPlanes.H:104
int is_q2_read
Definition: ERF_ReadBndryPlanes.H:110
int is_theta_read
Definition: ERF_ReadBndryPlanes.H:107
bool m_use_real_bcs
Are real BCs being used?
Definition: ERF_ReadBndryPlanes.H:99
std::string m_filename
File name for IO.
Definition: ERF_ReadBndryPlanes.H:81
int is_temperature_read
Definition: ERF_ReadBndryPlanes.H:106
int is_density_read
Definition: ERF_ReadBndryPlanes.H:105
amrex::Vector< std::unique_ptr< PlaneVector > > m_data_np2
Data at time m_tnp2.
Definition: ERF_ReadBndryPlanes.H:66
amrex::Vector< std::unique_ptr< PlaneVector > > m_data_interp
Data interpolated to the time requested.
Definition: ERF_ReadBndryPlanes.H:69
int last_file_read
Definition: ERF_ReadBndryPlanes.H:113
int is_KE_read
Definition: ERF_ReadBndryPlanes.H:111
const amrex::Real m_rdOcp
R_d/c_p is needed for reading boundary files.
Definition: ERF_ReadBndryPlanes.H:102
std::string m_time_file
File name for file holding timesteps and times.
Definition: ERF_ReadBndryPlanes.H:84
amrex::Vector< std::unique_ptr< PlaneVector > > m_data_tendency
Tendency between the n and np1 data.
Definition: ERF_ReadBndryPlanes.H:72
amrex::Vector< std::string > m_var_names
Variables to be read in.
Definition: ERF_ReadBndryPlanes.H:91
int is_scalar_read
Definition: ERF_ReadBndryPlanes.H:108
int is_q1_read
Definition: ERF_ReadBndryPlanes.H:109
amrex::Vector< std::unique_ptr< PlaneVector > > m_data_n
Data at time m_tn.
Definition: ERF_ReadBndryPlanes.H:60
amrex::Vector< std::unique_ptr< PlaneVector > > m_data_np1
Data at time m_tnp1.
Definition: ERF_ReadBndryPlanes.H:63
int m_in_rad
Controls extents on native bndry output.
Definition: ERF_ReadBndryPlanes.H:94
amrex::Geometry m_geom
Geometry at level 0.
Definition: ERF_ReadBndryPlanes.H:78
double m_tinterp
Time for plane at interpolation.
Definition: ERF_ReadBndryPlanes.H:75
Here is the call graph for this function:

Member Function Documentation

◆ define_level_data()

void ReadBndryPlanes::define_level_data ( int  lev)

Function in ReadBndryPlanes class for allocating space for the boundary plane data ERF will need.

44 {
45  Print() << "ReadBndryPlanes::define_level_data" << std::endl;
46  // *********************************************************
47  // Allocate space for all of the boundary planes we may need
48  // *********************************************************
49  int ncomp = BCVars::NumTypes;
50  const Box& domain = m_geom.Domain();
51  for (OrientationIter oit; oit != nullptr; ++oit) {
52  auto ori = oit();
53  if (ori.coordDir() < 2) {
54 
55  m_data_n[ori] = std::make_unique<PlaneVector>();
56  m_data_np1[ori] = std::make_unique<PlaneVector>();
57  m_data_np2[ori] = std::make_unique<PlaneVector>();
58  m_data_interp[ori] = std::make_unique<PlaneVector>();
59  m_data_tendency[ori] = std::make_unique<PlaneVector>();
60 
61  const auto& lo = domain.loVect();
62  const auto& hi = domain.hiVect();
63 
64  IntVect plo(lo);
65  IntVect phi(hi);
66  const int normal = ori.coordDir();
67  plo[normal] = ori.isHigh() ? hi[normal] - (m_in_rad - 1) : -m_out_rad;
68  phi[normal] = ori.isHigh() ? hi[normal] + (m_out_rad ) : (m_in_rad - 1);
69  const Box pbx(plo, phi);
70  m_data_n[ori]->push_back(FArrayBox(pbx, ncomp));
71  m_data_np1[ori]->push_back(FArrayBox(pbx, ncomp));
72  m_data_np2[ori]->push_back(FArrayBox(pbx, ncomp));
73  m_data_interp[ori]->push_back(FArrayBox(pbx, ncomp));
74  m_data_tendency[ori]->push_back(FArrayBox(pbx, ncomp));
75  }
76  }
77 }
const int m_out_rad
Definition: ERF_ReadBndryPlanes.H:95
@ NumTypes
Definition: ERF_IndexDefines.H:105

Referenced by read_time_file().

Here is the caller graph for this function:

◆ get_tendency()

Vector< std::unique_ptr< PlaneVector > > & ReadBndryPlanes::get_tendency ( const double &  time_in)

Function in ReadBndryPlanes class for interpolating boundary data in time.

Parameters
timeConstant specifying the time for interpolation
152 {
153  // A restart that lands exactly on a boundary-plane time can request a time a few
154  // ULP outside [m_tn, m_tnp2] because per-level t_new drifts under subcycling.
155  // Tolerate that drift, then clamp into the valid window before interpolating.
156  const double eps = 1.0e-8 * (m_tnp2 - m_tn);
157  AMREX_ALWAYS_ASSERT(m_tn - eps <= time_in && time_in <= m_tnp2 + eps);
158  const double time = std::min(std::max(time_in, m_tn), m_tnp2);
159 
160  if (time < m_tnp1) {
161  Real idt = static_cast<Real>(1.0 / (m_tnp1 - m_tn));
162  for (OrientationIter oit; oit != nullptr; ++oit) {
163  auto ori = oit();
164  if (ori.coordDir() < 2) {
165  const int nlevels = static_cast<int>(m_data_n[ori]->size());
166  for (int lev = 0; lev < nlevels; ++lev) {
167  auto& fabt = (*m_data_tendency[ori])[lev];
168  Box bx = fabt.box();
169  int ncomp = fabt.nComp();
170 
171  const auto& datt = fabt.array();
172  const auto& datn = (*m_data_n[ori])[lev].array();
173  const auto& datnp1 = (*m_data_np1[ori])[lev].array();
174  ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept
175  {
176  datt(i,j,k,n) = (datnp1(i,j,k,n) - datn(i,j,k,n)) * idt;
177  });
178  }
179  }
180  }
181  } else {
182  Real idt = static_cast<Real>(1.0 / (m_tnp2 - m_tnp1));
183  for (OrientationIter oit; oit != nullptr; ++oit) {
184  auto ori = oit();
185  if (ori.coordDir() < 2) {
186  const int nlevels = static_cast<int>(m_data_n[ori]->size());
187  for (int lev = 0; lev < nlevels; ++lev) {
188  auto& fabt = (*m_data_tendency[ori])[lev];
189  Box bx = fabt.box();
190  int ncomp = fabt.nComp();
191 
192  const auto& datt = fabt.array();
193  const auto& datnp1 = (*m_data_np1[ori])[lev].array();
194  const auto& datnp2 = (*m_data_np2[ori])[lev].array();
195  ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept
196  {
197  datt(i,j,k,n) = (datnp2(i,j,k,n) - datnp1(i,j,k,n)) * idt;
198  });
199  }
200  }
201  }
202  }
203 
204  return m_data_tendency;
205 }
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
ParallelFor(grown_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
double m_tnp1
Definition: ERF_ReadBndryPlanes.H:56
double m_tnp2
Definition: ERF_ReadBndryPlanes.H:57
double m_tn
The times for which we currently have data.
Definition: ERF_ReadBndryPlanes.H:55
Here is the call graph for this function:

◆ ingested_density()

int ReadBndryPlanes::ingested_density ( ) const
inline
46 {return is_density_read;}

Referenced by read_file().

Here is the caller graph for this function:

◆ ingested_KE()

int ReadBndryPlanes::ingested_KE ( ) const
inline
50 {return is_KE_read;}

◆ ingested_q1()

int ReadBndryPlanes::ingested_q1 ( ) const
inline
48 {return is_q1_read;}

◆ ingested_q2()

int ReadBndryPlanes::ingested_q2 ( ) const
inline
49 {return is_q2_read;}

◆ ingested_scalar()

int ReadBndryPlanes::ingested_scalar ( ) const
inline
47 {return is_scalar_read;}

◆ ingested_theta()

int ReadBndryPlanes::ingested_theta ( ) const
inline

◆ ingested_velocity()

int ReadBndryPlanes::ingested_velocity ( ) const
inline
44 {return is_velocity_read;}

◆ interp_in_time()

Vector< std::unique_ptr< PlaneVector > > & ReadBndryPlanes::interp_in_time ( const double &  time_in)

Function in ReadBndryPlanes class for interpolating boundary data in time.

Parameters
timeConstant specifying the time for interpolation
87 {
88  // A restart that lands exactly on a boundary-plane time can request a time a few
89  // ULP outside [m_tn, m_tnp2] because per-level t_new drifts under subcycling.
90  // Tolerate that drift, then clamp into the valid window before interpolating.
91  const double eps = 1.0e-8 * (m_tnp2 - m_tn);
92  AMREX_ALWAYS_ASSERT(m_tn - eps <= time_in && time_in <= m_tnp2 + eps);
93  const double time = std::min(std::max(time_in, m_tn), m_tnp2);
94 
95  //Print() << "interp_in_time at time " << time << " given " << m_tn << " " << m_tnp1 << " " << m_tnp2 << std::endl;
96  //Print() << "m_tinterp " << m_tinterp << std::endl;
97 
98  if (time == m_tinterp) {
99  // We have already interpolated to this time
100  return m_data_interp;
101 
102  } else {
103 
104  // We must now interpolate to a new time
105  m_tinterp = time;
106 
107  if (time < m_tnp1) {
108  for (OrientationIter oit; oit != nullptr; ++oit) {
109  auto ori = oit();
110  if (ori.coordDir() < 2) {
111  const int nlevels = static_cast<int>(m_data_n[ori]->size());
112  for (int lev = 0; lev < nlevels; ++lev) {
113  const auto& datn = (*m_data_n[ori])[lev];
114  const auto& datnp1 = (*m_data_np1[ori])[lev];
115  auto& dati = (*m_data_interp[ori])[lev];
116  dati.linInterp<RunOn::Device>(datn, 0, datnp1, 0,
117  static_cast<Real>(m_tn), static_cast<Real>(m_tnp1),
118  static_cast<Real>(m_tinterp),
119  datn.box(), 0, dati.nComp());
120  }
121  }
122  }
123  } else {
124  for (OrientationIter oit; oit != nullptr; ++oit) {
125  auto ori = oit();
126  if (ori.coordDir() < 2) {
127  const int nlevels = static_cast<int>(m_data_n[ori]->size());
128  for (int lev = 0; lev < nlevels; ++lev) {
129  const auto& datnp1 = (*m_data_np1[ori])[lev];
130  const auto& datnp2 = (*m_data_np2[ori])[lev];
131  auto& dati = (*m_data_interp[ori])[lev];
132  dati.linInterp<RunOn::Device>(datnp1, 0, datnp2, 0,
133  static_cast<Real>(m_tnp1), static_cast<Real>(m_tnp2),
134  static_cast<Real>(m_tinterp),
135  datnp1.box(), 0, dati.nComp());
136  }
137  }
138  }
139  }
140  }
141  return m_data_interp;
142 }
Here is the call graph for this function:

◆ read_file()

void ReadBndryPlanes::read_file ( int  idx,
amrex::Vector< std::unique_ptr< PlaneVector >> &  data_to_fill,
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NBCVAR_max m_bc_extdir_vals 
)

Function in ReadBndryPlanes to read boundary data for each face and variable from files.

Parameters
idxSpecifies the index corresponding to the timestep we want
data_to_fillContainer for face data on boundaries
m_bc_extdir_valsContainer storing the external dirichlet boundary conditions we are reading from the input files
423 {
424  if (idx >= m_in_timesteps.size()) {
425  Print() << "Asking for index " << idx << " but m_in_timesteps only has size " << m_in_timesteps.size() << std::endl;
426  Abort();
427  }
428  const int t_step = m_in_timesteps[idx];
429  const std::string chkname1 = m_filename + Concatenate("/bndry_output", t_step);
430 
431  const std::string level_prefix = "Level_";
432  const int lev = 0;
433 
434  const Box& domain = m_geom.Domain();
435  BoxArray ba(domain);
436  DistributionMapping dm{ba};
437 
438  GpuArray<GpuArray<Real, AMREX_SPACEDIM*2>, AMREX_SPACEDIM+NBCVAR_max> l_bc_extdir_vals_d;
439 
440  for (int i = 0; i < BCVars::NumTypes; i++)
441  {
442  for (OrientationIter oit; oit != nullptr; ++oit) {
443  auto ori = oit();
444  l_bc_extdir_vals_d[i][ori] = m_bc_extdir_vals[i][ori];
445  }
446  }
447 
448  int n_for_density = -1;
449  for (int i = 0; i < m_var_names.size(); i++)
450  {
451  if (m_var_names[i] == "density") n_for_density = i;
452  }
453 
454  // We need to initialize all the components because we may not fill all of them from files,
455  // but the loop in the interpolate routine goes over all the components anyway
456  int ncomp_for_bc = BCVars::NumTypes;
457  for (OrientationIter oit; oit != nullptr; ++oit) {
458  auto ori = oit();
459  if (ori.coordDir() < 2) {
460  FArrayBox& d = (*data_to_fill[ori])[lev];
461  const auto& bx = d.box();
462  Array4<Real> d_arr = d.array();
463  ParallelFor(
464  bx, ncomp_for_bc, [=] AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept {
465  d_arr(i,j,k,n) = zero;
466  });
467  }
468  }
469 
470  // Read density for primitive to conserved conversions
471  std::string filenamer = MultiFabFileFullPrefix(lev, chkname1, level_prefix, "density");
472  BndryRegister bndry_r(ba, dm, m_in_rad, m_out_rad, m_extent_rad, 1);
473  bndry_r.setVal(bogus_large_value);
474  for (OrientationIter oit; oit != nullptr; ++oit) {
475  auto ori = oit();
476  if (ori.coordDir() < 2) {
477  std::string facenamer = Concatenate(filenamer + '_', ori, 1);
478  bndry_r[ori].read(facenamer);
479  }
480  }
481 
482  // Expose for GPU
483  bool real_bcs = m_use_real_bcs;
484 
485  for (int ivar = 0; ivar < m_var_names.size(); ivar++)
486  {
487  std::string var_name = m_var_names[ivar];
488 
489  std::string filename1 = MultiFabFileFullPrefix(lev, chkname1, level_prefix, var_name);
490 
491  int ncomp;
492  if (var_name == "velocity") {
493  ncomp = AMREX_SPACEDIM;
494  } else {
495  ncomp = 1;
496  }
497 
498  int n_offset;
499  if (var_name == "density") n_offset = BCVars::Rho_bc_comp;
500  if (var_name == "theta") n_offset = BCVars::RhoTheta_bc_comp;
501  if (var_name == "temperature") n_offset = BCVars::RhoTheta_bc_comp;
502  if (var_name == "ke") n_offset = BCVars::RhoKE_bc_comp;
503  if (var_name == "scalar") n_offset = BCVars::RhoScalar_bc_comp;
504  if (var_name == "qv") n_offset = BCVars::RhoQ1_bc_comp;
505  if (var_name == "qc") n_offset = BCVars::RhoQ2_bc_comp;
506  if (var_name == "velocity") n_offset = BCVars::xvel_bc;
507 
508  // Print() << "Reading " << chkname1 << " for variable " << var_name << " with n_offset == " << n_offset << std::endl;
509 
510  BndryRegister bndry(ba, dm, m_in_rad, m_out_rad, m_extent_rad, ncomp);
511  bndry.setVal(bogus_large_value);
512 
513  // *********************************************************
514  // Read in the BndryReg for all non-z faces
515  // *********************************************************
516  for (OrientationIter oit; oit != nullptr; ++oit) {
517  auto ori = oit();
518  if (ori.coordDir() < 2) {
519 
520  std::string facename1 = Concatenate(filename1 + '_', ori, 1);
521  bndry[ori].read(facename1);
522 
523  int normal = ori.coordDir();
524  IntVect v_offset = offset(ori.faceDir(), normal);
525  if (real_bcs) { v_offset = IntVect(0); }
526 
527  const auto& bbx = (*data_to_fill[ori])[lev].box();
528 
529  // *********************************************************
530  // Copy from the BndryReg into a MultiFab then use copyTo
531  // to write from the MultiFab to a single FAB for each face
532  // *********************************************************
533  MultiFab bndryMF(
534  bndry[ori].boxArray(), bndry[ori].DistributionMap(),
535  ncomp, 0, MFInfo());
536 
537  for (MFIter mfi(bndryMF); mfi.isValid(); ++mfi) {
538 
539  const auto& vbx = mfi.validbox();
540  const auto& bndry_read_arr = bndry[ori].array(mfi);
541  const auto& bndry_read_r_arr = bndry_r[ori].array(mfi);
542  const auto& bndry_mf_arr = bndryMF.array(mfi);
543 
544  const auto& bx = bbx & vbx;
545  if (bx.isEmpty()) {
546  continue;
547  }
548 
549  // Split the 2-cell-thick working box into ghost and interior
550  // slots so the (i+v_offset) neighbor access stays in-bounds.
551  // Both slots are filled with the same face-averaged Dirichlet
552  // value; the interior slot just needs the opposite neighbor.
553  Box bx_ghost = bx;
554  Box bx_int = bx;
555  if (ori.isLow()) {
556  bx_ghost.setBig (normal, domain.smallEnd(normal) - 1);
557  bx_int .setSmall(normal, domain.smallEnd(normal));
558  } else {
559  bx_ghost.setSmall(normal, domain.bigEnd(normal) + 1);
560  bx_int .setBig (normal, domain.bigEnd(normal));
561  }
562  const IntVect v_offset_int = -v_offset;
563 
564  // We average the two cell-centered data points in the normal direction
565  // to define a Dirichlet value on the face itself.
566 
567  // This is the scalars -- they all get multiplied by rho, and in the case of
568  // reading in temperature, we must convert to theta first
569  Real rdOcp = m_rdOcp;
570  if (n_for_density >= 0) {
571  if (var_name == "temperature") {
572  ParallelFor(
573  bx_ghost, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
574  Real R1 = bndry_read_r_arr(i, j, k, 0);
575  Real R2 = bndry_read_r_arr(i+v_offset[0],j+v_offset[1],k+v_offset[2],0);
576  Real T1 = bndry_read_arr(i, j, k, 0);
577  Real T2 = bndry_read_arr(i+v_offset[0],j+v_offset[1],k+v_offset[2],0);
578  Real Th1 = getThgivenRandT(R1,T1,rdOcp);
579  Real Th2 = getThgivenRandT(R2,T2,rdOcp);
580  bndry_mf_arr(i, j, k, 0) = (real_bcs) ? bndry_read_arr(i, j, k, 0) :
581  myhalf * (R1*Th1 + R2*Th2);
582  });
583  } else if (var_name == "theta" || var_name == "ke" || var_name == "scalar" ||
584  var_name == "qv" || var_name == "qc") {
585  ParallelFor(
586  bx_ghost, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
587  Real R1 = bndry_read_r_arr(i, j, k, 0);
588  Real R2 = bndry_read_r_arr(i+v_offset[0],j+v_offset[1],k+v_offset[2],0);
589  bndry_mf_arr(i, j, k, 0) = (real_bcs) ? bndry_read_arr(i, j, k, 0) :
590  myhalf * ( R1 * bndry_read_arr(i, j, k, 0) +
591  R2 * bndry_read_arr(i+v_offset[0],j+v_offset[1],k+v_offset[2], 0));
592  });
593  } else if (var_name == "density") {
594  ParallelFor(
595  bx_ghost, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
596  bndry_mf_arr(i, j, k, 0) = (real_bcs) ? bndry_read_arr(i, j, k, 0) :
597  myhalf * ( bndry_read_arr(i, j, k, 0) +
598  bndry_read_arr(i+v_offset[0],j+v_offset[1],k+v_offset[2], 0));
599  });
600  }
601  } else if (!ingested_density()) {
602  if (var_name == "temperature") {
603  ParallelFor(
604  bx_ghost, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
605  Real R1 = l_bc_extdir_vals_d[BCVars::Rho_bc_comp][ori];
606  Real R2 = l_bc_extdir_vals_d[BCVars::Rho_bc_comp][ori];
607  Real T1 = bndry_read_arr(i, j, k, 0);
608  Real T2 = bndry_read_arr(i+v_offset[0],j+v_offset[1],k+v_offset[2], 0);
609  Real Th1 = getThgivenRandT(R1,T1,rdOcp);
610  Real Th2 = getThgivenRandT(R2,T2,rdOcp);
611  bndry_mf_arr(i, j, k, 0) = (real_bcs) ? bndry_read_arr(i, j, k, 0) :
612  myhalf * (R1*Th1 + R2*Th2);
613  });
614  } else if (var_name == "theta" || var_name == "ke" || var_name == "scalar" ||
615  var_name == "qv" || var_name == "qc") {
616  ParallelFor(
617  bx_ghost, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
618  Real R1 = l_bc_extdir_vals_d[BCVars::Rho_bc_comp][ori];
619  Real R2 = l_bc_extdir_vals_d[BCVars::Rho_bc_comp][ori];
620  bndry_mf_arr(i, j, k, 0) = (real_bcs) ? bndry_read_arr(i, j, k, 0) :
621  myhalf * (R1 * bndry_read_arr(i, j, k, 0) +
622  R2 * bndry_read_arr(i+v_offset[0],j+v_offset[1],k+v_offset[2], 0));
623  });
624  }
625  }
626 
627  // This is velocity
628  if (var_name == "velocity") {
629  ParallelFor(
630  bx_ghost, ncomp, [=] AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept {
631  bndry_mf_arr(i, j, k, n) = (real_bcs) ? bndry_read_arr(i, j, k, n) :
632  myhalf * (bndry_read_arr(i, j, k, n) +
633  bndry_read_arr(i+v_offset[0],j+v_offset[1],k+v_offset[2], n));
634  });
635  }
636 
637  // --- interior-slot fill (same face-averaged Dirichlet value;
638  // neighbor offset is flipped because the "other cell"
639  // is now on the opposite side of the boundary face) ---
640  if (n_for_density >= 0) {
641  if (var_name == "temperature") {
642  ParallelFor(
643  bx_int, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
644  Real R1 = bndry_read_r_arr(i, j, k, 0);
645  Real R2 = bndry_read_r_arr(i+v_offset_int[0],j+v_offset_int[1],k+v_offset_int[2],0);
646  Real T1 = bndry_read_arr(i, j, k, 0);
647  Real T2 = bndry_read_arr(i+v_offset_int[0],j+v_offset_int[1],k+v_offset_int[2],0);
648  Real Th1 = getThgivenRandT(R1,T1,rdOcp);
649  Real Th2 = getThgivenRandT(R2,T2,rdOcp);
650  bndry_mf_arr(i, j, k, 0) = (real_bcs) ? bndry_read_arr(i, j, k, 0) :
651  myhalf * (R1*Th1 + R2*Th2);
652  });
653  } else if (var_name == "theta" || var_name == "ke" || var_name == "scalar" ||
654  var_name == "qv" || var_name == "qc") {
655  ParallelFor(
656  bx_int, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
657  Real R1 = bndry_read_r_arr(i, j, k, 0);
658  Real R2 = bndry_read_r_arr(i+v_offset_int[0],j+v_offset_int[1],k+v_offset_int[2],0);
659  bndry_mf_arr(i, j, k, 0) = (real_bcs) ? bndry_read_arr(i, j, k, 0) :
660  myhalf * ( R1 * bndry_read_arr(i, j, k, 0) +
661  R2 * bndry_read_arr(i+v_offset_int[0],j+v_offset_int[1],k+v_offset_int[2], 0));
662  });
663  } else if (var_name == "density") {
664  ParallelFor(
665  bx_int, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
666  bndry_mf_arr(i, j, k, 0) = (real_bcs) ? bndry_read_arr(i, j, k, 0) :
667  myhalf * ( bndry_read_arr(i, j, k, 0) +
668  bndry_read_arr(i+v_offset_int[0],j+v_offset_int[1],k+v_offset_int[2], 0));
669  });
670  }
671  } else if (!ingested_density()) {
672  if (var_name == "temperature") {
673  ParallelFor(
674  bx_int, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
675  Real R1 = l_bc_extdir_vals_d[BCVars::Rho_bc_comp][ori];
676  Real R2 = l_bc_extdir_vals_d[BCVars::Rho_bc_comp][ori];
677  Real T1 = bndry_read_arr(i, j, k, 0);
678  Real T2 = bndry_read_arr(i+v_offset_int[0],j+v_offset_int[1],k+v_offset_int[2], 0);
679  Real Th1 = getThgivenRandT(R1,T1,rdOcp);
680  Real Th2 = getThgivenRandT(R2,T2,rdOcp);
681  bndry_mf_arr(i, j, k, 0) = (real_bcs) ? bndry_read_arr(i, j, k, 0) :
682  myhalf * (R1*Th1 + R2*Th2);
683  });
684  } else if (var_name == "theta" || var_name == "ke" || var_name == "scalar" ||
685  var_name == "qv" || var_name == "qc") {
686  ParallelFor(
687  bx_int, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
688  Real R1 = l_bc_extdir_vals_d[BCVars::Rho_bc_comp][ori];
689  Real R2 = l_bc_extdir_vals_d[BCVars::Rho_bc_comp][ori];
690  bndry_mf_arr(i, j, k, 0) = (real_bcs) ? bndry_read_arr(i, j, k, 0) :
691  myhalf * (R1 * bndry_read_arr(i, j, k, 0) +
692  R2 * bndry_read_arr(i+v_offset_int[0],j+v_offset_int[1],k+v_offset_int[2], 0));
693  });
694  }
695  }
696 
697  if (var_name == "velocity") {
698  ParallelFor(
699  bx_int, ncomp, [=] AMREX_GPU_DEVICE(int i, int j, int k, int n) noexcept {
700  bndry_mf_arr(i, j, k, n) = (real_bcs) ? bndry_read_arr(i, j, k, n) :
701  myhalf * (bndry_read_arr(i, j, k, n) +
702  bndry_read_arr(i+v_offset_int[0],j+v_offset_int[1],k+v_offset_int[2], n));
703  });
704  }
705 
706  } // mfi
707  bndryMF.copyTo((*data_to_fill[ori])[lev], 0, n_offset, ncomp);
708  } // coordDir < 2
709  } // ori
710  } // var_name
711 }
constexpr amrex::Real bogus_large_value
Definition: ERF_Constants.H:26
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getThgivenRandT(const amrex::Real rho, const amrex::Real T, const amrex::Real rdOcp, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:64
#define NBCVAR_max
Definition: ERF_IndexDefines.H:29
const Real rdOcp
Definition: ERF_InitCustomPert_Bomex.H:16
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int idx(int i, int j, int k, int nx, int ny)
Definition: ERF_InitForEnsemble.cpp:287
AMREX_FORCE_INLINE IntVect offset(const int face_dir, const int normal)
Definition: ERF_ReadBndryPlanes.cpp:28
amrex::Vector< int > m_in_timesteps
Definition: ERF_ReadBndryPlanes.H:88
int ingested_density() const
Definition: ERF_ReadBndryPlanes.H:46
const int m_extent_rad
Definition: ERF_ReadBndryPlanes.H:96
@ RhoScalar_bc_comp
Definition: ERF_IndexDefines.H:90
@ RhoQ1_bc_comp
Definition: ERF_IndexDefines.H:91
@ RhoKE_bc_comp
Definition: ERF_IndexDefines.H:89
@ RhoTheta_bc_comp
Definition: ERF_IndexDefines.H:88
@ RhoQ2_bc_comp
Definition: ERF_IndexDefines.H:92
@ Rho_bc_comp
Definition: ERF_IndexDefines.H:87
@ xvel_bc
Definition: ERF_IndexDefines.H:102

Referenced by read_input_files().

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

◆ read_input_files()

void ReadBndryPlanes::read_input_files ( double  time,
double  dt,
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NBCVAR_max m_bc_extdir_vals 
)

Function in ReadBndryPlanes for reading boundary data at a specific time and at the next timestep from input files.

Parameters
timeCurrent time
dtCurrent timestep
m_bc_extdir_valsContainer storing the external dirichlet boundary conditions we are reading from the input files
349 {
350  BL_PROFILE("ERF::ReadBndryPlanes::read_input_files");
351 
352  // Assert that both the current time and the next time are within the bounds
353  // of the data that we can read
354  AMREX_ALWAYS_ASSERT((m_in_times[0] <= time) && (time <= m_in_times.back()));
355  AMREX_ALWAYS_ASSERT((m_in_times[0] <= time+dt) && (time+dt <= m_in_times.back()));
356 
357  int ncomp = 1;
358 
359  const Box& domain = m_geom.Domain();
360  BoxArray ba(domain);
361  DistributionMapping dm{ba};
362  BndryRegister bndryn(ba, dm, m_in_rad, m_out_rad, m_extent_rad, ncomp);
363  bndryn.setVal(bogus_large_value);
364 
365  // The first time we enter this routine we read the first three files
366  if (last_file_read == -1)
367  {
368  int idx_init = 0;
369  read_file(idx_init,m_data_n ,m_bc_extdir_vals);
370  read_file(idx_init,m_data_interp,m_bc_extdir_vals); // We want to start with this filled
371  m_tn = m_in_times[idx_init];
372 
373  idx_init = 1;
374  read_file(idx_init,m_data_np1,m_bc_extdir_vals);
375  m_tnp1 = m_in_times[idx_init];
376 
377  idx_init = 2;
378  read_file(idx_init,m_data_np2,m_bc_extdir_vals);
379  m_tnp2 = m_in_times[idx_init];
380 
381  last_file_read = idx_init;
382  }
383 
384  // Compute the index such that time falls between times[idx] and times[idx+1]
385  const int idx = closest_index(m_in_times, time);
386 
387  // Advance the read window until it spans the requested time.
388  while (idx >= last_file_read-1 && last_file_read != m_in_times.size()-1) {
389  int new_read = last_file_read+1;
390 
391  // We need to change which data the pointers point to before we read in the new data
392  // This doesn't actually move the data, just swaps the pointers
393  for (OrientationIter oit; oit != nullptr; ++oit) {
394  auto ori = oit();
395  std::swap(m_data_n[ori] ,m_data_np1[ori]);
396  std::swap(m_data_np1[ori],m_data_np2[ori]);
397  }
398 
399  // Set the times corresponding to the post-swap pointers
400  m_tn = m_tnp1;
401  m_tnp1 = m_tnp2;
402  m_tnp2 = m_in_times[new_read];
403 
404  read_file(new_read,m_data_np2,m_bc_extdir_vals);
405  last_file_read = new_read;
406  }
407 
408  AMREX_ASSERT(time >= m_tn && time <= m_tnp2);
409  AMREX_ASSERT(time+dt >= m_tn && time+dt <= m_tnp2);
410 }
AMREX_FORCE_INLINE int closest_index(const Vector< double > &vec, const double value)
Definition: ERF_ReadBndryPlanes.cpp:15
amrex::Vector< double > m_in_times
The timesteps / times that we read from time.dat.
Definition: ERF_ReadBndryPlanes.H:87
void read_file(int idx, amrex::Vector< std::unique_ptr< PlaneVector >> &data_to_fill, amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NBCVAR_max > m_bc_extdir_vals)
Definition: ERF_ReadBndryPlanes.cpp:420
Here is the call graph for this function:

◆ read_time_file()

void ReadBndryPlanes::read_time_file ( )

Function in ReadBndryPlanes class for reading the external file specifying time data and broadcasting this data across MPI ranks.

277 {
278  BL_PROFILE("ERF::ReadBndryPlanes::read_time_file");
279 
280  // *********************************************************
281  // Read the time.data file and store the timesteps and times
282  // *********************************************************
283  int time_file_length = 0;
284 
285  if (ParallelDescriptor::IOProcessor()) {
286 
287  std::string line;
288  std::ifstream time_file(m_time_file);
289  if (!time_file.good()) {
290  Abort("Cannot find time file: " + m_time_file);
291  }
292  while (std::getline(time_file, line)) {
293  ++time_file_length;
294  }
295 
296  time_file.close();
297  }
298 
299  ParallelDescriptor::Bcast(
300  &time_file_length, 1,
301  ParallelDescriptor::IOProcessorNumber(),
302  ParallelDescriptor::Communicator());
303 
304  m_in_times.resize(time_file_length);
305  m_in_timesteps.resize(time_file_length);
306 
307  if (ParallelDescriptor::IOProcessor()) {
308  std::ifstream time_file(m_time_file);
309  for (int i = 0; i < time_file_length; ++i) {
310  time_file >> m_in_timesteps[i] >> m_in_times[i];
311  }
312  // Sanity check that there are no duplicates or mis-orderings
313  for (int i = 1; i < time_file_length; ++i) {
314  if (m_in_timesteps[i] <= m_in_timesteps[i-1])
315  Error("Bad timestep in time.dat file");
316  if (m_in_times[i] <= m_in_times[i-1])
317  Error("Bad time in time.dat file");
318  }
319  time_file.close();
320  }
321 
322  ParallelDescriptor::Bcast(
323  m_in_timesteps.data(), time_file_length,
324  ParallelDescriptor::IOProcessorNumber(),
325  ParallelDescriptor::Communicator());
326 
327  ParallelDescriptor::Bcast(
328  m_in_times.data(), time_file_length,
329  ParallelDescriptor::IOProcessorNumber(),
330  ParallelDescriptor::Communicator());
331 
332  // Allocate data we will need -- for now just at one level
333  int lev = 0;
334  define_level_data(lev);
335  Print() << "Successfully read time file and allocated data" << std::endl;
336 }
void define_level_data(int lev)
Definition: ERF_ReadBndryPlanes.cpp:43
Here is the call graph for this function:

◆ tinterp()

double ReadBndryPlanes::tinterp ( ) const
inline
42 { return m_tinterp; }

Member Data Documentation

◆ is_density_read

int ReadBndryPlanes::is_density_read
private

◆ is_KE_read

int ReadBndryPlanes::is_KE_read
private

Referenced by ingested_KE(), and ReadBndryPlanes().

◆ is_q1_read

int ReadBndryPlanes::is_q1_read
private

Referenced by ingested_q1(), and ReadBndryPlanes().

◆ is_q2_read

int ReadBndryPlanes::is_q2_read
private

Referenced by ingested_q2(), and ReadBndryPlanes().

◆ is_scalar_read

int ReadBndryPlanes::is_scalar_read
private

Referenced by ingested_scalar(), and ReadBndryPlanes().

◆ is_temperature_read

int ReadBndryPlanes::is_temperature_read
private

Referenced by ingested_theta(), and ReadBndryPlanes().

◆ is_theta_read

int ReadBndryPlanes::is_theta_read
private

Referenced by ingested_theta(), and ReadBndryPlanes().

◆ is_velocity_read

int ReadBndryPlanes::is_velocity_read
private

◆ last_file_read

int ReadBndryPlanes::last_file_read
private

◆ m_data_interp

amrex::Vector<std::unique_ptr<PlaneVector> > ReadBndryPlanes::m_data_interp
private

Data interpolated to the time requested.

Referenced by read_input_files(), and ReadBndryPlanes().

◆ m_data_n

amrex::Vector<std::unique_ptr<PlaneVector> > ReadBndryPlanes::m_data_n
private

Data at time m_tn.

Referenced by read_input_files(), and ReadBndryPlanes().

◆ m_data_np1

amrex::Vector<std::unique_ptr<PlaneVector> > ReadBndryPlanes::m_data_np1
private

Data at time m_tnp1.

Referenced by read_input_files(), and ReadBndryPlanes().

◆ m_data_np2

amrex::Vector<std::unique_ptr<PlaneVector> > ReadBndryPlanes::m_data_np2
private

Data at time m_tnp2.

Referenced by read_input_files(), and ReadBndryPlanes().

◆ m_data_tendency

amrex::Vector<std::unique_ptr<PlaneVector> > ReadBndryPlanes::m_data_tendency
private

Tendency between the n and np1 data.

Referenced by ReadBndryPlanes().

◆ m_extent_rad

const int ReadBndryPlanes::m_extent_rad = 0
private

Referenced by read_file(), and read_input_files().

◆ m_filename

std::string ReadBndryPlanes::m_filename {""}
private

File name for IO.

Referenced by read_file(), and ReadBndryPlanes().

◆ m_geom

amrex::Geometry ReadBndryPlanes::m_geom
private

Geometry at level 0.

Referenced by read_file(), and read_input_files().

◆ m_in_rad

int ReadBndryPlanes::m_in_rad = 1
private

Controls extents on native bndry output.

Referenced by read_file(), read_input_files(), and ReadBndryPlanes().

◆ m_in_times

amrex::Vector<double> ReadBndryPlanes::m_in_times
private

The timesteps / times that we read from time.dat.

Referenced by read_input_files(), and read_time_file().

◆ m_in_timesteps

amrex::Vector<int> ReadBndryPlanes::m_in_timesteps
private

Referenced by read_file(), and read_time_file().

◆ m_out_rad

const int ReadBndryPlanes::m_out_rad = 1
private

Referenced by read_file(), and read_input_files().

◆ m_rdOcp

const amrex::Real ReadBndryPlanes::m_rdOcp
private

R_d/c_p is needed for reading boundary files.

Referenced by read_file().

◆ m_time_file

std::string ReadBndryPlanes::m_time_file {""}
private

File name for file holding timesteps and times.

Referenced by read_time_file(), and ReadBndryPlanes().

◆ m_tinterp

double ReadBndryPlanes::m_tinterp {-1.0}
private

Time for plane at interpolation.

Referenced by ReadBndryPlanes(), and tinterp().

◆ m_tn

double ReadBndryPlanes::m_tn
private

The times for which we currently have data.

Referenced by read_input_files().

◆ m_tnp1

double ReadBndryPlanes::m_tnp1
private

Referenced by read_input_files().

◆ m_tnp2

double ReadBndryPlanes::m_tnp2
private

Referenced by read_input_files().

◆ m_use_real_bcs

bool ReadBndryPlanes::m_use_real_bcs = false
private

Are real BCs being used?

Referenced by read_file(), and ReadBndryPlanes().

◆ m_var_names

amrex::Vector<std::string> ReadBndryPlanes::m_var_names
private

Variables to be read in.

Referenced by read_file(), and ReadBndryPlanes().


The documentation for this class was generated from the following files: