Skip to content

Commit

Permalink
This commit successfully runs the DensityCurrent problem in anelastic…
Browse files Browse the repository at this point in the history
… mode (#1822)
  • Loading branch information
asalmgren committed Sep 19, 2024
1 parent 6b4e94f commit 741364b
Show file tree
Hide file tree
Showing 8 changed files with 281 additions and 229 deletions.
16 changes: 14 additions & 2 deletions Exec/RegTests/DensityCurrent/ERF_prob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Problem::init_custom_pert(
const SolverChoice& sc)
{
const bool use_moisture = (sc.moisture_type != MoistureType::None);
const bool is_anelastic = (sc.anelastic[0] == 1);

const Real l_x_r = parms.x_r;
//const Real l_x_r = parms.x_r * mf_u(0,0,0); //used to validate constant msf
Expand All @@ -70,15 +71,21 @@ Problem::init_custom_pert(
Real L = std::sqrt(
std::pow((x - l_x_c)/l_x_r, 2) +
std::pow((z - l_z_c)/l_z_r, 2));

if (L <= 1.0)
{
Real dT = l_Tpt * (std::cos(PI*L) + 1.0)/2.0;
Real Tbar_hse = p_hse(i,j,k) / (R_d * r_hse(i,j,k));

// Note: dT is a perturbation in temperature, theta_perturbed is base state + perturbation
Real theta_perturbed = (Tbar_hse+dT)*std::pow(p_0/p_hse(i,j,k), rdOcp);
Real theta_0 = (Tbar_hse )*std::pow(p_0/p_hse(i,j,k), rdOcp);

state_pert(i, j, k, Rho_comp) = getRhoThetagivenP(p_hse(i,j,k)) / theta_perturbed - r_hse(i,j,k);
if (is_anelastic) {
state_pert(i, j, k, RhoTheta_comp) = r_hse(i,j,k) * (theta_perturbed - theta_0);
} else {
state_pert(i, j, k, Rho_comp) = getRhoThetagivenP(p_hse(i,j,k)) / theta_perturbed - r_hse(i,j,k);
}
}

// Set scalar = 0 everywhere
Expand Down Expand Up @@ -109,8 +116,13 @@ Problem::init_custom_pert(

// Note: dT is a perturbation in temperature, theta_perturbed is base state + perturbation
Real theta_perturbed = (Tbar_hse+dT)*std::pow(p_0/p_hse(i,j,k), rdOcp);
Real theta_0 = (Tbar_hse )*std::pow(p_0/p_hse(i,j,k), rdOcp);

state_pert(i, j, k, Rho_comp) = getRhoThetagivenP(p_hse(i,j,k)) / theta_perturbed - r_hse(i,j,k);
if (is_anelastic) {
state_pert(i, j, k, RhoTheta_comp) = r_hse(i,j,k) * (theta_perturbed - theta_0);
} else {
state_pert(i, j, k, Rho_comp) = getRhoThetagivenP(p_hse(i,j,k)) / theta_perturbed - r_hse(i,j,k);
}
}

// Set scalar = 0 everywhere
Expand Down
74 changes: 74 additions & 0 deletions Exec/RegTests/DensityCurrent/inputs_anelastic
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# ------------------ INPUTS TO MAIN PROGRAM -------------------
max_step = 999999
stop_time = 900.0

erf.anelastic = 1
erf.no_substepping = 1
erf.buoyancy_type = 2

erf.use_terrain = true
erf.use_terrain = false

amrex.fpe_trap_invalid = 1

fabarray.mfiter_tile_size = 1024 1024 1024

# PROBLEM SIZE & GEOMETRY

#geometry.prob_lo = -12800. 0. 0.
#geometry.prob_hi = 12800. 1600. 6400.
#xlo.type = "Outflow"

geometry.prob_lo = 0. 0. 0.
geometry.prob_hi = 25600. 1600. 6400.
xlo.type = "Symmetry"

xhi.type = "Outflow"

geometry.is_periodic = 0 1 0

amr.n_cell = 256 16 64 # dx=dy=dz=100 m, Straka et al 1993 / Xue et al 2000

zlo.type = "SlipWall"
zhi.type = "SlipWall"

# TIME STEP CONTROL
erf.fixed_dt = 1.0 # fixed time step [s] -- Straka et al 1993
erf.fixed_fast_dt = 0.25 # fixed time step [s] -- Straka et al 1993

# DIAGNOSTICS & VERBOSITY
erf.sum_interval = 1 # timesteps between computing mass
erf.v = 0 # verbosity in ERF.cpp
erf.mg_v = 1 # verbosity in ERF.cpp
amr.v = 1 # verbosity in Amr.cpp

# REFINEMENT / REGRIDDING
amr.max_level = 0 # maximum level number allowed

# CHECKPOINT FILES
erf.check_file = chk # root name of checkpoint file
erf.check_int = -57600 # number of timesteps between checkpoints

# PLOTFILES
erf.plot_file_1 = plta # prefix of plotfile name
erf.plot_int_1 = 100 # number of timesteps between plotfiles
erf.plot_vars_1 = density x_velocity y_velocity z_velocity pressure theta pres_hse dens_hse pert_pres pert_dens

# SOLVER CHOICE
erf.use_gravity = true
erf.use_coriolis = false

erf.les_type = "None"
#
# diffusion coefficient from Straka, K = 75 m^2/s
#
erf.molec_diff_type = "ConstantAlpha"
erf.rho0_trans = 1.0 # [kg/m^3], used to convert input diffusivities
erf.dynamicViscosity = 75.0 # [kg/(m-s)] ==> nu = 75.0 m^2/s
erf.alpha_T = 0.0 # [m^2/s]

erf.c_p = 1004.0

# PROBLEM PARAMETERS (optional)
prob.T_0 = 300.0
prob.U_0 = 0.0
20 changes: 11 additions & 9 deletions Exec/RegTests/DensityCurrent/inputs_crse_halfdomain
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# ------------------ INPUTS TO MAIN PROGRAM -------------------
max_step = 999999
stop_time = 900.0
max_step = 100

erf.use_terrain = true
erf.use_terrain = false
Expand All @@ -11,16 +10,19 @@ amrex.fpe_trap_invalid = 1
fabarray.mfiter_tile_size = 1024 1024 1024

# PROBLEM SIZE & GEOMETRY
#geometry.prob_lo = -12800. 0. 0.
#geometry.prob_hi = 12800. 1600. 6400.
#xlo.type = "Outflow"

geometry.prob_lo = 0. 0. 0.
geometry.prob_hi = 25600. 400. 6400.
geometry.prob_hi = 25600. 1600. 6400.
xlo.type = "Symmetry"

amr.n_cell = 256 4 64 # dx=dy=dz=100 m, Straka et al 1993 / Xue et al 2000
xhi.type = "Outflow"

# periodic in x to match WRF setup
# - as an alternative, could use symmetry at x=0 and outflow at x=25600
geometry.is_periodic = 0 1 0
xlo.type = "Symmetry"
xhi.type = "Outflow"

amr.n_cell = 256 16 64 # dx=dy=dz=100 m, Straka et al 1993 / Xue et al 2000

zlo.type = "SlipWall"
zhi.type = "SlipWall"
Expand All @@ -42,8 +44,8 @@ erf.check_file = chk # root name of checkpoint file
erf.check_int = -57600 # number of timesteps between checkpoints

# PLOTFILES
erf.plot_file_1 = plt # prefix of plotfile name
erf.plot_int_1 = 100 # number of timesteps between plotfiles
erf.plot_file_1 = pltc # prefix of plotfile name
erf.plot_int_1 = 10 # number of timesteps between plotfiles
erf.plot_vars_1 = density x_velocity y_velocity z_velocity pressure theta pres_hse dens_hse pert_pres pert_dens

# SOLVER CHOICE
Expand Down
3 changes: 0 additions & 3 deletions Exec/RegTests/WitchOfAgnesi/ERF_prob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ Problem::init_custom_pert (
Array4<Real const> const& /*mf_v*/,
const SolverChoice& sc)
{
//const int khi = geomdata.Domain().bigEnd()[2];
//AMREX_ALWAYS_ASSERT(bx.length()[2] == khi+1);

const bool use_moisture = (sc.moisture_type != MoistureType::None);

ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
Expand Down
14 changes: 13 additions & 1 deletion Source/DataStructs/ERF_DataStruct.H
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,19 @@ struct SolverChoice {
for (int i = 0; i <= max_level; ++i) anelastic.push_back(anelastic_in[0]);
}

pp.query("constant_density", constant_density);
bool any_anelastic = false;
for (int i = 0; i <= max_level; ++i) {
if (anelastic[i] == 1) any_anelastic = true;
}

// If anelastic at all, we do not advect rho -- it is always == rho0
if (any_anelastic == 1) {
constant_density = true;
} else {
constant_density = false; // We default to false but allow the user to set it
pp.query("constant_density", constant_density);
}

pp.query("project_every_stage", project_every_stage);
pp.query("ncorr", ncorr);
pp.query("poisson_abstol", poisson_abstol);
Expand Down
15 changes: 13 additions & 2 deletions Source/ERF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1627,17 +1627,23 @@ ERF::MakeHorizontalAverages ()
auto domain = geom[0].Domain();

bool use_moisture = (solverChoice.moisture_type != MoistureType::None);
bool is_anelastic = (solverChoice.anelastic[lev] == 1);

for (MFIter mfi(mf); mfi.isValid(); ++mfi) {
const Box& bx = mfi.validbox();
auto fab_arr = mf.array(mfi);
auto const hse_arr = base_state[lev].const_array(mfi);
auto const cons_arr = vars_new[lev][Vars::cons].const_array(mfi);
ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) {
Real dens = cons_arr(i, j, k, Rho_comp);
fab_arr(i, j, k, 0) = dens;
fab_arr(i, j, k, 1) = cons_arr(i, j, k, RhoTheta_comp) / dens;
if (!use_moisture) {
fab_arr(i, j, k, 2) = getPgivenRTh(cons_arr(i, j, k, RhoTheta_comp));
if (is_anelastic) {
fab_arr(i,j,k,2) = hse_arr(i,j,k,1);
} else {
fab_arr(i,j,k,2) = getPgivenRTh(cons_arr(i,j,k,RhoTheta_comp));
}
}
});
}
Expand All @@ -1647,13 +1653,18 @@ ERF::MakeHorizontalAverages ()
for (MFIter mfi(mf); mfi.isValid(); ++mfi) {
const Box& bx = mfi.validbox();
auto fab_arr = mf.array(mfi);
auto const hse_arr = base_state[lev].const_array(mfi);
auto const cons_arr = vars_new[lev][Vars::cons].const_array(mfi);
auto const qv_arr = qmoist[lev][0]->const_array(mfi);
int ncomp = vars_new[lev][Vars::cons].nComp();

ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) {
Real dens = cons_arr(i, j, k, Rho_comp);
fab_arr(i, j, k, 2) = getPgivenRTh(cons_arr(i, j, k, RhoTheta_comp), qv_arr(i,j,k));
if (is_anelastic) {
fab_arr(i,j,k,2) = hse_arr(i,j,k,1);
} else {
fab_arr(i, j, k, 2) = getPgivenRTh(cons_arr(i, j, k, RhoTheta_comp), qv_arr(i,j,k));
}
fab_arr(i, j, k, 3) = (ncomp > RhoQ1_comp ? cons_arr(i, j, k, RhoQ1_comp) / dens : 0.0);
fab_arr(i, j, k, 4) = (ncomp > RhoQ2_comp ? cons_arr(i, j, k, RhoQ2_comp) / dens : 0.0);
});
Expand Down
103 changes: 62 additions & 41 deletions Source/IO/ERF_Plotfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,47 +345,61 @@ ERF::WritePlotFile (int which, Vector<std::string> plot_var_names)

if (containerHasElement(plot_var_names, "pressure"))
{
if (solverChoice.anelastic[lev] == 1) {
MultiFab::Copy(mf[lev], p_hse, 0, mf_comp, 1, 0);
} else
#ifdef _OPENMP
#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
#endif
for ( MFIter mfi(mf[lev],TilingIfNotGPU()); mfi.isValid(); ++mfi)
{
const Box& bx = mfi.tilebox();
const Array4<Real >& derdat = mf[lev].array(mfi);
const Array4<Real const>& S_arr = vars_new[lev][Vars::cons].const_array(mfi);
const int ncomp = vars_new[lev][Vars::cons].nComp();

ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
for ( MFIter mfi(mf[lev],TilingIfNotGPU()); mfi.isValid(); ++mfi)
{
Real qv_for_p = (use_moisture && (ncomp > RhoQ1_comp)) ? S_arr(i,j,k,RhoQ1_comp)/S_arr(i,j,k,Rho_comp) : 0;
const Real rhotheta = S_arr(i,j,k,RhoTheta_comp);
derdat(i, j, k, mf_comp) = getPgivenRTh(rhotheta,qv_for_p);
});
}
const Box& bx = mfi.tilebox();
const Array4<Real >& derdat = mf[lev].array(mfi);
const Array4<Real const>& S_arr = vars_new[lev][Vars::cons].const_array(mfi);
const int ncomp = vars_new[lev][Vars::cons].nComp();

ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
{
Real qv_for_p = (use_moisture && (ncomp > RhoQ1_comp)) ? S_arr(i,j,k,RhoQ1_comp)/S_arr(i,j,k,Rho_comp) : 0;
const Real rhotheta = S_arr(i,j,k,RhoTheta_comp);
derdat(i, j, k, mf_comp) = getPgivenRTh(rhotheta,qv_for_p);
});
}
} // not anelastic
mf_comp += 1;
}
} // pressure

