1 #ifndef ERF_TURB_PERT_STRUCT_H_
2 #define ERF_TURB_PERT_STRUCT_H_
6 #include <AMReX_MultiFabUtil.H>
20 Source, Direct, CPM, CPM_W, None
42 const PerturbationType& pert_type,
45 if (
pt_type.size() < max_level + 1) {
46 pt_type.resize(max_level + 1, -1);
49 if (pert_type == PerturbationType::Source) {
51 }
else if (pert_type == PerturbationType::Direct) {
53 }
else if (pert_type == PerturbationType::CPM) {
55 }
else if (pert_type == PerturbationType::CPM_W) {
75 const amrex::Vector<amrex::BoxArray>& subdomains_lev,
76 const amrex::GpuArray<amrex::Real,3>
dx,
77 const amrex::BoxArray& ba,
78 const amrex::DistributionMapping& dm,
79 const int ngrow_state,
80 std::string pp_prefix,
81 const amrex::Vector<amrex::IntVect> refRatio,
87 amrex::ParmParse
pp(pp_prefix);
99 pp.queryAdd(
"perturbation_T_infinity",
tpi_Tinf);
102 pp.queryAdd(
"perturbation_T_intensity",
tpi_Ti);
124 if (
tpi_offset < 0) { amrex::Abort(
"Please provide a valid inflow cell offset value for perturbation region (ie. 0-5)"); }
125 if (
tpi_layers < 0) { amrex::Abort(
"Please provide a valid perturbation layer value (ie. 3-5)"); }
126 if (
tpi_nonDim <
zero) { amrex::Abort(
"Please provide a valid nondimensional number (ie. Ri = amrex::Real(0.042))"); }
128 if (
tpi_boxDim[i] < 3) { amrex::Abort(
"Please provide valid dimensions for perturbation boxes."); }
130 if (
input_Ug <
zero) { amrex::Abort(
"Please provide a valid geostrophic wind speed (ie. Ug = amrex::Real(10.0) m/s)"); }
131 if (
tpi_Tinf <
zero) { amrex::Abort(
"Please provide a valid ambient temperature value (ie. T_0 = T_infty)"); }
132 if (
tpi_Ti <
zero) { amrex::Abort(
"Please provide a valid temperature intensity value (ie. 0-one)"); }
135 amrex::BoxList tmp_bl;
142 for (
int isub = 0;
isub < subdomains_lev.size(); ++
isub) {
143 const amrex::BoxArray& subdomain = subdomains_lev[
isub];
144 amrex::Box subdomain_box(subdomain.minimalBox());
146 if (subdomain_box.numPts() != subdomain.numPts()) {
147 amrex::Abort(
"Turbulent perturbations require rectangular subdomains. "
148 "Level " + std::to_string(lev) +
149 ", subdomain " + std::to_string(
isub) +
150 " is not a rectangular region fully covered by grids.");
153 const amrex::IntVect& valid_box_lo = subdomain_box.smallEnd();
154 const amrex::IntVect& valid_box_hi = subdomain_box.bigEnd();
161 amrex::Box lo_x_bx(amrex::IntVect(0), amrex::IntVect(1), amrex::IntVect(0));
162 amrex::Box hi_x_bx(amrex::IntVect(0), amrex::IntVect(1), amrex::IntVect(0));
163 amrex::Box lo_y_bx(amrex::IntVect(0), amrex::IntVect(1), amrex::IntVect(0));
164 amrex::Box hi_y_bx(amrex::IntVect(0), amrex::IntVect(1), amrex::IntVect(0));
172 amrex::PrintToFile(
"BoxPerturbationOutput") <<
" West face";
178 amrex::PrintToFile(
"BoxPerturbationOutput") <<
" East face";
185 amrex::PrintToFile(
"BoxPerturbationOutput") <<
" North face";
191 amrex::PrintToFile(
"BoxPerturbationOutput") <<
" South face";
196 amrex::Box lo_x_lo_y_u = lo_x_bx & lo_y_bx;
197 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)));
201 amrex::Box hi_x_lo_y_u = hi_x_bx & lo_y_bx;
202 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)));
206 amrex::Box lo_x_hi_y_u = lo_x_bx & hi_y_bx;
207 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)));
211 amrex::Box hi_x_hi_y_u = hi_x_bx & hi_y_bx;
212 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)));
223 amrex::BoxArray tmp_ba(tmp_bl);
224 tmp_ba.maxSize(boxSize);
226 const int num_levels = max_level + 1;
227 if (
pb_ba.size() < num_levels) {
228 pb_ba.resize(num_levels);
229 pb_mag.resize(num_levels);
230 pb_dir.resize(num_levels);
234 pb_amp.resize(num_levels);
256 pb_cell[lev].define(convert(ba, amrex::IntVect(0,0,1)), dm, 1, ngrow_state);
258 pb_cell[lev].define(ba, dm, 1, ngrow_state);
302 amrex::MultiFab& mf_xvel,
303 amrex::MultiFab& mf_yvel,
304 amrex::MultiFab& mf_cons)
310 srand( (
unsigned) time(NULL) );
312 auto m_ixtype = mf_cons.boxArray().ixType();
313 if (
pt_type[lev] == 3) { m_ixtype = amrex::IndexType(amrex::IntVect(0,0,1)); }
317 amrex::ParmParse
pp(
"erf");
321 amrex::InitRandom(1024UL, amrex::ParallelDescriptor::NProcs(), 1024UL);
327 for (
int boxIdx = 0; boxIdx <
pb_ba[lev].size(); boxIdx++) {
329 bool update_box =
true;
345 double interval = 0.0;
349 if (wind_direction >
PI / 4) { wind_direction =
PI / 2 - wind_direction; }
394 for (
int boxIdx = 0; boxIdx <
pb_ba[lev].size(); boxIdx++) {
410 const amrex::Box& vbx,
412 const amrex::IndexType& m_ixtype,
413 const amrex::Array4<amrex::Real>& src_arr,
414 const amrex::Array4<amrex::Real const>& pert_cell)
416 for (
int boxIdx = 0; boxIdx <
pb_ba[lev].size(); boxIdx++) {
417 amrex::Box pbx = amrex::convert(
pb_ba[lev][boxIdx], m_ixtype);
418 if (
pt_type[lev] == 3) { pbx.setBig(2, pbx.bigEnd(2) - 1); }
419 amrex::Box ubx = pbx & vbx;
422 ParallelFor(ubx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept {
423 src_arr(i,j,k) += pert_cell(i,j,k);
426 ParallelFor(ubx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k) noexcept {
427 src_arr(i,j,k,comp) += pert_cell(i,j,k);
447 const double& interval)
454 }
else if (
pt_type[lev] == 3) {
463 int total_ref_ratio = 1;
464 for (
int level = lev; level >= 1; level--) {
465 total_ref_ratio *=
ref_ratio[level-1][2];
490 const amrex::IndexType& m_ixtype)
492 for (amrex::MFIter mfi(
pb_cell[lev],
TileNoZ()); mfi.isValid(); ++mfi) {
493 amrex::Box vbx = mfi.validbox();
494 amrex::Box pbx = amrex::convert(
pb_ba[lev][boxIdx], m_ixtype);
495 if (
pt_type[lev] == 3) { pbx.setBig(2, pbx.bigEnd(2) - 1); }
496 amrex::Box ubx = pbx & vbx;
499 const amrex::Array4<amrex::Real>& pert_cell =
pb_cell[lev].array(mfi);
503 ParallelFor(ubx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept {
504 pert_cell(i,j,k) = rand_number_const * amp_copy;
507 ParallelForRNG(ubx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k,
const amrex::RandomEngine& engine) noexcept {
509 pert_cell(i,j,k) = (rand_double*
two -
one) * amp_copy;
524 const amrex::IndexType& m_ixtype)
527 for (amrex::MFIter mfi(
pb_cell[lev],
TileNoZ()); mfi.isValid(); ++mfi) {
528 amrex::Box vbx = mfi.validbox();
529 amrex::Box pbx = amrex::convert(
pb_ba[lev][boxIdx], m_ixtype);
530 if (
pt_type[lev] == 3) { pbx.setBig(2, pbx.bigEnd(2) - 1); }
531 amrex::Box ubx = pbx & vbx;
533 const amrex::Array4<amrex::Real>& pert_cell =
pb_cell[lev].array(mfi);
534 ParallelFor(ubx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept {
535 pert_cell(i,j,k) =
zero;
550 const amrex::BoxArray m_pb_ba =
pb_ba[lev];
554 amrex::Vector<amrex::Real> avg_h(1,
zero);
555 amrex::Gpu::DeviceVector<amrex::Real> avg_d(1,
zero);
559 for (amrex::MFIter mfi(
pb_cell[lev],
TileNoZ()) ; mfi.isValid(); ++mfi) {
560 const amrex::Box& vbx = mfi.validbox();
561 amrex::Box pbx = amrex::convert(m_pb_ba[boxIdx], vbx.ixType());
562 amrex::Box ubx = pbx & vbx;
564 const amrex::Array4<const amrex::Real>& pert_cell =
pb_cell[lev].const_array(mfi);
566 ParallelFor(amrex::Gpu::KernelInfo().setReduction(
true), ubx, [=]
567 AMREX_GPU_DEVICE(
int i,
int j,
int k, amrex::Gpu::Handler
const& handler) noexcept {
568 amrex::Gpu::deviceReduceSum(&avg[0], pert_cell(i,j,k)*norm, handler);
570 amrex::Gpu::copy(amrex::Gpu::deviceToHost, avg_d.begin(), avg_d.end(), avg_h.begin());
573 m_pb_netZero[boxIdx] = avg_h[0];
587 const amrex::BoxArray m_pb_ba =
pb_ba[lev];
588 for (amrex::MFIter mfi(
pb_cell[lev],
TileNoZ()) ; mfi.isValid(); ++mfi) {
589 const amrex::Box& vbx = mfi.validbox();
590 amrex::Box pbx = amrex::convert(m_pb_ba[boxIdx], vbx.ixType());
591 amrex::Box ubx = pbx & vbx;
594 const amrex::Array4<amrex::Real>& pert_cell =
pb_cell[lev].array(mfi);
595 ParallelFor(ubx, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept {
596 pert_cell(i,j,k) -= adjust;
603 #define USE_VOLUME_AVERAGE
614 amrex::MultiFab& mf_cons,
615 amrex::MultiFab& mf_xvel,
616 amrex::MultiFab& mf_yvel)
620 const amrex::BoxArray m_pb_ba =
pb_ba[lev];
623 m_pb_mag[boxIdx] =
zero;
624 m_pb_dir[boxIdx] =
zero;
630 amrex::Vector<amrex::Real> avg_h(n_avg,
zero);
631 amrex::Gpu::DeviceVector<amrex::Real> avg_d(n_avg,
zero);
635 for (amrex::MFIter mfi(mf_cons,
TileNoZ()); mfi.isValid(); ++mfi) {
638 const amrex::Box& vbx = mfi.validbox();
641 auto ixtype_u = mf_xvel.boxArray().ixType();
642 amrex::Box vbx_u = amrex::convert(vbx,ixtype_u);
643 amrex::Box pbx_u = amrex::convert(m_pb_ba[boxIdx], ixtype_u);
644 amrex::Box ubx_u = pbx_u & vbx_u;
647 auto ixtype_v = mf_yvel.boxArray().ixType();
648 amrex::Box vbx_v = amrex::convert(vbx,ixtype_v);
649 amrex::Box pbx_v = amrex::convert(m_pb_ba[boxIdx], ixtype_v);
650 amrex::Box ubx_v = pbx_v & vbx_v;
654 const amrex::Array4<const amrex::Real>& xvel_arry = mf_xvel.const_array(mfi);
656 #ifdef USE_VOLUME_AVERAGE
658 ParallelFor(amrex::Gpu::KernelInfo().setReduction(
true), ubx_u, [=]
659 AMREX_GPU_DEVICE(
int i,
int j,
int k, amrex::Gpu::Handler
const& handler) noexcept {
660 amrex::Gpu::deviceReduceSum(&avg[0], xvel_arry(i,j,k)*norm, handler);
664 #ifdef USE_SLAB_AVERAGE
665 amrex::Box ubxSlab_lo = makeSlab(ubx_u,2,ubx_u.smallEnd(2));
666 amrex::Box ubxSlab_hi = makeSlab(ubx_u,2,ubx_u.bigEnd(2));
671 ParallelFor(amrex::Gpu::KernelInfo().setReduction(
true), ubxSlab_lo, [=]
672 AMREX_GPU_DEVICE(
int i,
int j,
int k, amrex::Gpu::Handler
const& handler) noexcept {
673 amrex::Gpu::deviceReduceSum(&avg[0], xvel_arry(i,j,k)*norm_lo, handler);
677 ParallelFor(amrex::Gpu::KernelInfo().setReduction(
true), ubxSlab_hi, [=]
678 AMREX_GPU_DEVICE(
int i,
int j,
int k, amrex::Gpu::Handler
const& handler) noexcept {
679 amrex::Gpu::deviceReduceSum(&avg[2], xvel_arry(i,j,k)*norm_hi, handler);
686 const amrex::Array4<const amrex::Real>& yvel_arry = mf_yvel.const_array(mfi);
688 #ifdef USE_VOLUME_AVERAGE
690 ParallelFor(amrex::Gpu::KernelInfo().setReduction(
true), ubx_v, [=]
691 AMREX_GPU_DEVICE(
int i,
int j,
int k, amrex::Gpu::Handler
const& handler) noexcept {
692 amrex::Gpu::deviceReduceSum(&avg[1], yvel_arry(i,j,k)*norm, handler);
696 #ifdef USE_SLAB_AVERAGE
697 amrex::Box ubxSlab_lo = makeSlab(ubx_v,2,ubx_v.smallEnd(2));
698 amrex::Box ubxSlab_hi = makeSlab(ubx_v,2,ubx_v.bigEnd(2));
703 ParallelFor(amrex::Gpu::KernelInfo().setReduction(
true), ubxSlab_lo, [=]
704 AMREX_GPU_DEVICE(
int i,
int j,
int k, amrex::Gpu::Handler
const& handler) noexcept {
705 amrex::Gpu::deviceReduceSum(&avg[1], yvel_arry(i,j,k)*norm_lo, handler);
709 ParallelFor(amrex::Gpu::KernelInfo().setReduction(
true), ubxSlab_hi, [=]
710 AMREX_GPU_DEVICE(
int i,
int j,
int k, amrex::Gpu::Handler
const& handler) noexcept {
711 amrex::Gpu::deviceReduceSum(&avg[3], yvel_arry(i,j,k)*norm_hi, handler);
718 amrex::Gpu::copy(amrex::Gpu::deviceToHost, avg_d.begin(), avg_d.end(), avg_h.begin());
721 #ifdef USE_VOLUME_AVERAGE
722 m_pb_mag[boxIdx] = std::sqrt(avg_h[0]*avg_h[0] + avg_h[1]*avg_h[1]);
726 #ifdef USE_SLAB_AVERAGE
727 m_pb_mag[boxIdx] =
myhalf*( std::sqrt(avg_h[0]*avg_h[0] + avg_h[1]*avg_h[1])
728 + std::sqrt(avg_h[2]*avg_h[2] + avg_h[3]*avg_h[3]));
757 amrex::Vector<amrex::BoxArray>
pb_ba;
758 amrex::Vector<amrex::Vector<amrex::Real>>
pb_mag;
759 amrex::Vector<amrex::Vector<amrex::Real>>
pb_dir;
797 amrex::Vector<amrex::Vector<amrex::Real>>
pb_amp;
809 return min + r * (max - min);
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:56
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;if(deterministic_ic_pert) { rand_double=erf_hash_rng::hash_uniform(i, j, k, temperature_hash_comp, lev, ic_pert_seed);} else { 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);} } if(add_sinusoidal_T) { const Real zl=z/pert_ref_height;const Real damp=std::exp(-myhalf *zl *zl);const Real rho=state(i, j, k, Rho_comp);const Real rhotheta=state(i, j, k, RhoTheta_comp);const Real qv=(use_moisture) ? state(i, j, k, RhoQ1_comp)/rho :amrex::Real(0);const Real Told=getTgivenRandRTh(rho, rhotheta, qv);const Real P=getPgivenRTh(rhotheta, qv);const Real Tnew=Told+tfac *damp *z *std::cos(cval *(x - xc));const Real theta_new=getThgivenTandP(Tnew, P, rdOcp);const Real rho_new=getRhogivenThetaPress(theta_new, P, rdOcp, qv);state_pert(i, j, k, Rho_comp)+=rho_new - rho;if(use_moisture) { state_pert(i, j, k, RhoQ1_comp)+=(rho_new - rho) *qv;} } 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) { const Real z_sfc=(use_eb) ? zero :fourth *(z_nd(i, j, klo)+z_nd(i+1, j, klo)+z_nd(i, j+1, klo)+z_nd(i+1, j+1, klo));const Real z_agl=z_cc(i, j, k) - z_sfc;state_pert(i, j, k, RhoKE_comp) *=amrex::max(std::pow(1 - amrex::min(z_agl/KE_decay_height, amrex::Real(1)), KE_decay_order), amrex::Real(1e-12));} } })
int fix_random_seed
Definition: ERF_InitCustomPert_ABL.H:5
const Real dx
Definition: ERF_InitCustomPert_ABL.H:44
amrex::Real beta
Definition: ERF_InitCustomPert_DataAssimilation_ISV.H:10
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);})
constexpr amrex::Real two
Definition: ERF_NumericalConstants.H:31
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:30
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:29
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:34
constexpr amrex::Real PI
Definition: ERF_NumericalConstants.H:39
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_FORCE_INLINE amrex::IntVect TileNoZ()
Definition: ERF_TileNoZ.H:11
AMREX_ENUM(PerturbationType, Source, Direct, CPM, CPM_W, None)
real(c_double), parameter g
Definition: ERF_module_model_constants.F90:19
real(c_double), parameter epsilon
Definition: ERF_module_model_constants.F90:12
real(c_double), parameter cp
Definition: ERF_module_model_constants.F90:22
integer, private isub
Definition: ERF_module_mp_morr_two_moment.F90:164
Runtime state and operations for turbulent perturbation forcing.
Definition: ERF_TurbPertStruct.H:26
amrex::Real tpi_Tinf
Reference temperature used by the perturbation formulation [K].
Definition: ERF_TurbPertStruct.H:777
int tpi_layers
Number of layers of perturbation boxes.
Definition: ERF_TurbPertStruct.H:768
amrex::Vector< amrex::Real > tpi_Wpb
Perturbation-box width for each AMR level [m].
Definition: ERF_TurbPertStruct.H:782
amrex::Real input_w_amp
Input vertical velocity perturbation amplitude.
Definition: ERF_TurbPertStruct.H:790
void calc_tpi_update(const int lev, const double dt, amrex::MultiFab &mf_xvel, amrex::MultiFab &mf_yvel, amrex::MultiFab &mf_cons)
Update perturbation amplitudes and intervals when each box is ready.
Definition: ERF_TurbPertStruct.H:300
void calc_tpi_amp(const int &lev, const int &boxIdx, const double &interval)
Compute the perturbation amplitude for one perturbation box.
Definition: ERF_TurbPertStruct.H:445
void pseudoRandomPert(const int &boxIdx, const int &lev, const amrex::IndexType &m_ixtype)
Assign pseudo-random perturbations to cells in one perturbation box.
Definition: ERF_TurbPertStruct.H:488
amrex::Real tpi_pert_adjust
Per-cell perturbation adjustment used for net-zero buoyancy.
Definition: ERF_TurbPertStruct.H:786
amrex::Vector< int > tpi_direction
Boundary directions where perturbations are applied.
Definition: ERF_TurbPertStruct.H:772
int perturbation_klo
Lower vertical index bound for perturbations.
Definition: ERF_TurbPertStruct.H:791
int tpi_offset
Cell offset for the start of the perturbation region.
Definition: ERF_TurbPertStruct.H:769
amrex::Vector< amrex::Real > tpi_Lpb
Perturbation-box length for each AMR level [m].
Definition: ERF_TurbPertStruct.H:781
amrex::Vector< amrex::Vector< amrex::Real > > pb_netZero
Per-box storage used for net-zero buoyancy calculation.
Definition: ERF_TurbPertStruct.H:798
void netZeroBuoyantAdjust(const int &boxIdx, const int &lev)
Adjust perturbation cells so the net buoyant forcing is zero.
Definition: ERF_TurbPertStruct.H:583
amrex::Vector< amrex::Vector< amrex::Real > > pb_mag
Mean velocity magnitude for each perturbation box [m/s].
Definition: ERF_TurbPertStruct.H:758
amrex::Real tpi_net_buoyant
Accumulated net buoyant perturbation used for correction.
Definition: ERF_TurbPertStruct.H:785
amrex::Vector< amrex::Vector< amrex::Real > > pb_dir
Mean velocity direction for each perturbation box.
Definition: ERF_TurbPertStruct.H:759
amrex::Real input_Ug
Input geostrophic wind speed used to scale CPM perturbations.
Definition: ERF_TurbPertStruct.H:789
amrex::Vector< int > tpi_boxDim
Dimensions of each perturbation box.
Definition: ERF_TurbPertStruct.H:771
amrex::Vector< amrex::Vector< double > > pb_interval
Perturbation update interval for each box [s].
Definition: ERF_TurbPertStruct.H:795
void init_tpi_type(const int lev, const PerturbationType &pert_type, const int max_level)
Store the integer perturbation-type selector for one AMR level.
Definition: ERF_TurbPertStruct.H:41
void debug(double)
Write perturbation debug information when debug output is enabled.
Definition: ERF_TurbPertStruct.H:736
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)
Initialize turbulent perturbation regions and per-box storage.
Definition: ERF_TurbPertStruct.H:74
amrex::Vector< amrex::Vector< double > > pb_local_etime
Local elapsed time for each perturbation box [s].
Definition: ERF_TurbPertStruct.H:796
amrex::Vector< amrex::Real > tpi_lref
Perturbation-box reference length for each AMR level [m].
Definition: ERF_TurbPertStruct.H:783
amrex::Vector< amrex::MultiFab > pb_cell
Per-cell perturbation amplitude storage.
Definition: ERF_TurbPertStruct.H:763
void zero_amp(const int &boxIdx, const int &lev, const amrex::IndexType &m_ixtype)
Reset CPM perturbation amplitudes in one perturbation box to zero.
Definition: ERF_TurbPertStruct.H:522
amrex::Vector< amrex::IntVect > ref_ratio
Refinement ratios used by multilevel perturbation scaling.
Definition: ERF_TurbPertStruct.H:788
int perturbation_khi
Upper vertical index bound for perturbations.
Definition: ERF_TurbPertStruct.H:792
void calc_tpi_meanMag_perBox(const int &boxIdx, const int &lev, amrex::MultiFab &mf_cons, amrex::MultiFab &mf_xvel, amrex::MultiFab &mf_yvel)
Compute mean horizontal velocity magnitude and direction for one perturbation box.
Definition: ERF_TurbPertStruct.H:612
amrex::Real tpi_Ti
Temperature intensity used by the perturbation formulation.
Definition: ERF_TurbPertStruct.H:776
amrex::Vector< amrex::BoxArray > pb_ba
Perturbation-box BoxArray for each AMR level.
Definition: ERF_TurbPertStruct.H:757
void netZeroBuoyantAdd(const int &boxIdx, const int &lev)
Accumulate the mean perturbation contribution for net-zero buoyancy enforcement.
Definition: ERF_TurbPertStruct.H:546
~TurbulentPerturbation()
Destroy turbulent perturbation state.
Definition: ERF_TurbPertStruct.H:33
amrex::Real RandomReal(const amrex::Real min, const amrex::Real max)
Return a pseudo-random real value in a closed interval.
Definition: ERF_TurbPertStruct.H:806
amrex::Vector< int > pt_type
Integer perturbation type for each AMR level.
Definition: ERF_TurbPertStruct.H:754
amrex::Vector< amrex::Vector< amrex::Real > > pb_amp
Perturbation amplitude for each perturbation box.
Definition: ERF_TurbPertStruct.H:797
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)
Apply stored turbulent perturbations to a source or state array.
Definition: ERF_TurbPertStruct.H:409
amrex::Real tpi_nonDim
Nondimensional number used by the perturbation formulation.
Definition: ERF_TurbPertStruct.H:775
amrex::Vector< amrex::Real > tpi_Hpb
Perturbation-box height for each AMR level [m].
Definition: ERF_TurbPertStruct.H:780