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

#include <ERF_TurbPertStruct.H>

Collaboration diagram for TurbulentPerturbation:

Public Member Functions

 ~TurbulentPerturbation ()
 
void init_tpi_type (const int lev, const PerturbationType &pert_type, const int max_level)
 
void init_tpi (const int lev, const amrex::Vector< amrex::BoxArray > &subdomains_lev, const amrex::GpuArray< amrex::Real, 3 > dx, const amrex::BoxArray &ba, const amrex::DistributionMapping &dm, const int ngrow_state, std::string pp_prefix, const amrex::Vector< amrex::IntVect > refRatio, const int max_level)
 
void calc_tpi_update (const int lev, const double dt, amrex::MultiFab &mf_xvel, amrex::MultiFab &mf_yvel, amrex::MultiFab &mf_cons)
 
void apply_tpi (const int &lev, const amrex::Box &vbx, const int &comp, const amrex::IndexType &m_ixtype, const amrex::Array4< amrex::Real > &src_arr, const amrex::Array4< amrex::Real const > &pert_cell)
 
void calc_tpi_amp (const int &lev, const int &boxIdx, const double &interval)
 
void pseudoRandomPert (const int &boxIdx, const int &lev, const amrex::IndexType &m_ixtype)
 
void zero_amp (const int &boxIdx, const int &lev, const amrex::IndexType &m_ixtype)
 
void netZeroBuoyantAdd (const int &boxIdx, const int &lev)
 
void netZeroBuoyantAdjust (const int &boxIdx, const int &lev)
 
void calc_tpi_meanMag_perBox (const int &boxIdx, const int &lev, amrex::MultiFab &mf_cons, amrex::MultiFab &mf_xvel, amrex::MultiFab &mf_yvel)
 
void debug (double)
 

Public Attributes

amrex::Vector< int > pt_type
 
amrex::Vector< amrex::BoxArray > pb_ba
 
amrex::Vector< amrex::Vector< amrex::Real > > pb_mag
 
amrex::Vector< amrex::Vector< amrex::Real > > pb_dir
 
amrex::Vector< amrex::MultiFab > pb_cell
 

Private Member Functions

amrex::Real RandomReal (const amrex::Real min, const amrex::Real max)
 

Private Attributes

int tpi_layers
 
int tpi_offset
 
amrex::Vector< int > tpi_boxDim
 
amrex::Vector< int > tpi_direction
 
amrex::Real tpi_nonDim
 
amrex::Real tpi_Ti
 
amrex::Real tpi_Tinf
 
amrex::Vector< amrex::Realtpi_Hpb
 
amrex::Vector< amrex::Realtpi_Lpb
 
amrex::Vector< amrex::Realtpi_Wpb
 
amrex::Vector< amrex::Realtpi_lref
 
amrex::Real tpi_net_buoyant
 
amrex::Real tpi_pert_adjust
 
amrex::Vector< amrex::IntVect > ref_ratio
 
amrex::Real input_Ug
 
amrex::Real input_w_amp
 
int perturbation_klo
 
int perturbation_khi
 
amrex::Vector< amrex::Vector< double > > pb_interval
 
amrex::Vector< amrex::Vector< double > > pb_local_etime
 
amrex::Vector< amrex::Vector< amrex::Real > > pb_amp
 
amrex::Vector< amrex::Vector< amrex::Real > > pb_netZero
 

Constructor & Destructor Documentation

◆ ~TurbulentPerturbation()

TurbulentPerturbation::~TurbulentPerturbation ( )
inline
26 {}

Member Function Documentation

◆ apply_tpi()

void TurbulentPerturbation::apply_tpi ( const int &  lev,
const amrex::Box &  vbx,
const int &  comp,
const amrex::IndexType &  m_ixtype,
const amrex::Array4< amrex::Real > &  src_arr,
const amrex::Array4< amrex::Real const > &  pert_cell 
)
inline
379  {
380  for (int boxIdx = 0; boxIdx < pb_ba[lev].size(); boxIdx++) {
381  amrex::Box pbx = amrex::convert(pb_ba[lev][boxIdx], m_ixtype);
382  if (pt_type[lev] == 3) { pbx.setBig(2, pbx.bigEnd(2) - 1); } // prevent double counting after converting to k-faces
383  amrex::Box ubx = pbx & vbx;
384  if (ubx.ok()) {
385  if (comp == -1) { // vertical velocity perturbations
386  ParallelFor(ubx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
387  src_arr(i,j,k) += pert_cell(i,j,k);
388  });
389  } else {
390  ParallelFor(ubx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
391  src_arr(i,j,k,comp) += pert_cell(i,j,k);
392 
393  // For box region debug only
394  #ifdef INDEX_PERTURB
395  src_arr(i,j,k,comp) = (amrex::Real) (boxIdx + 5.);
396  #endif
397  });
398  }
399  }
400  }
401  }
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
amrex::Vector< amrex::BoxArray > pb_ba
Definition: ERF_TurbPertStruct.H:693
amrex::Vector< int > pt_type
Definition: ERF_TurbPertStruct.H:690

Referenced by make_sources().

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

◆ calc_tpi_amp()

