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

Fast eddy microphysics clean up #1336

Merged
merged 32 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7c03e4b
Changes to EOS.H with moisture
Oct 10, 2023
4a20716
Change all functions in EOS.H to work with moisture
Oct 10, 2023
c082747
Merge remote-tracking branch 'upstream/development' into development
Nov 15, 2023
5e60056
Adding qp for buoyancy type 1
Nov 15, 2023
5582efc
Updating docs for buoyancy term
Nov 15, 2023
ee79839
Updating docs for buoyancy term
Nov 15, 2023
38c2861
Update docs for buoyancy
Nov 15, 2023
fb48acc
Avoiding extra divide
Nov 16, 2023
926ad1e
Update buoyancy docs
Nov 16, 2023
c3ac150
Merge branch 'development' into development
asalmgren Nov 16, 2023
fe0b6d6
Some corrections to buoyancy docs
Nov 16, 2023
c960497
Merge branch 'development' of https://github.com/nataraj2/ERF into de…
Nov 16, 2023
4d6053f
Merge remote-tracking branch 'upstream/development' into development
Nov 16, 2023
a89a48f
Some corrections to Docs in buoyancy
Nov 16, 2023
ab100b4
Correcting docs issue
Nov 16, 2023
026eba2
Merge remote-tracking branch 'upstream/development' into development
Nov 16, 2023
d277d33
Correcting docs
Nov 16, 2023
051117a
adding Kessler microphysics docs
Nov 16, 2023
16e76d7
adding Kessler microphysics docs
Nov 16, 2023
f33cdd8
adding Kessler microphysics docs
Nov 16, 2023
a0bb74d
adding Kessler microphysics docs
Nov 16, 2023
4a0d660
Merge remote-tracking branch 'upstream/development' into development
Nov 17, 2023
92f5266
Merge remote-tracking branch 'upstream/development' into development
Nov 29, 2023
2bf340f
Merge remote-tracking branch 'upstream/development' into development
Nov 30, 2023
56957bd
Updating inputs
Nov 30, 2023
1407387
Adding inputs for Gabersek test case:
Dec 3, 2023
59439a7
Correcting VisIt plot issue
Dec 7, 2023
398ce20
Reverting changes
Dec 11, 2023
f740568
Merging current development
Dec 11, 2023
bb7f3a8
Reverting changes
Dec 11, 2023
56dac28
FastEddy microphysics clean up
Dec 11, 2023
91257bc
FastEddy microphysics clean up
Dec 11, 2023
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
33 changes: 0 additions & 33 deletions Source/Microphysics/FastEddy/Diagnose_FE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,4 @@
* from the existing Microphysics variables.
*/
void FastEddy::Diagnose () {

auto qt = mic_fab_vars[MicVar_FE::qt];
auto qp = mic_fab_vars[MicVar_FE::qp];
auto qv = mic_fab_vars[MicVar_FE::qv];
auto qn = mic_fab_vars[MicVar_FE::qn];
auto qcl = mic_fab_vars[MicVar_FE::qcl];
auto qci = mic_fab_vars[MicVar_FE::qci];
auto qpl = mic_fab_vars[MicVar_FE::qpl];
auto qpi = mic_fab_vars[MicVar_FE::qpi];
auto tabs = mic_fab_vars[MicVar_FE::tabs];

for ( amrex::MFIter mfi(*tabs, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) {
auto qt_array = qt->array(mfi);
auto qp_array = qp->array(mfi);
auto qv_array = qv->array(mfi);
auto qn_array = qn->array(mfi);
auto qcl_array = qcl->array(mfi);
auto qci_array = qci->array(mfi);
auto qpl_array = qpl->array(mfi);
auto qpi_array = qpi->array(mfi);

const auto& box3d = mfi.tilebox();

amrex::ParallelFor(box3d, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
qv_array(i,j,k) = std::max(0.0,qt_array(i,j,k) - qn_array(i,j,k));
amrex::Real omn = 1.0;
qcl_array(i,j,k) = qn_array(i,j,k)*omn;
qci_array(i,j,k) = qn_array(i,j,k)*(1.0-omn);
amrex::Real omp = 1.0;;
qpl_array(i,j,k) = qp_array(i,j,k)*omp;
qpi_array(i,j,k) = qp_array(i,j,k)*(1.0-omp);
});
}
}
15 changes: 2 additions & 13 deletions Source/Microphysics/FastEddy/FastEddy.H
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,11 @@
namespace MicVar_FE {
enum {
// independent variables
qt = 0,
qp,
qv = 0,
qc,
theta, // liquid/ice water potential temperature
tabs, // temperature
rho, // density
pres, // pressure
// derived variables
qr, // rain water
qv, // water vapor
qn, // cloud condensate (liquid+ice), initial to zero
qci, // cloud ice
qcl, // cloud water
qpl, // precip rain
qpi, // precip ice
// temporary variable
omega,
NumVars
};
}
Expand Down
201 changes: 29 additions & 172 deletions Source/Microphysics/FastEddy/FastEddy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,201 +13,58 @@ using namespace amrex;
*/
void FastEddy::AdvanceFE() {

auto qt = mic_fab_vars[MicVar_FE::qt];
auto qp = mic_fab_vars[MicVar_FE::qp];
auto qn = mic_fab_vars[MicVar_FE::qn];
auto tabs = mic_fab_vars[MicVar_FE::tabs];
auto tabs = mic_fab_vars[MicVar_FE::tabs];

auto qcl = mic_fab_vars[MicVar_FE::qcl];
auto theta = mic_fab_vars[MicVar_FE::theta];
auto qv = mic_fab_vars[MicVar_FE::qv];
auto rho = mic_fab_vars[MicVar_FE::rho];

auto dz = m_geom.CellSize(2);
auto domain = m_geom.Domain();
int k_lo = domain.smallEnd(2);
int k_hi = domain.bigEnd(2);

MultiFab fz;
auto ba = tabs->boxArray();
auto dm = tabs->DistributionMap();
fz.define(convert(ba, IntVect(0,0,1)), dm, 1, 0); // No ghost cells

for ( MFIter mfi(fz, TilingIfNotGPU()); mfi.isValid(); ++mfi ){
auto rho_array = mic_fab_vars[MicVar_FE::rho]->array(mfi);
auto qp_array = mic_fab_vars[MicVar_FE::qp]->array(mfi);
auto fz_array = fz.array(mfi);
const Box& tbz = mfi.tilebox();

ParallelFor(tbz, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {

Real rho_avg, qp_avg;

if (k==k_lo) {
rho_avg = rho_array(i,j,k);
qp_avg = qp_array(i,j,k);
} else if (k==k_hi+1) {
rho_avg = rho_array(i,j,k-1);
qp_avg = qp_array(i,j,k-1);
} else {
rho_avg = 0.5*(rho_array(i,j,k-1) + rho_array(i,j,k)); // Convert to g/cm^3
qp_avg = 0.5*(qp_array(i,j,k-1) + qp_array(i,j,k));
}

qp_avg = std::max(0.0, qp_avg);

Real V_terminal = 36.34*std::pow(rho_avg*0.001*qp_avg, 0.1346)*std::pow(rho_avg/1.16, -0.5); // in m/s

fz_array(i,j,k) = rho_avg*V_terminal*qp_avg;

/*if(k==0){
fz_array(i,j,k) = 0;
}*/
});
}

Real dtn = dt;

/*for ( MFIter mfi(*tabs,TilingIfNotGPU()); mfi.isValid(); ++mfi) {

auto qn_array = mic_fab_vars[MicVar_FE::qn]->array(mfi);
auto qt_array = mic_fab_vars[MicVar_FE::qt]->array(mfi);
auto qp_array = mic_fab_vars[MicVar_FE::qp]->array(mfi);
auto qv_array = mic_fab_vars[MicVar_FE::qv]->array(mfi);

const auto& box3d = mfi.tilebox();

ParallelFor(box3d, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {

qt_array(i,j,k) = std::max(0.0, qt_array(i,j,k));
qp_array(i,j,k) = std::max(0.0, qp_array(i,j,k));
qn_array(i,j,k) = std::max(0.0, qn_array(i,j,k));

if(qt_array(i,j,k) == 0.0){
qv_array(i,j,k) = 0.0;
qn_array(i,j,k) = 0.0;
}
});
}


for ( MFIter mfi(*tabs,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
auto qp_array = mic_fab_vars[MicVar_FE::qp]->array(mfi);
auto rho_array = mic_fab_vars[MicVar_FE::rho]->array(mfi);

const auto& box3d = mfi.tilebox();
auto fz_array = fz.array(mfi);

ParallelFor(box3d, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
Real dq_sed = 1.0/rho_array(i,j,k)*(fz_array(i,j,k+1) - fz_array(i,j,k))/dz*dtn;
qp_array(i,j,k) = qp_array(i,j,k) + dq_sed;
});
}*/




// get the temperature, dentisy, theta, qt and qp from input
// get the temperature, dentisy, theta, qt and qc from input
for ( MFIter mfi(*tabs,TilingIfNotGPU()); mfi.isValid(); ++mfi) {
auto tabs_array = mic_fab_vars[MicVar_FE::tabs]->array(mfi);
auto qn_array = mic_fab_vars[MicVar_FE::qn]->array(mfi);
auto qt_array = mic_fab_vars[MicVar_FE::qt]->array(mfi);
auto qp_array = mic_fab_vars[MicVar_FE::qp]->array(mfi);

auto theta_array = theta->array(mfi);
auto qv_array = qv->array(mfi);
auto rho_array = mic_fab_vars[MicVar_FE::rho]->array(mfi);
auto qv_array = mic_fab_vars[MicVar_FE::qv]->array(mfi);
auto qc_array = mic_fab_vars[MicVar_FE::qc]->array(mfi);
auto tabs_array = mic_fab_vars[MicVar_FE::tabs]->array(mfi);
auto theta_array = mic_fab_vars[MicVar_FE::theta]->array(mfi);
auto rho_array = mic_fab_vars[MicVar_FE::rho]->array(mfi);

const auto& box3d = mfi.tilebox();

auto fz_array = fz.array(mfi);

// Expose for GPU
Real d_fac_cond = m_fac_cond;

ParallelFor(box3d, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {

qt_array(i,j,k) = std::max(0.0, qt_array(i,j,k));
qp_array(i,j,k) = std::max(0.0, qp_array(i,j,k));
qn_array(i,j,k) = std::max(0.0, qn_array(i,j,k));

if(qt_array(i,j,k) == 0.0){
qv_array(i,j,k) = 0.0;
qn_array(i,j,k) = 0.0;
}
qc_array(i,j,k) = std::max(0.0, qc_array(i,j,k));

//------- Autoconversion/accretion
Real qcc, autor, accrr, dq_clwater_to_rain, dq_rain_to_vapor, dq_clwater_to_vapor, dq_vapor_to_clwater, qsat;
Real dq_clwater_to_vapor, dq_vapor_to_clwater, qsat;

Real pressure = getPgivenRTh(rho_array(i,j,k)*theta_array(i,j,k),qv_array(i,j,k))/100.0;
erf_qsatw(tabs_array(i,j,k), pressure, qsat);

// If there is precipitating water (i.e. rain), and the cell is not saturated
// then the rain water can evaporate leading to extraction of latent heat, hence
// reducing temperature and creating negative buoyancy

dq_clwater_to_rain = 0.0;
dq_rain_to_vapor = 0.0;
dq_vapor_to_clwater = 0.0;
dq_clwater_to_vapor = 0.0;

// If there is precipitating water (i.e. rain), and the cell is not saturated
// then the rain water can evaporate leading to extraction of latent heat, hence
// reducing temperature and creating negative buoyancy

//Real fac = qsat*4093.0*L_v/(Cp_d*std::pow(tabs_array(i,j,k)-36.0,2));
Real fac = qsat*L_v*L_v/(Cp_d*R_v*tabs_array(i,j,k)*tabs_array(i,j,k));
dq_vapor_to_clwater = 0.0;
dq_clwater_to_vapor = 0.0;

// If water vapor content exceeds saturation value, then vapor condenses to waterm and latent heat is released, increasing temperature
if(qv_array(i,j,k) > qsat){
dq_vapor_to_clwater = std::min(qv_array(i,j,k), (qv_array(i,j,k)-qsat)/(1.0 + fac));
}
//Real fac = qsat*4093.0*L_v/(Cp_d*std::pow(tabs_array(i,j,k)-36.0,2));
Real fac = qsat*L_v*L_v/(Cp_d*R_v*tabs_array(i,j,k)*tabs_array(i,j,k));


// If water vapor is less than the satruated value, then the cloud water can evaporate, leading to evaporative cooling and
// reducing temperature
if(qv_array(i,j,k) < qsat and qn_array(i,j,k) > 0.0){
dq_clwater_to_vapor = std::min(qn_array(i,j,k), (qsat - qv_array(i,j,k))/(1.0 + fac));
}

if(qp_array(i,j,k) > 0.0 && qv_array(i,j,k) < qsat) {
Real C = 1.6 + 124.9*std::pow(0.001*rho_array(i,j,k)*qp_array(i,j,k),0.2046);
dq_rain_to_vapor = 1.0/(0.001*rho_array(i,j,k))*(1.0 - qv_array(i,j,k)/qsat)*C*std::pow(0.001*rho_array(i,j,k)*qp_array(i,j,k),0.525)/
(5.4e5 + 2.55e6/(pressure*qsat))*dtn;
// The negative sign is to make this variable (vapor formed from evaporation)
// a poistive quantity (as qv/qs < 1)
dq_rain_to_vapor = std::min({qp_array(i,j,k), dq_rain_to_vapor});

// Removing latent heat due to evaporation from rain water to water vapor, reduces the (potential) temperature
}

// If there is cloud water present then do accretion and autoconversion to rain

if (qn_array(i,j,k) > 0.0) {
qcc = qn_array(i,j,k);

autor = 0.0;
if (qcc > qcw0) {
autor = 0.001;
}

accrr = 0.0;
accrr = 2.2 * std::pow(qp_array(i,j,k) , 0.875);
dq_clwater_to_rain = dtn *(accrr*qcc + autor*(qcc - 0.001));

// If the amount of change is more than the amount of qc present, then dq = qc
dq_clwater_to_rain = std::min(dq_clwater_to_rain, qn_array(i,j,k));
// If water vapor content exceeds saturation value, then vapor condenses to waterm and latent heat is released, increasing temperature
if(qv_array(i,j,k) > qsat){
dq_vapor_to_clwater = std::min(qv_array(i,j,k), (qv_array(i,j,k)-qsat)/(1.0 + fac));
}
// If water vapor is less than the satruated value, then the cloud water can evaporate, leading to evaporative cooling and
// reducing temperature
if(qv_array(i,j,k) < qsat and qc_array(i,j,k) > 0.0){
dq_clwater_to_vapor = std::min(qc_array(i,j,k), (qsat - qv_array(i,j,k))/(1.0 + fac));
}

qv_array(i,j,k) = qv_array(i,j,k) - dq_vapor_to_clwater + dq_clwater_to_vapor;
qc_array(i,j,k) = qc_array(i,j,k) + dq_vapor_to_clwater - dq_clwater_to_vapor;

Real dq_sed = 1.0/rho_array(i,j,k)*(fz_array(i,j,k+1) - fz_array(i,j,k))/dz*dtn;

qt_array(i,j,k) = qt_array(i,j,k) + dq_rain_to_vapor - dq_clwater_to_rain;
qp_array(i,j,k) = qp_array(i,j,k) + dq_sed + dq_clwater_to_rain - dq_rain_to_vapor;
qn_array(i,j,k) = qn_array(i,j,k) + dq_vapor_to_clwater - dq_clwater_to_vapor - dq_clwater_to_rain;

theta_array(i,j,k) = theta_array(i,j,k) + theta_array(i,j,k)/tabs_array(i,j,k)*d_fac_cond*(dq_vapor_to_clwater - dq_clwater_to_vapor - dq_rain_to_vapor);
theta_array(i,j,k) = theta_array(i,j,k) + theta_array(i,j,k)/tabs_array(i,j,k)*d_fac_cond*(dq_vapor_to_clwater - dq_clwater_to_vapor);

qt_array(i,j,k) = std::max(0.0, qt_array(i,j,k));
qp_array(i,j,k) = std::max(0.0, qp_array(i,j,k));
qn_array(i,j,k) = std::max(0.0, qn_array(i,j,k));
qv_array(i,j,k) = std::max(0.0, qv_array(i,j,k));
qc_array(i,j,k) = std::max(0.0, qc_array(i,j,k));

});
}
Expand Down
Loading
Loading