if (containerHasElement(plot_var_names, "pert_pres"))
{
#ifdef ERF_USE_POISSON_SOLVE
if (solverChoice.anelastic[lev] == 1) {
MultiFab::Copy(mf[lev], pp_inc[lev], 0, mf_comp, 1, 0);
} else
#endif
#ifdef _OPENMP
#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
#endif
for ( MFIter mfi(mf[lev],TilingIfNotGPU()); mfi.isValid(); ++mfi)
{
const Box& bx = mfi.tilebox();
const Array4<Real>& derdat = mf[lev].array(mfi);
const Array4<Real const>& p0_arr = p_hse.const_array(mfi);
const Array4<Real const>& S_arr = vars_new[lev][Vars::cons].const_array(mfi);
const int ncomp = vars_new[lev][Vars::cons].nComp();

ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
for ( MFIter mfi(mf[lev],TilingIfNotGPU()); mfi.isValid(); ++mfi)
{
Real qv_for_p = (use_moisture && (ncomp > RhoQ1_comp)) ? S_arr(i,j,k,RhoQ1_comp)/S_arr(i,j,k,Rho_comp) : 0;
const Real rhotheta = S_arr(i,j,k,RhoTheta_comp);
derdat(i, j, k, mf_comp) = getPgivenRTh(rhotheta,qv_for_p) - p0_arr(i,j,k);
});
}
const Box& bx = mfi.tilebox();
const Array4<Real>& derdat = mf[lev].array(mfi);
const Array4<Real const>& p0_arr = p_hse.const_array(mfi);
const Array4<Real const>& S_arr = vars_new[lev][Vars::cons].const_array(mfi);
const int ncomp = vars_new[lev][Vars::cons].nComp();

ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept
{
Real qv_for_p = (use_moisture && (ncomp > RhoQ1_comp)) ? S_arr(i,j,k,RhoQ1_comp)/S_arr(i,j,k,Rho_comp) : 0;
const Real rhotheta = S_arr(i,j,k,RhoTheta_comp);
derdat(i, j, k, mf_comp) = getPgivenRTh(rhotheta,qv_for_p) - p0_arr(i,j,k);
});
}
} // not anelastic
mf_comp += 1;
}