void TurbulentPerturbation::calc_tpi_amp ( const int &  lev,
const int &  boxIdx,
const double &  interval 
)
inline
407  {
408  pb_amp[lev][boxIdx] = zero; // Safety step
409  if (pt_type[lev] == 2) { // CPM
410  amrex::Real cp = 1004; // specific heat of air [J/(kg K)]
411  amrex::Real Ec = amrex::Real(0.2); // Eckert number
412  pb_amp[lev][boxIdx] = (input_Ug * input_Ug) / (Ec * cp);
413  } else if (pt_type[lev] == 3) {
414  pb_amp[lev][boxIdx] = input_w_amp;
415  } else { // box perturbation
416  amrex::Real Um = pb_mag[lev][boxIdx];
417  amrex::Real beta = one/tpi_Tinf; // Thermal expansion coefficient
418 
419  // Pseudo Random temperature the ignores scale when mechanically tripping turbulence
421  // get total refinement ratio on each level
422  int total_ref_ratio = 1;
423  for (int level = lev; level >= 1; level--) {
424  total_ref_ratio *= ref_ratio[level-1][2];
425  }
426  // calculation needs to be scale-aware since the formulation relies on the physical size of the box
427  if (tpi_Ti > zero) g = (tpi_nonDim * Um * Um) / (tpi_Ti * tpi_Hpb[lev]) * 1 / total_ref_ratio;
428 
429  // Ma and Senocak (2023) Eq. 8, solving for delta phi
430  pb_amp[lev][boxIdx] = (tpi_nonDim * Um * Um) / (g * beta * tpi_Hpb[lev]) * 1 / total_ref_ratio;
431 
432  if (pt_type[lev] == 0) {
433  // Performing this step converts the perturbation proportionality into
434  // the forcing term
435  // Ma & Senocak (2023) Eq. 7
436  pb_amp[lev][boxIdx] /= static_cast<amrex::Real>(interval);
437  }
438  }
439  }
constexpr amrex::Real one
Definition: ERF_Constants.H:9
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:64
amrex::Real beta
Definition: ERF_InitCustomPert_DataAssimilation_ISV.H:10
real(c_double), parameter g
Definition: ERF_module_model_constants.F90:19
real(c_double), parameter cp
Definition: ERF_module_model_constants.F90:22
amrex::Real input_w_amp
Definition: ERF_TurbPertStruct.H:726
amrex::Real tpi_Tinf
Definition: ERF_TurbPertStruct.H:713
amrex::Vector< amrex::IntVect > ref_ratio
Definition: ERF_TurbPertStruct.H:724
amrex::Real input_Ug
Definition: ERF_TurbPertStruct.H:725
amrex::Vector< amrex::Vector< amrex::Real > > pb_mag
Definition: ERF_TurbPertStruct.H:694
amrex::Vector< amrex::Real > tpi_Hpb
Definition: ERF_TurbPertStruct.H:716
amrex::Real tpi_Ti
Definition: ERF_TurbPertStruct.H:712
amrex::Real tpi_nonDim
Definition: ERF_TurbPertStruct.H:711
amrex::Vector< amrex::Vector< amrex::Real > > pb_amp
Definition: ERF_TurbPertStruct.H:733

Referenced by calc_tpi_update().

Here is the caller graph for this function:

◆ calc_tpi_meanMag_perBox()

void TurbulentPerturbation::calc_tpi_meanMag_perBox ( const int &  boxIdx,
const int &  lev,
amrex::MultiFab &  mf_cons,
amrex::MultiFab &  mf_xvel,
amrex::MultiFab &  mf_yvel 
)
inline
556  {
557  // Creating local copy of PB box array and magnitude
558  const amrex::BoxArray m_pb_ba = pb_ba[lev];
559  amrex::Real* m_pb_mag = pb_mag[lev].data();
560  amrex::Real* m_pb_dir = pb_dir[lev].data();
561  m_pb_mag[boxIdx] = zero; // Safety step
562  m_pb_dir[boxIdx] = zero; // Safety step
563 
564  // Storage of averages per PB
565  // Index: 0=u (vol/slab_lo), 1=v (vol/slab_lo)
566  // 2=u (slab_hi), 3=v (slab_hi)
567  int n_avg = 4;
568  amrex::Vector<amrex::Real> avg_h(n_avg,zero);
569  amrex::Gpu::DeviceVector<amrex::Real> avg_d(n_avg,zero);
570  amrex::Real* avg = avg_d.data();
571 
572  // Averaging u & v components in single MFIter
573  for (amrex::MFIter mfi(mf_cons, TileNoZ()); mfi.isValid(); ++mfi) {
574 
575  // CC valid box (inherited from mf_cons)
576  const amrex::Box& vbx = mfi.validbox();
577 
578  // Box logic for u velocity
579  auto ixtype_u = mf_xvel.boxArray().ixType();
580  amrex::Box vbx_u = amrex::convert(vbx,ixtype_u);
581  amrex::Box pbx_u = amrex::convert(m_pb_ba[boxIdx], ixtype_u);
582  amrex::Box ubx_u = pbx_u & vbx_u;
583 
584  // Box logic for v velocity
585  auto ixtype_v = mf_yvel.boxArray().ixType();
586  amrex::Box vbx_v = amrex::convert(vbx,ixtype_v);
587  amrex::Box pbx_v = amrex::convert(m_pb_ba[boxIdx], ixtype_v);
588  amrex::Box ubx_v = pbx_v & vbx_v;
589 
590  // Operation over box union (U)
591  if (ubx_u.ok()) {
592  const amrex::Array4<const amrex::Real>& xvel_arry = mf_xvel.const_array(mfi);
593 
594  #ifdef USE_VOLUME_AVERAGE
595  amrex::Real norm = one / static_cast<amrex::Real>(ubx_u.numPts());
596  ParallelFor(amrex::Gpu::KernelInfo().setReduction(true), ubx_u, [=]
597  AMREX_GPU_DEVICE(int i, int j, int k, amrex::Gpu::Handler const& handler) noexcept {
598  amrex::Gpu::deviceReduceSum(&avg[0], xvel_arry(i,j,k)*norm, handler);
599  });
600  #endif // USE_VOLUME_AVERAGE
601 
602  #ifdef USE_SLAB_AVERAGE
603  amrex::Box ubxSlab_lo = makeSlab(ubx_u,2,ubx_u.smallEnd(2));
604  amrex::Box ubxSlab_hi = makeSlab(ubx_u,2,ubx_u.bigEnd(2));
605  amrex::Real norm_lo = one / static_cast<amrex::Real>(ubxSlab_lo.numPts());
606  amrex::Real norm_hi = one / static_cast<amrex::Real>(ubxSlab_hi.numPts());
607 
608  // Average u in the low slab
609  ParallelFor(amrex::Gpu::KernelInfo().setReduction(true), ubxSlab_lo, [=]
610  AMREX_GPU_DEVICE(int i, int j, int k, amrex::Gpu::Handler const& handler) noexcept {
611  amrex::Gpu::deviceReduceSum(&avg[0], xvel_arry(i,j,k)*norm_lo, handler);
612  });
613 
614  // Average u in the high slab
615  ParallelFor(amrex::Gpu::KernelInfo().setReduction(true), ubxSlab_hi, [=]
616  AMREX_GPU_DEVICE(int i, int j, int k, amrex::Gpu::Handler const& handler) noexcept {
617  amrex::Gpu::deviceReduceSum(&avg[2], xvel_arry(i,j,k)*norm_hi, handler);
618  });
619  #endif // USE_SLAB_AVERAGE
620  } // if
621 
622  // Operation over box union (V)
623  if (ubx_v.ok()) {
624  const amrex::Array4<const amrex::Real>& yvel_arry = mf_yvel.const_array(mfi);
625 
626  #ifdef USE_VOLUME_AVERAGE
627  amrex::Real norm = one / static_cast<amrex::Real>(ubx_v.numPts());
628  ParallelFor(amrex::Gpu::KernelInfo().setReduction(true), ubx_v, [=]
629  AMREX_GPU_DEVICE(int i, int j, int k, amrex::Gpu::Handler const& handler) noexcept {
630  amrex::Gpu::deviceReduceSum(&avg[1], yvel_arry(i,j,k)*norm, handler);
631  });
632  #endif // USE_VOLUME_AVERAGE
633 
634  #ifdef USE_SLAB_AVERAGE
635  amrex::Box ubxSlab_lo = makeSlab(ubx_v,2,ubx_v.smallEnd(2));
636  amrex::Box ubxSlab_hi = makeSlab(ubx_v,2,ubx_v.bigEnd(2));
637  amrex::Real norm_lo = one / static_cast<amrex::Real>(ubxSlab_lo.numPts());
638  amrex::Real norm_hi = one / static_cast<amrex::Real>(ubxSlab_hi.numPts());
639 
640  // Average v in the low slab
641  ParallelFor(amrex::Gpu::KernelInfo().setReduction(true), ubxSlab_lo, [=]
642  AMREX_GPU_DEVICE(int i, int j, int k, amrex::Gpu::Handler const& handler) noexcept {
643  amrex::Gpu::deviceReduceSum(&avg[1], yvel_arry(i,j,k)*norm_lo, handler);
644  });
645 
646  // Average v in the high slab
647  ParallelFor(amrex::Gpu::KernelInfo().setReduction(true), ubxSlab_hi, [=]
648  AMREX_GPU_DEVICE(int i, int j, int k, amrex::Gpu::Handler const& handler) noexcept {
649  amrex::Gpu::deviceReduceSum(&avg[3], yvel_arry(i,j,k)*norm_hi, handler);
650  });
651  #endif // USE_SLAB_AVERAGE
652  } // if
653  } // MFIter
654 
655  // Copy from device back to host
656  amrex::Gpu::copy(amrex::Gpu::deviceToHost, avg_d.begin(), avg_d.end(), avg_h.begin());
657 
658  // Computing the average magnitude within PB
659  #ifdef USE_VOLUME_AVERAGE
660  m_pb_mag[boxIdx] = std::sqrt(avg_h[0]*avg_h[0] + avg_h[1]*avg_h[1]);
661  m_pb_dir[boxIdx] = std::atan(std::abs(avg_h[0]) / std::abs(avg_h[1]+std::numeric_limits<amrex::Real>::epsilon()));
662  #endif
663 
664  #ifdef USE_SLAB_AVERAGE
665  m_pb_mag[boxIdx] = myhalf*( std::sqrt(avg_h[0]*avg_h[0] + avg_h[1]*avg_h[1])
666  + std::sqrt(avg_h[2]*avg_h[2] + avg_h[3]*avg_h[3]));
667  m_pb_dir[boxIdx] = std::atan(std::abs(myhalf*(avg_h[0]+avg_h[2])) / std::abs(myhalf*(avg_h[1]+avg_h[3])+std::numeric_limits<amrex::Real>::epsilon()));
668  #endif
669  }
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13
AMREX_FORCE_INLINE amrex::IntVect TileNoZ()
Definition: ERF_TileNoZ.H:11
real(c_double), parameter epsilon
Definition: ERF_module_model_constants.F90:12
amrex::Vector< amrex::Vector< amrex::Real > > pb_dir
Definition: ERF_TurbPertStruct.H:695

