Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simplify queries for PBL and LES parameters per level #1772

Merged
merged 16 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Docs/sphinx_doc/Inputs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,8 @@ If we set ``erf.molec_diff_type`` to ``ConstantAlpha``, then

- ``erf.alpha_C`` is multiplied by the instantaneous local density :math:`\rho` to form the coefficient for an advected scalar.

Parameters for LES can either be set with one value that applies across all levels, or set with a number of values
equal to the number of levels, allowing unique values of the parameter to be set for each level.

PBL Scheme
==========
Expand Down Expand Up @@ -928,6 +930,9 @@ transport equation, it is optional to advect QKE, and to apply LES diffusive tra
in the horizontal directions (the vertical component is always computed as part of the PBL
scheme).

Parameters for PBL schemes can either be set with one value that applies across all levels, or set with a number of values
equal to the number of levels, allowing unique values of the parameter to be set for each level.

Forcing Terms
=============

Expand Down
2 changes: 1 addition & 1 deletion Exec/ABL/inputs_GABLS1_mynn25
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ erf.les_type = "None"
#erf.rho0_trans = 1.3223 # from Cuxart et al. 2006
#erf.theta_ref = 263.5 # from Cuxart et al. 2006

erf.pbl_type = "MYNN2.5"
erf.pbl_type = MYNN25

# Initial conditions from Beare et al. 2006
prob.KE_0 = 0.4 # [m2/s2]
Expand Down
297 changes: 80 additions & 217 deletions Source/DataStructs/TurbStruct.H
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,25 @@

#include <MYNNStruct.H>

enum struct LESType {
None, Smagorinsky, Deardorff
};

enum struct PBLType {
None, MYNN25, YSU
};

AMREX_ENUM(LESType, None, Smagorinsky, Deardorff);

AMREX_ENUM(PBLType, None, MYNN25, YSU);

template <typename T>
void query_one_or_per_level(const amrex::ParmParse& pp, const char* query_string, T& query_var, const int lev, const int maxlev)
{
int count = pp.countval(query_string);
if (count == 0) {
return; // nothing to do
} else if (count == 1) {
pp.query(query_string, query_var);
} else if (count == maxlev + 1) {
pp.query(query_string, query_var, lev);
} else {
amrex::Error("For parmparse variable " + pp.prefixedName(query_string)
+ ": if specified, specify once total or once for each level");
}
}