if (containerHasElement(plot_var_names, "pert_dens"))
{
#ifdef _OPENMP
Expand Down Expand Up @@ -475,11 +489,18 @@ ERF::WritePlotFile (int which, Vector<std::string> plot_var_names)
{
// First define pressure on grown box
const Box& gbx = mfi.growntilebox(1);
const Array4<Real> & p_arr = pres.array(mfi);
const Array4<Real > & p_arr = pres.array(mfi);
const Array4<Real const> & hse_arr = base_state[lev].const_array(mfi);
const Array4<Real const>& S_arr = vars_new[lev][Vars::cons].const_array(mfi);
ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
p_arr(i,j,k) = getPgivenRTh(S_arr(i,j,k,RhoTheta_comp));
});
if (solverChoice.anelastic[lev] == 1) {
ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
p_arr(i,j,k) = hse_arr(i,j,k,1);
});
} else {
ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
p_arr(i,j,k) = getPgivenRTh(S_arr(i,j,k,RhoTheta_comp));
});
}
}
pres.FillBoundary(geom[lev].periodicity());

Expand Down Expand Up @@ -562,11 +583,18 @@ ERF::WritePlotFile (int which, Vector<std::string> plot_var_names)
{
// First define pressure on grown box
const Box& gbx = mfi.growntilebox(1);
const Array4<Real> & p_arr = pres.array(mfi);
const Array4<Real > & p_arr = pres.array(mfi);
const Array4<Real const> & hse_arr = base_state[lev].const_array(mfi);
const Array4<Real const>& S_arr = vars_new[lev][Vars::cons].const_array(mfi);
ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
p_arr(i,j,k) = getPgivenRTh(S_arr(i,j,k,RhoTheta_comp));
});
if (solverChoice.anelastic[lev] == 1) {
ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
p_arr(i,j,k) = hse_arr(i,j,k,1);
});
} else {
ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept {
p_arr(i,j,k) = getPgivenRTh(S_arr(i,j,k,RhoTheta_comp));
});
}
}
pres.FillBoundary(geom[lev].periodicity());

Expand Down Expand Up @@ -1076,13 +1104,6 @@ ERF::WritePlotFile (int which, Vector<std::string> plot_var_names)
}
#endif

#ifdef ERF_USE_POISSON_SOLVE
if (containerHasElement(plot_var_names, "pp_inc")) {
MultiFab::Copy(mf[lev], pp_inc[lev], 0, mf_comp, 1, 0);
mf_comp += 1;
}
#endif

#ifdef ERF_COMPUTE_ERROR
// Next, check for error in velocities and if desired, output them -- note we output none or all, not just some
if (containerHasElement(plot_var_names, "xvel_err") ||
Expand Down
Loading

0 comments on commit 741364b

Please sign in to comment.