Referenced by calc_tpi_update().

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

◆ calc_tpi_update()

void TurbulentPerturbation::calc_tpi_update ( const int  lev,
const double  dt,
amrex::MultiFab &  mf_xvel,
amrex::MultiFab &  mf_yvel,
amrex::MultiFab &  mf_cons 
)
inline
275  {
276  // Resetting the net buoyant force value
278 
279  // Setting random number generator for update interval
280  srand( (unsigned) time(NULL) );
281 
282  auto m_ixtype = mf_cons.boxArray().ixType(); // safety step
283  if (pt_type[lev] == 3) { m_ixtype = amrex::IndexType(amrex::IntVect(0,0,1)); }
284 
285  // Seed the random generator at 1024UL for regression testing
286  int fix_random_seed = 0;
287  amrex::ParmParse pp("erf");
288  pp.query("fix_random_seed", fix_random_seed);
289  if (fix_random_seed) {
290  // We need this one for the ParalleForRNG used in calc_tpi
291  amrex::InitRandom(1024UL, amrex::ParallelDescriptor::NProcs(), 1024UL);
292 
293  // We need this one for the RandomReal below
294  srand(1024UL);
295  }
296 
297  for (int boxIdx = 0; boxIdx < pb_ba[lev].size(); boxIdx++) {
298 
299  bool update_box = true; // initialize flag
300  // Check if the local elapsed time is greater than the update interval and don't go into boxes the rank doesn't own
301  if (pt_type[lev] == 2 || pt_type[lev] == 3) {
302  // for CPM, perturbation boxes/cells refresh after boxes have advected box width/length * num_layers (advective time scale)
303  update_box = ((pb_local_etime[lev][boxIdx] >= pb_interval[lev][boxIdx]*tpi_layers) && pb_local_etime[lev][boxIdx] != -one);
304  } else {
305  update_box = ( pb_local_etime[lev][boxIdx] >= pb_interval[lev][boxIdx] && pb_local_etime[lev][boxIdx] != -one );
306  }
307  if ( update_box ) {
308 
309  // Compute mean velocity of each perturbation box
310  calc_tpi_meanMag_perBox(boxIdx, lev, mf_cons, mf_xvel, mf_yvel);
311 
312  // Only the rank owning the box will be able to access the storage location
313  // Done for parallelism to avoid Inf being stored in array
314  if (pb_mag[lev][boxIdx] !=zero) {
315  double interval = 0.0;
316  if (pt_type[lev] == 2 || pt_type[lev] == 3) {
317  // Wind direction correction for angled wind
318  amrex::Real wind_direction = pb_dir[lev][boxIdx];
319  if (wind_direction > PI / 4) { wind_direction = PI / 2 - wind_direction; }
320  // CPM only cares about the side length of a box, min call maintains flexibility.
321  interval = one / std::cos(wind_direction) * std::min(tpi_Lpb[lev], tpi_Wpb[lev]) / pb_mag[lev][boxIdx];
322  } else {
323  interval = tpi_lref[lev] / pb_mag[lev][boxIdx];
324  }
325  pb_interval[lev][boxIdx] = RandomReal(static_cast<amrex::Real>(0.9*interval),
326  static_cast<amrex::Real>(1.1*interval)); // 10% variation
327 
328  // Reset local elapsed time
329  pb_local_etime[lev][boxIdx] = zero;
330  } else {
331  // this box is not on this rank, we shouldn't enter it again.
332  // Technically, all boxes are looped through on the very first step of a simulation and this is when this is set
333  pb_local_etime[lev][boxIdx] = -one;
334  }
335 
336  // Trigger amplitude calculation per perturbation box
337  calc_tpi_amp(lev, boxIdx, pb_interval[lev][boxIdx]);
338 
339  // Trigger random amplitude storage per cell within perturbation box
340  pseudoRandomPert(boxIdx, lev, m_ixtype);
341 
342  } else {
343  // set perturbation amplitudes to 0 for CPM. A little inefficient but leverages as much as existing code as possible.
344  if (pt_type[lev] == 2 || pt_type[lev] == 3) { zero_amp(boxIdx, lev, m_ixtype); }
345 
346  // Increase by timestep of level 0 (but only if the box is owned by this rank)
347  if (pb_local_etime[lev][boxIdx] != -one) { pb_local_etime[lev][boxIdx] += dt; }
348  } // if
349 
350  if (pt_type[lev] < 2) { // box perturbation method only
351  // Per iteration operation of net-zero buoyant force check
352  if (pb_mag[lev][boxIdx] !=zero) netZeroBuoyantAdd(boxIdx, lev);
353  tpi_net_buoyant += pb_netZero[lev][boxIdx];
354  }
355  } // for
356 
357  if (pt_type[lev] < 2) { // box perturbation method only
358  // Normalizing the adjustment based on how many boxes there are
359  // the values within the array is already normalized by the number
360  // of cells within each box
362 
363  // Per iteration operation of net-zero buoyant force adjustment
364  for (int boxIdx = 0; boxIdx < pb_ba[lev].size(); boxIdx++) {
365  if (pb_mag[lev][boxIdx] !=zero) netZeroBuoyantAdjust(boxIdx, lev);
366  }
367  }
368  }
constexpr amrex::Real PI
Definition: ERF_Constants.H:42
ParmParse pp("prob")
void calc_tpi_amp(const int &lev, const int &boxIdx, const double &interval)
Definition: ERF_TurbPertStruct.H:404
int tpi_layers
Definition: ERF_TurbPertStruct.H:704
void pseudoRandomPert(const int &boxIdx, const int &lev, const amrex::IndexType &m_ixtype)
Definition: ERF_TurbPertStruct.H:444
void netZeroBuoyantAdjust(const int &boxIdx, const int &lev)
Definition: ERF_TurbPertStruct.H:527
amrex::Vector< amrex::Real > tpi_lref
Definition: ERF_TurbPertStruct.H:719
amrex::Vector< amrex::Vector< double > > pb_interval
Definition: ERF_TurbPertStruct.H:731
amrex::Vector< amrex::Vector< amrex::Real > > pb_netZero
Definition: ERF_TurbPertStruct.H:734
amrex::Real tpi_pert_adjust
Definition: ERF_TurbPertStruct.H:722
void zero_amp(const int &boxIdx, const int &lev, const amrex::IndexType &m_ixtype)
Definition: ERF_TurbPertStruct.H:473
amrex::Vector< amrex::Real > tpi_Wpb
Definition: ERF_TurbPertStruct.H:718
void calc_tpi_meanMag_perBox(const int &boxIdx, const int &lev, amrex::MultiFab &mf_cons, amrex::MultiFab &mf_xvel, amrex::MultiFab &mf_yvel)
Definition: ERF_TurbPertStruct.H:550
void netZeroBuoyantAdd(const int &boxIdx, const int &lev)
Definition: ERF_TurbPertStruct.H:493
amrex::Real RandomReal(const amrex::Real min, const amrex::Real max)
Definition: ERF_TurbPertStruct.H:737
amrex::Vector< amrex::Real > tpi_Lpb
Definition: ERF_TurbPertStruct.H:717
amrex::Real tpi_net_buoyant
Definition: ERF_TurbPertStruct.H:721
amrex::Vector< amrex::Vector< double > > pb_local_etime
Definition: ERF_TurbPertStruct.H:732
Here is the call graph for this function:

◆ debug()

void TurbulentPerturbation::debug ( double  )
inline
673  {
674  /*
675  amrex::PrintToFile("BoxPerturbationOutput") << "#################### PB output at time = "
676  << time << " ####################\n";
677  amrex::PrintToFile("BoxPerturbationOutput") << " Using type: " << pt_type << "\n";
678  amrex::PrintToFile("BoxPerturbationOutput") << " Net: " << tpi_net_buoyant << " Adjust : " << tpi_pert_adjust << "\n";
679  for (int i = 0; i < pb_mag.size(); i++) {
680  amrex::PrintToFile("BoxPerturbationOutput") << "[" << i
681  << "] pb_Umag=" << pb_mag[i]
682  << " | pb_interval=" << pb_interval[i]
683  << " (" << pb_local_etime[i]
684  << ") | pb_amp=" << pb_amp[i] << "\n";
685  }
686  amrex::PrintToFile("BoxPerturbationOutput") << "\n";
687  */
688  }

◆ init_tpi()

void TurbulentPerturbation::init_tpi ( const int  lev,
const amrex::Vector< amrex::BoxArray > &  subdomains_lev,
const amrex::GpuArray< amrex::Real, 3 >  dx,
const amrex::BoxArray &  ba,
const amrex::DistributionMapping &  dm,
const int  ngrow_state,
std::string  pp_prefix,
const amrex::Vector< amrex::IntVect >  refRatio,
const int  max_level 
)
inline
64  {
65  ref_ratio = refRatio;
66 
67  amrex::ParmParse pp(pp_prefix);
68 
69  // Reading inputs, and placing assertion for the perturbation inflow to work
70  pp.getarr("perturbation_box_dims",tpi_boxDim);
71  pp.getarr("perturbation_direction",tpi_direction);
72  pp.get("perturbation_layers",tpi_layers);
73  pp.get("perturbation_offset",tpi_offset);
74 
75  tpi_nonDim = zero;
76  pp.query("perturbation_nondimensional",tpi_nonDim);
77 
78  tpi_Tinf = amrex::Real(300.);
79  pp.query("perturbation_T_infinity",tpi_Tinf);
80 
81  tpi_Ti = zero;
82  pp.query("perturbation_T_intensity",tpi_Ti);
83 
84  input_Ug = zero;
85  pp.query("perturbation_Ug",input_Ug);
86 
87  input_w_amp = zero;
88  pp.query("perturbation_w_amp",input_w_amp);
89 
90  perturbation_klo = 0;
91  bool have_klo = pp.query("perturbation_klo", perturbation_klo);
92 
93  perturbation_khi = 0;
94  bool have_khi = pp.query("perturbation_khi", perturbation_khi);
95 
96  // Check variables message
97  if (tpi_offset < 0) { amrex::Abort("Please provide a valid inflow cell offset value for perturbation region (ie. 0-5)"); }
98  if (tpi_layers < 0) { amrex::Abort("Please provide a valid perturbation layer value (ie. 3-5)"); }
99  if (tpi_nonDim < zero) { amrex::Abort("Please provide a valid nondimensional number (ie. Ri = amrex::Real(0.042))"); }
100  for (int i = 0; i < tpi_boxDim.size(); i++) {
101  if (tpi_boxDim[i] < 3) { amrex::Abort("Please provide valid dimensions for perturbation boxes."); }
102  }
103  if (input_Ug < zero) { amrex::Abort("Please provide a valid geostrophic wind speed (ie. Ug = amrex::Real(10.0) m/s)"); }
104  if (tpi_Tinf < zero) { amrex::Abort("Please provide a valid ambient temperature value (ie. T_0 = T_infty)"); }
105  if (tpi_Ti < zero) { amrex::Abort("Please provide a valid temperature intensity value (ie. 0-one)"); }
106 
107  // Create a temporary box list to accumulate all the perturbation regions after box modification
108  amrex::BoxList tmp_bl;
109 
110  // boxSize for individual boxes
111  amrex::IntVect boxSize(tpi_boxDim[0],tpi_boxDim[1],tpi_boxDim[2]);
112 
113  if (tpi_direction[2] || tpi_direction[5]) { amrex::Abort("Currently not supporting z-direction flow perturbation"); }
114 
115  for (int isub = 0; isub < subdomains_lev.size(); ++isub) {
116  const amrex::BoxArray& subdomain = subdomains_lev[isub];
117  amrex::Box subdomain_box(subdomain.minimalBox());
118 
119  if (subdomain_box.numPts() != subdomain.numPts()) {
120  amrex::Abort("Turbulent perturbations require rectangular subdomains. "
121  "Level " + std::to_string(lev) +
122  ", subdomain " + std::to_string(isub) +
123  " is not a rectangular region fully covered by grids.");
124  }
125 
126  const amrex::IntVect& valid_box_lo = subdomain_box.smallEnd();
127  const amrex::IntVect& valid_box_hi = subdomain_box.bigEnd();
128 
129  // default perturbation region to be the entire z extent if the user does not specify bounds
130  if (!have_klo) { perturbation_klo = valid_box_lo[2]; }
131  if (!have_khi) { perturbation_khi = valid_box_hi[2]; }
132 
133  // Creating perturbation regions and initializing with generic size.
134  amrex::Box lo_x_bx(amrex::IntVect(0), amrex::IntVect(1), amrex::IntVect(0));
135  amrex::Box hi_x_bx(amrex::IntVect(0), amrex::IntVect(1), amrex::IntVect(0));
136  amrex::Box lo_y_bx(amrex::IntVect(0), amrex::IntVect(1), amrex::IntVect(0));
137  amrex::Box hi_y_bx(amrex::IntVect(0), amrex::IntVect(1), amrex::IntVect(0));
138 
139  // Starting logic to set the size of the perturbation region(s)
140  //amrex::PrintToFile("BoxPerturbationOutput") << "Setting perturbation region in:";
141  // ***** X-direction perturbation *****
142  if (tpi_direction[0]) { // West
143  lo_x_bx.setSmall(amrex::IntVect(valid_box_lo[0]+tpi_offset, valid_box_lo[1]+tpi_direction[1]*tpi_offset, perturbation_klo));
144  lo_x_bx.setBig (amrex::IntVect(valid_box_lo[0]+(tpi_layers*tpi_boxDim[0]-1)+tpi_offset, valid_box_hi[1]-(tpi_direction[4]*tpi_offset), perturbation_khi));
145  amrex::PrintToFile("BoxPerturbationOutput") << " West face";
146  }
147 
148  if (tpi_direction[3]) { // East
149  hi_x_bx.setSmall(amrex::IntVect(valid_box_hi[0]-((tpi_layers*tpi_boxDim[0]-1)+tpi_offset), valid_box_lo[1]+tpi_direction[1]*tpi_offset, perturbation_klo));
150  hi_x_bx.setBig(amrex::IntVect(valid_box_hi[0]-tpi_offset, valid_box_hi[1]-(tpi_direction[4]*tpi_offset), perturbation_khi));
151  amrex::PrintToFile("BoxPerturbationOutput") << " East face";
152  }
153 
154  // ***** Y-direction Perturbation *****
155  if (tpi_direction[1]) { // North
156  lo_y_bx.setSmall(amrex::IntVect(valid_box_lo[0]+tpi_direction[0]*tpi_offset, valid_box_lo[1]+tpi_offset, perturbation_klo));
157  lo_y_bx.setBig(amrex::IntVect(valid_box_hi[0]-tpi_direction[3]*tpi_offset, valid_box_lo[1]+((tpi_layers*tpi_boxDim[1])-1)+tpi_offset, perturbation_khi));
158  amrex::PrintToFile("BoxPerturbationOutput") << " North face";
159  }
160 
161  if (tpi_direction[4]) { // South
162  hi_y_bx.setSmall(amrex::IntVect(valid_box_lo[0]+tpi_direction[0]*tpi_offset, valid_box_hi[1]-((tpi_layers*tpi_boxDim[1]-1)+tpi_offset), perturbation_klo));
163  hi_y_bx.setBig(amrex::IntVect(valid_box_hi[0]-tpi_direction[3]*tpi_offset, valid_box_hi[1]-tpi_offset, perturbation_khi));
164  amrex::PrintToFile("BoxPerturbationOutput") << " South face";
165  }
166 
167  // Performing box union for intersecting perturbation regions to avoid overlapping sections (double counting at corners)
168  if (tpi_direction[0] && tpi_direction[1]) { // Reshaping South smallEnd
169  amrex::Box lo_x_lo_y_u = lo_x_bx & lo_y_bx;
170  lo_y_bx.setSmall(amrex::IntVect(lo_x_lo_y_u.bigEnd(0)+1, lo_x_lo_y_u.smallEnd(1), lo_x_lo_y_u.smallEnd(2)));
171  }
172 
173  if (tpi_direction[3] && tpi_direction[1]) { // Reshaping South bigEnd
174  amrex::Box hi_x_lo_y_u = hi_x_bx & lo_y_bx;
175  lo_y_bx.setBig(amrex::IntVect(hi_x_lo_y_u.smallEnd(0)-1, hi_x_lo_y_u.bigEnd(1), hi_x_lo_y_u.bigEnd(2)));
176  }
177 
178  if (tpi_direction[0] && tpi_direction[4]) { // Reshaping North smallEnd
179  amrex::Box lo_x_hi_y_u = lo_x_bx & hi_y_bx;
180  hi_y_bx.setSmall(amrex::IntVect(lo_x_hi_y_u.bigEnd(0)+1, lo_x_hi_y_u.smallEnd(1), lo_x_hi_y_u.smallEnd(2)));
181  }
182 
183  if (tpi_direction[3] && tpi_direction[4]) { // Reshaping North bigEnd
184  amrex::Box hi_x_hi_y_u = hi_x_bx & hi_y_bx;
185  hi_y_bx.setBig(amrex::IntVect(hi_x_hi_y_u.smallEnd(0)-1, hi_x_hi_y_u.bigEnd(1), hi_x_hi_y_u.bigEnd(2)));
186  }
187 
188  // Creating structure box array for conserved quantity
189  if (tpi_direction[0]) { tmp_bl.push_back(lo_x_bx); }
190  if (tpi_direction[1]) { tmp_bl.push_back(lo_y_bx); }
191  if (tpi_direction[3]) { tmp_bl.push_back(hi_x_bx); }
192  if (tpi_direction[4]) { tmp_bl.push_back(hi_y_bx); }
193  }
194 
195  //amrex::PrintToFile("BoxPerturbationOutput") << "\nBoxList: " << tmp_bl << "\n";
196  amrex::BoxArray tmp_ba(tmp_bl);
197  tmp_ba.maxSize(boxSize);
198 
199  const int num_levels = max_level + 1;
200  if (pb_ba.size() < num_levels) {
201  pb_ba.resize(num_levels);
202  pb_mag.resize(num_levels);
203  pb_dir.resize(num_levels);
204  pb_netZero.resize(num_levels);
205  pb_interval.resize(num_levels);
206  pb_local_etime.resize(num_levels);
207  pb_amp.resize(num_levels);
208  pb_cell.resize(num_levels);
209  tpi_Lpb.resize(num_levels);
210  tpi_Wpb.resize(num_levels);
211  tpi_Hpb.resize(num_levels);
212  tpi_lref.resize(num_levels);
213  }
214 
215  pb_ba[lev] = tmp_ba;
216 
217  // Initializing mean magnitude and direction vectors
218  pb_mag[lev].resize(pb_ba[lev].size(), zero);
219  pb_dir[lev].resize(pb_ba[lev].size(), zero);
220  pb_netZero[lev].resize(pb_ba[lev].size(), zero);
221 
222  // Set size of vector and initialize
223  pb_interval[lev].resize(pb_ba[lev].size(), -one);
224  pb_local_etime[lev].resize(pb_ba[lev].size(), zero);
225  pb_amp[lev].resize(pb_ba[lev].size(), zero);
226 
227  // Creating data array for perturbation amplitude storage
228  if (pt_type[lev] == 3) { // CPM_W converts to the k-face ba.
229  pb_cell[lev].define(convert(ba, amrex::IntVect(0,0,1)), dm, 1, ngrow_state);
230  } else {
231  pb_cell[lev].define(ba, dm, 1, ngrow_state); // this is the only place ba is used. Maybe we can print here to determine what's valid...
232  }
233  pb_cell[lev].setVal(0.);
234 
235  // Computing perturbation reference length
236  tpi_Lpb[lev] = tpi_boxDim[0]*dx[0];
237  tpi_Wpb[lev] = tpi_boxDim[1]*dx[1];
238  tpi_Hpb[lev] = tpi_boxDim[2]*dx[2];
239  tpi_lref[lev] = std::sqrt(tpi_Lpb[lev]*tpi_Lpb[lev] + tpi_Wpb[lev]*tpi_Wpb[lev]);
240 
243 
244  /*
245  // Function check point message
246  amrex::PrintToFile("BoxPerturbationOutput") << "perturbation_box_dims: "
247  << tpi_boxDim[0] << " "
248  << tpi_boxDim[1] << " "
249  << tpi_boxDim[2] << "\n";
250  amrex::PrintToFile("BoxPerturbationOutput") << "perturbation_direction: "
251  << tpi_direction[0] << " "
252  << tpi_direction[1] << " "
253  << tpi_direction[2] << "\n\n";
254  amrex::PrintToFile("BoxPerturbationOutput") << "perturbation_layers: " << tpi_layers << "\n";
255  amrex::PrintToFile("BoxPerturbationOutput") << "perturbation_offset: " << tpi_offset << "\n\n";
256  amrex::PrintToFile("BoxPerturbationOutput") << "perturbation_nondimensional: " << tpi_nonDim << "\n";
257  amrex::PrintToFile("BoxPerturbationOutput") << "perturbation_T_infinity: " << tpi_Tinf << "\n";
258  amrex::PrintToFile("BoxPerturbationOutput") << "perturbation_T_intensity: " << tpi_Ti << "\n";
259  amrex::PrintToFile("BoxPerturbationOutput") << "Reference length per box = " << tpi_lref[lev] << "\n\n";
260  amrex::PrintToFile("BoxPerturbationOutput") << "Turbulent perturbation BoxArray:\n" << pb_ba[lev] << "\n";
261  */
262  }
const Real dx
Definition: ERF_InitCustomPert_ABL.H:23
integer, private isub
Definition: ERF_module_mp_morr_two_moment.F90:164
amrex::Vector< amrex::MultiFab > pb_cell
Definition: ERF_TurbPertStruct.H:699
int perturbation_khi
Definition: ERF_TurbPertStruct.H:728
int tpi_offset
Definition: ERF_TurbPertStruct.H:705
amrex::Vector< int > tpi_boxDim
Definition: ERF_TurbPertStruct.H:707
int perturbation_klo
Definition: ERF_TurbPertStruct.H:727
amrex::Vector< int > tpi_direction
Definition: ERF_TurbPertStruct.H:708
Here is the call graph for this function:

◆ init_tpi_type()

void TurbulentPerturbation::init_tpi_type ( const int  lev,
const PerturbationType &  pert_type,
const int  max_level 
)
inline
31  {
32  if (pt_type.size() < max_level + 1) {
33  pt_type.resize(max_level + 1, -1);
34  }
35 
36  if (pert_type == PerturbationType::Source) {
37  pt_type[lev] = 0;
38  } else if (pert_type == PerturbationType::Direct) {
39  pt_type[lev] = 1;
40  } else if (pert_type == PerturbationType::CPM) {
41  pt_type[lev] = 2;
42  } else if (pert_type == PerturbationType::CPM_W) {
43  pt_type[lev] = 3;
44  } else {
45  pt_type[lev] = -1;
46  }
47  }

◆ netZeroBuoyantAdd()

void TurbulentPerturbation::netZeroBuoyantAdd ( const int &  boxIdx,
const int &  lev 
)
inline
495  {
496  // Creating local copy of PB box array and magnitude
497  const amrex::BoxArray m_pb_ba = pb_ba[lev];
498  amrex::Real* m_pb_netZero = pb_netZero[lev].data();
499 
500  // Create device array for summation
501  amrex::Vector<amrex::Real> avg_h(1,zero);
502  amrex::Gpu::DeviceVector<amrex::Real> avg_d(1,zero);
503  amrex::Real* avg = avg_d.data();
504 
505  // Iterates through the cells of each box and sum the white noise perturbation
506  for (amrex::MFIter mfi(pb_cell[lev], TileNoZ()) ; mfi.isValid(); ++mfi) {
507  const amrex::Box& vbx = mfi.validbox();
508  amrex::Box pbx = amrex::convert(m_pb_ba[boxIdx], vbx.ixType());
509  amrex::Box ubx = pbx & vbx;
510  if (ubx.ok()) {
511  const amrex::Array4<const amrex::Real>& pert_cell = pb_cell[lev].const_array(mfi);
512  amrex::Real norm = one / static_cast<amrex::Real>(ubx.numPts());
513  ParallelFor(amrex::Gpu::KernelInfo().setReduction(true), ubx, [=]
514  AMREX_GPU_DEVICE(int i, int j, int k, amrex::Gpu::Handler const& handler) noexcept {
515  amrex::Gpu::deviceReduceSum(&avg[0], pert_cell(i,j,k)*norm, handler);
516  });
517  amrex::Gpu::copy(amrex::Gpu::deviceToHost, avg_d.begin(), avg_d.end(), avg_h.begin());
518 
519  // Assigning onto storage array
520  m_pb_netZero[boxIdx] = avg_h[0];
521  }
522  }
523  }