/**
* Container holding quantities related to turbulence parametrizations
Expand All @@ -21,230 +32,82 @@ struct TurbChoice {
{
amrex::ParmParse pp(pp_prefix);

int nvals_les = pp.countval("les_type");
int nvals_pbl = pp.countval("pbl_type");

// If nvals_les and nvals_pbl are both zero then we skip everything below
if ( (nvals_les == 0) && (nvals_pbl == 0) ) {
les_type = LESType::None;
pbl_type = PBLType::None;
return;
}

// If nvals_les and nvals_pbl are both > 0 then they must be the same, and either 1 or max_levels
if ( (nvals_les > 0) && (nvals_pbl > 0) ) {
if (nvals_les != nvals_pbl) {
amrex::Error("If specifying both, we must specify the same number of values for les_type and pbl_type");
}
if (nvals_les != 1 && nvals_les != max_level+1) {
amrex::Error("If specifying both, we must either input one value for all levels, or one value per level");
}
}

// Here we cover the case where either one is 1 and the other is 0, or they both are = 1
if (nvals_les == 1 || nvals_pbl == 1) {

// Which LES closure?
std::string les_type_string = "None";
pp.query("les_type",les_type_string);

if (!les_type_string.compare("Smagorinsky")) {
les_type = LESType::Smagorinsky;
} else if (!les_type_string.compare("Deardorff")) {
les_type = LESType::Deardorff;
} else if (!les_type_string.compare("None")) {
les_type = LESType::None; // Means DNS
} else {
amrex::Error("Don't know this les_type");
}
// Which LES closure?
std::string les_type_string = "None";
query_one_or_per_level(pp, "les_type", les_type, lev, max_level);

// Which PBL Closure
static std::string pbl_type_string = "None";
pp.query("pbl_type",pbl_type_string);
if (pbl_type_string == "MYNN2.5") {
pbl_type = PBLType::MYNN25;
} else if (pbl_type_string == "YSU") {
pbl_type = PBLType::YSU;
} else if (pbl_type_string == "None") {
pbl_type = PBLType::None;
} else {
amrex::Error("Don't know this pbl_type");
}
// Which PBL Closure
static std::string pbl_type_string = "None";
query_one_or_per_level(pp, "pbl_type", pbl_type, lev, max_level);

// Do some more stuff for PBL Modeling
if (pbl_type != PBLType::None) {
// Check for compatibility between PBL, LES, Molec Transport
if (les_type == LESType::Deardorff) {
amrex::Error("It is not recommended to use Deardorff LES and a PBL model");
} else if (les_type != LESType::None) {
amrex::Print() << "Selected a PBL model and an LES model: " <<
// Do some more stuff for PBL Modeling
if (pbl_type != PBLType::None) {
// Check for compatibility between PBL, LES, Molec Transport
if (les_type != LESType::None) {
amrex::Print() << "Selected a PBL model and an LES model: " <<
"Using PBL for vertical transport, LES for horizontal" << std::endl;
}

if (pbl_type == PBLType::MYNN25) {
pp.query("pbl_mynn_A1", pbl_mynn.A1);
pp.query("pbl_mynn_A2", pbl_mynn.A2);
pp.query("pbl_mynn_B1", pbl_mynn.B1);
pp.query("pbl_mynn_B2", pbl_mynn.B2);
pp.query("pbl_mynn_C1", pbl_mynn.C1);
pp.query("pbl_mynn_C2", pbl_mynn.C2);
pp.query("pbl_mynn_C3", pbl_mynn.C3);
pp.query("pbl_mynn_C4", pbl_mynn.C4);
pp.query("pbl_mynn_C5", pbl_mynn.C5);
pbl_mynn_level2.init_coeffs(pbl_mynn.A1, pbl_mynn.A2, pbl_mynn.B1, pbl_mynn.B2,
pbl_mynn.C1, pbl_mynn.C2, pbl_mynn.C3, pbl_mynn.C4, pbl_mynn.C5);
pp.query("pbl_mynn_diffuse_moistvars", pbl_mynn.diffuse_moistvars);
pp.query("pbl_mynn_SMmin", pbl_mynn.SMmin);
pp.query("pbl_mynn_SMmax", pbl_mynn.SMmax);
pp.query("pbl_mynn_SHmin", pbl_mynn.SHmin);
pp.query("pbl_mynn_SHmax", pbl_mynn.SHmax);

std::string mynn_cfg_string = "default";
pp.query("pbl_mynn_config", mynn_cfg_string);
if (!mynn_cfg_string.compare("ChenBryan2021")) {
pbl_mynn.config = MYNNConfigType::CHEN2021;
} else {
pbl_mynn.config = MYNNConfigType::NN09;
}
} else if (pbl_type == PBLType::YSU) {
pp.query("pbl_ysu_coriolis_freq", pbl_ysu_coriolis_freq);
pp.query("pbl_ysu_use_consistent_coriolis", pbl_ysu_use_consistent_coriolis);
pp.query("pbl_ysu_force_over_water", pbl_ysu_force_over_water);
pp.query("pbl_ysu_land_Ribcr", pbl_ysu_land_Ribcr);
pp.query("pbl_ysu_unst_Ribcr", pbl_ysu_unst_Ribcr);
}
} else if (les_type == LESType::Deardorff) {
amrex::Error("It is not recommended to use Deardorff LES and a PBL model");
}

// Right now, solving the QKE equation is only supported when MYNN PBL is turned on
if (pbl_type == PBLType::MYNN25) {
use_QKE = true;
pp.query("advect_QKE", advect_QKE); // Whether to include advection term in transport eqn
pp.query("diffuse_QKE_3D", diffuse_QKE_3D); // Note: This only controls whether numerical diffusion is
// added to QKE; the vertical diffusion operator is
// always calculated and gives
// d/dz[K d(qke)/dz] = d/dz<w'(qke)'>,
// which is the turbulent transport of QKE.
}

// LES constants...
pp.query("Cs" , Cs);
pp.query("CI" , CI);
pp.query("Pr_t", Pr_t);
pp.query("Sc_t", Sc_t);

// Compute relevant forms of diffusion parameters
Pr_t_inv = amrex::Real(1.0) / Pr_t;
Sc_t_inv = amrex::Real(1.0) / Sc_t;

pp.query("Ce" , Ce);
pp.query("Ce_wall" , Ce_wall);
pp.query("sigma_k" , sigma_k);

if (les_type == LESType::Deardorff) {
pp.query("Ck" , Ck);
}

pp.query("theta_ref", theta_ref);

// Validate inputs
if (les_type == LESType::Smagorinsky) {
if (Cs == 0) {
amrex::Error("Need to specify Cs for Smagorsinky LES");
}
}

// Here we cover the case where either one is > 1 and the other is 0, or they both are the same and > 1
} else {

// Which LES closure?
std::string les_type_string = "None";
pp.get("les_type", les_type_string, lev);

if (!les_type_string.compare("Smagorinsky")) {
les_type = LESType::Smagorinsky;
} else if (!les_type_string.compare("Deardorff")) {
les_type = LESType::Deardorff;
} else if (!les_type_string.compare("None")) {
les_type = LESType::None; // Means DNS
} else {
amrex::Error("Don't know this les_type");
}

// Which PBL Closure
static std::string pbl_type_string = "None";
pp.get("pbl_type", pbl_type_string, lev);
if (pbl_type_string == "MYNN2.5") {
pbl_type = PBLType::MYNN25;
} else if (pbl_type_string == "YSU") {
pbl_type = PBLType::YSU;
} else if (pbl_type_string == "None") {
pbl_type = PBLType::None;
} else {
amrex::Error("Don't know this pbl_type");
query_one_or_per_level(pp, "pbl_mynn_A1", pbl_mynn.A1, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_A2", pbl_mynn.A2, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_B1", pbl_mynn.B1, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_B2", pbl_mynn.B2, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_C1", pbl_mynn.C1, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_C2", pbl_mynn.C2, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_C3", pbl_mynn.C3, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_C4", pbl_mynn.C4, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_C5", pbl_mynn.C5, lev, max_level);
pbl_mynn_level2.init_coeffs(pbl_mynn.A1, pbl_mynn.A2, pbl_mynn.B1, pbl_mynn.B2,
pbl_mynn.C1, pbl_mynn.C2, pbl_mynn.C3, pbl_mynn.C4, pbl_mynn.C5);
query_one_or_per_level(pp, "pbl_mynn_diffuse_moistvars", pbl_mynn.diffuse_moistvars, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_SMmin", pbl_mynn.SMmin, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_SMmax", pbl_mynn.SMmax, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_SHmin", pbl_mynn.SHmin, lev, max_level);
query_one_or_per_level(pp, "pbl_mynn_SHmax", pbl_mynn.SHmax, lev, max_level);
} else if (pbl_type == PBLType::YSU) {
query_one_or_per_level(pp, "pbl_ysu_coriolis_freq", pbl_ysu_coriolis_freq, lev, max_level);
query_one_or_per_level(pp, "pbl_ysu_use_consistent_coriolis", pbl_ysu_use_consistent_coriolis, lev, max_level);
query_one_or_per_level(pp, "pbl_ysu_force_over_water", pbl_ysu_force_over_water, lev, max_level);
query_one_or_per_level(pp, "pbl_ysu_land_Ribcr", pbl_ysu_land_Ribcr, lev, max_level);
query_one_or_per_level(pp, "pbl_ysu_unst_Ribcr", pbl_ysu_unst_Ribcr, lev, max_level);
}
}

// Do some more stuff for PBL Modeling
if (pbl_type != PBLType::None) {
// Check for compatibility between PBL, LES, Molec Transport
if (les_type != LESType::None) {
amrex::Print() << "Selected a PBL model and an LES model: " <<
"Using PBL for vertical transport, LES for horizontal" << std::endl;
} else if (les_type == LESType::Deardorff) {
amrex::Error("It is not recommended to use Deardorff LES and a PBL model");
}
// Right now, solving the QKE equation is only supported when MYNN PBL is turned on
if (pbl_type == PBLType::MYNN25) {
use_QKE = true;
query_one_or_per_level(pp, "advect_QKE" , advect_QKE, lev, max_level);
query_one_or_per_level(pp, "diffuse_QKE_3D", diffuse_QKE_3D, lev, max_level);
}

if (pbl_type == PBLType::MYNN25) {
pp.query("pbl_mynn_A1", pbl_mynn.A1, lev);
pp.query("pbl_mynn_A2", pbl_mynn.A2, lev);
pp.query("pbl_mynn_B1", pbl_mynn.B1, lev);
pp.query("pbl_mynn_B2", pbl_mynn.B2, lev);
pp.query("pbl_mynn_C1", pbl_mynn.C1, lev);
pp.query("pbl_mynn_C2", pbl_mynn.C2, lev);
pp.query("pbl_mynn_C3", pbl_mynn.C3, lev);
pp.query("pbl_mynn_C4", pbl_mynn.C4, lev);
pp.query("pbl_mynn_C5", pbl_mynn.C5, lev);
pbl_mynn_level2.init_coeffs(pbl_mynn.A1, pbl_mynn.A2, pbl_mynn.B1, pbl_mynn.B2,
pbl_mynn.C1, pbl_mynn.C2, pbl_mynn.C3, pbl_mynn.C4, pbl_mynn.C5);
pp.query("pbl_mynn_diffuse_moistvars", pbl_mynn.diffuse_moistvars, lev);
pp.query("pbl_mynn_SMmin", pbl_mynn.SMmin);
pp.query("pbl_mynn_SMmax", pbl_mynn.SMmax);
pp.query("pbl_mynn_SHmin", pbl_mynn.SHmin);
pp.query("pbl_mynn_SHmax", pbl_mynn.SHmax);
} else if (pbl_type == PBLType::YSU) {
pp.query("pbl_ysu_coriolis_freq", pbl_ysu_coriolis_freq);
pp.query("pbl_ysu_use_consistent_coriolis", pbl_ysu_use_consistent_coriolis);
pp.query("pbl_ysu_force_over_water", pbl_ysu_force_over_water);
pp.query("pbl_ysu_land_Ribcr", pbl_ysu_land_Ribcr);
pp.query("pbl_ysu_unst_Ribcr", pbl_ysu_unst_Ribcr);
}
}
// LES constants...
query_one_or_per_level(pp, "Cs" ,Cs, lev, max_level);
query_one_or_per_level(pp, "CI" ,CI, lev, max_level);
query_one_or_per_level(pp, "Pr_t",Pr_t, lev, max_level);
query_one_or_per_level(pp, "Sc_t",Sc_t, lev, max_level);

// Right now, solving the QKE equation is only supported when MYNN PBL is turned on
if (pbl_type == PBLType::MYNN25) {
use_QKE = true;
pp.query("advect_QKE" , advect_QKE, lev);
pp.query("diffuse_QKE_3D", diffuse_QKE_3D, lev);
}
// Compute relevant forms of diffusion parameters
Pr_t_inv = amrex::Real(1.0) / Pr_t;
Sc_t_inv = amrex::Real(1.0) / Sc_t;

// LES constants...
pp.query("Cs" ,Cs, lev);
pp.query("CI" ,CI, lev);
pp.query("Pr_t",Pr_t, lev);
pp.query("Sc_t",Sc_t, lev);
query_one_or_per_level(pp, "Ce" , Ce, lev, max_level);
query_one_or_per_level(pp, "Ce_wall" , Ce_wall, lev, max_level);
query_one_or_per_level(pp, "sigma_k" , sigma_k, lev, max_level);

// Compute relevant forms of diffusion parameters
Pr_t_inv = amrex::Real(1.0) / Pr_t;
Sc_t_inv = amrex::Real(1.0) / Sc_t;
if (les_type == LESType::Deardorff) {
query_one_or_per_level(pp, "Ck" , Ck, lev, max_level);
}

pp.query("Ce" , Ce, lev);
pp.query("Ce_wall" , Ce_wall, lev);
pp.query("sigma_k" , sigma_k, lev);
query_one_or_per_level(pp, "theta_ref", theta_ref, lev, max_level);

if (les_type == LESType::Deardorff) {
pp.query("Ck" , Ck, lev);
// Validate inputs
if (les_type == LESType::Smagorinsky) {
if (Cs == 0) {
amrex::Error("Need to specify Cs for Smagorsinky LES");
}

pp.query("theta_ref", theta_ref, lev);
}
}

Expand Down
2 changes: 1 addition & 1 deletion Submodules/AMReX
Submodule AMReX updated 34 files
+1 −0 .github/workflows/cuda.yml
+1 −1 .github/workflows/style/check_tabs.sh
+1 −1 .github/workflows/style/check_trailing_whitespaces.sh
+2 −2 Docs/sphinx_documentation/source/RuntimeParameters.rst
+1 −0 Src/AmrCore/AMReX_FillPatchUtil.H
+101 −36 Src/AmrCore/AMReX_FillPatchUtil_I.H
+36 −1 Src/Base/AMReX_Arena.H
+50 −2 Src/Base/AMReX_Arena.cpp
+4 −1 Src/Base/AMReX_BArena.cpp
+0 −12 Src/Base/AMReX_CArena.H
+8 −31 Src/Base/AMReX_CArena.cpp
+174 −87 Src/Base/AMReX_CTOParallelForImpl.H
+3 −3 Src/Base/AMReX_GpuPrint.H
+2 −0 Src/Base/AMReX_PArena.cpp
+46 −16 Src/Base/AMReX_ParmParse.H
+17 −17 Src/Base/AMReX_ParmParse.cpp
+2 −1 Src/Base/AMReX_TinyProfiler.H
+51 −25 Src/Base/AMReX_TinyProfiler.cpp
+4 −0 Src/Base/AMReX_parmparse_mod.F90
+5 −2 Src/EB/AMReX_EB2_IndexSpace_STL.cpp
+5 −2 Src/EB/AMReX_EB2_IndexSpace_chkpt_file.cpp
+4 −0 Src/F_Interfaces/AmrCore/AMReX_fluxregister_mod.F90
+4 −0 Src/F_Interfaces/Base/AMReX_boxarray_mod.F90
+4 −0 Src/F_Interfaces/Base/AMReX_distromap_mod.F90
+4 −0 Src/F_Interfaces/Base/AMReX_fab_mod.F90
+4 −0 Src/F_Interfaces/Base/AMReX_geometry_mod.F90
+12 −0 Src/F_Interfaces/Base/AMReX_multifab_mod.F90
+8 −2 Src/F_Interfaces/Base/AMReX_multifabutil_fi.cpp
+25 −1 Src/F_Interfaces/Base/AMReX_multifabutil_mod.F90
+4 −0 Src/F_Interfaces/Base/AMReX_physbc_mod.F90
+4 −0 Src/F_Interfaces/LinearSolvers/AMReX_abeclaplacian_mod.F90
+4 −0 Src/F_Interfaces/LinearSolvers/AMReX_multigrid_mod.F90
+4 −0 Src/F_Interfaces/LinearSolvers/AMReX_poisson_mod.F90
+4 −0 Src/F_Interfaces/Particle/AMReX_particlecontainer_mod.F90
4 changes: 2 additions & 2 deletions Tests/test_files/ABL_MYNN_PBL/ABL_MYNN_PBL.i
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ------------------ INPUTS TO MAIN PROGRAM -------------------
stop_time = 32400.0 # 540 min = 9 h (Cuxart et al. 2006)
max_step = 100

amrex.fpe_trap_invalid = 0

fabarray.mfiter_tile_size = 1024 1024 1024
Expand Down Expand Up @@ -72,7 +72,7 @@ erf.les_type = "None"
#erf.rho0_trans = 1.3223 # from Cuxart et al. 2006
#erf.theta_ref = 263.5 # from Cuxart et al. 2006

erf.pbl_type = "MYNN2.5"
erf.pbl_type = "MYNN25"

# Initial conditions from Beare et al. 2006
prob.KE_0 = 0.4 # [m2/s2]
Expand Down
Loading