Referenced by calc_tpi_update().

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

◆ netZeroBuoyantAdjust()

void TurbulentPerturbation::netZeroBuoyantAdjust ( const int &  boxIdx,
const int &  lev 
)
inline
529  {
530  // Creating local copy of PB box array and magnitude
531  const amrex::BoxArray m_pb_ba = pb_ba[lev];
532  for (amrex::MFIter mfi(pb_cell[lev], TileNoZ()) ; mfi.isValid(); ++mfi) {
533  const amrex::Box& vbx = mfi.validbox();
534  amrex::Box pbx = amrex::convert(m_pb_ba[boxIdx], vbx.ixType());
535  amrex::Box ubx = pbx & vbx;
536  if (ubx.ok()) {
537  const amrex::Real adjust = tpi_pert_adjust;
538  const amrex::Array4<amrex::Real>& pert_cell = pb_cell[lev].array(mfi);
539  ParallelFor(ubx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
540  pert_cell(i,j,k) -= adjust;
541  });
542  }
543  }
544  }

Referenced by calc_tpi_update().

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

◆ pseudoRandomPert()

void TurbulentPerturbation::pseudoRandomPert ( const int &  boxIdx,
const int &  lev,
const amrex::IndexType &  m_ixtype 
)
inline
447  {
448  for (amrex::MFIter mfi(pb_cell[lev],TileNoZ()); mfi.isValid(); ++mfi) {
449  amrex::Box vbx = mfi.validbox();
450  amrex::Box pbx = amrex::convert(pb_ba[lev][boxIdx], m_ixtype);
451  if (pt_type[lev] == 3) { pbx.setBig(2, pbx.bigEnd(2) - 1); } // prevent double counting after converting to k-faces
452  amrex::Box ubx = pbx & vbx;
453  if (ubx.ok()) {
454  amrex::Real amp_copy = pb_amp[lev][boxIdx];
455  const amrex::Array4<amrex::Real>& pert_cell = pb_cell[lev].array(mfi);
456 
457  if (pt_type[lev] == 2 || pt_type[lev] == 3) { // CPM
458  amrex::Real rand_number_const = RandomReal(-one, one);
459  ParallelFor(ubx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
460  pert_cell(i,j,k) = rand_number_const * amp_copy;
461  });
462  } else {
463  ParallelForRNG(ubx, [=] AMREX_GPU_DEVICE(int i, int j, int k, const amrex::RandomEngine& engine) noexcept {
464  amrex::Real rand_double = amrex::Random(engine);
465  pert_cell(i,j,k) = (rand_double*two - one) * amp_copy;
466  });
467  }
468  }
469  }
470  }
constexpr amrex::Real two
Definition: ERF_Constants.H:10
ParallelForRNG(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k, const amrex::RandomEngine &engine) noexcept { const Real x=prob_lo_x+(i+myhalf) *dx;const Real y=prob_lo_y+(j+myhalf) *dy;const Real z=z_cc(i, j, k);const Real r=std::sqrt((x-xc) *(x-xc)+(y-yc) *(y-yc)+(z-zc) *(z-zc));if((z<=pert_ref_height) &&(T_0_Pert_Mag !=amrex::Real(0))) { Real rand_double=amrex::Random(engine);state_pert(i, j, k, RhoTheta_comp)=(rand_double *amrex::Real(2) - amrex::Real(1)) *T_0_Pert_Mag;if(!pert_rhotheta) { state_pert(i, j, k, RhoTheta_comp) *=r_hse(i, j, k);} } state_pert(i, j, k, RhoScalar_comp)=A_0 *std::exp(-amrex::Real(10.) *r *r);if(state_pert.nComp() > RhoKE_comp) { if(rhoKE_0 > 0) { state_pert(i, j, k, RhoKE_comp)=rhoKE_0;} else { state_pert(i, j, k, RhoKE_comp)=r_hse(i, j, k) *KE_0;} if(KE_decay_height > 0) { state_pert(i, j, k, RhoKE_comp) *=amrex::max(std::pow(1 - amrex::min(z/KE_decay_height, amrex::Real(1)), KE_decay_order), Real(1e-12));} } })

Referenced by calc_tpi_update().

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

◆ RandomReal()

amrex::Real TurbulentPerturbation::RandomReal ( const amrex::Real  min,
const amrex::Real  max 
)
inlineprivate
738  {
739  amrex::Real r = (amrex::Real) rand() / (amrex::Real) RAND_MAX;
740  return min + r * (max - min);
741  }

Referenced by calc_tpi_update(), and pseudoRandomPert().

Here is the caller graph for this function:

◆ zero_amp()

void TurbulentPerturbation::zero_amp ( const int &  boxIdx,
const int &  lev,
const amrex::IndexType &  m_ixtype 
)
inline
476  {
477 
478  for (amrex::MFIter mfi(pb_cell[lev],TileNoZ()); mfi.isValid(); ++mfi) {
479  amrex::Box vbx = mfi.validbox();
480  amrex::Box pbx = amrex::convert(pb_ba[lev][boxIdx], m_ixtype);
481  if (pt_type[lev] == 3) { pbx.setBig(2, pbx.bigEnd(2) - 1); } // prevent double counting after converting to k-faces
482  amrex::Box ubx = pbx & vbx;
483  if (ubx.ok()) {
484  const amrex::Array4<amrex::Real>& pert_cell = pb_cell[lev].array(mfi);
485  ParallelFor(ubx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
486  pert_cell(i,j,k) = zero;
487  });
488  }
489  }
490  }

Referenced by calc_tpi_update().

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

Member Data Documentation

◆ input_Ug

amrex::Real TurbulentPerturbation::input_Ug
private

Referenced by calc_tpi_amp(), and init_tpi().

◆ input_w_amp

amrex::Real TurbulentPerturbation::input_w_amp
private

Referenced by calc_tpi_amp(), and init_tpi().

◆ pb_amp

amrex::Vector<amrex::Vector<amrex::Real> > TurbulentPerturbation::pb_amp
private

◆ pb_ba

amrex::Vector<amrex::BoxArray> TurbulentPerturbation::pb_ba

◆ pb_cell

amrex::Vector<amrex::MultiFab> TurbulentPerturbation::pb_cell

◆ pb_dir

amrex::Vector<amrex::Vector<amrex::Real> > TurbulentPerturbation::pb_dir

◆ pb_interval

amrex::Vector<amrex::Vector<double> > TurbulentPerturbation::pb_interval
private

Referenced by calc_tpi_update(), and init_tpi().

◆ pb_local_etime

amrex::Vector<amrex::Vector<double> > TurbulentPerturbation::pb_local_etime
private

Referenced by calc_tpi_update(), and init_tpi().

◆ pb_mag

amrex::Vector<amrex::Vector<amrex::Real> > TurbulentPerturbation::pb_mag

◆ pb_netZero

amrex::Vector<amrex::Vector<amrex::Real> > TurbulentPerturbation::pb_netZero
private

◆ perturbation_khi

int TurbulentPerturbation::perturbation_khi
private

Referenced by init_tpi().

◆ perturbation_klo

int TurbulentPerturbation::perturbation_klo
private

Referenced by init_tpi().

◆ pt_type

amrex::Vector<int> TurbulentPerturbation::pt_type

◆ ref_ratio

amrex::Vector<amrex::IntVect> TurbulentPerturbation::ref_ratio
private

Referenced by calc_tpi_amp(), and init_tpi().

◆ tpi_boxDim

amrex::Vector<int> TurbulentPerturbation::tpi_boxDim
private

Referenced by init_tpi().

◆ tpi_direction

amrex::Vector<int> TurbulentPerturbation::tpi_direction
private

Referenced by init_tpi().

◆ tpi_Hpb

amrex::Vector<amrex::Real> TurbulentPerturbation::tpi_Hpb
private

Referenced by calc_tpi_amp(), and init_tpi().

◆ tpi_layers

int TurbulentPerturbation::tpi_layers
private

Referenced by calc_tpi_update(), and init_tpi().

◆ tpi_Lpb

amrex::Vector<amrex::Real> TurbulentPerturbation::tpi_Lpb
private

Referenced by calc_tpi_update(), and init_tpi().

◆ tpi_lref

amrex::Vector<amrex::Real> TurbulentPerturbation::tpi_lref
private

Referenced by calc_tpi_update(), and init_tpi().

◆ tpi_net_buoyant

amrex::Real TurbulentPerturbation::tpi_net_buoyant
private

Referenced by calc_tpi_update(), and init_tpi().

◆ tpi_nonDim

amrex::Real TurbulentPerturbation::tpi_nonDim
private

Referenced by calc_tpi_amp(), and init_tpi().

◆ tpi_offset

int TurbulentPerturbation::tpi_offset
private

Referenced by init_tpi().

◆ tpi_pert_adjust

amrex::Real TurbulentPerturbation::tpi_pert_adjust
private

◆ tpi_Ti

amrex::Real TurbulentPerturbation::tpi_Ti
private

Referenced by calc_tpi_amp(), and init_tpi().

◆ tpi_Tinf

amrex::Real TurbulentPerturbation::tpi_Tinf
private

Referenced by calc_tpi_amp(), and init_tpi().

◆ tpi_Wpb

amrex::Vector<amrex::Real> TurbulentPerturbation::tpi_Wpb
private

Referenced by calc_tpi_update(), and init_tpi().


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