ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_MakeBuoyancy.cpp File Reference
#include <AMReX_MultiFab.H>
#include <AMReX_ArrayLim.H>
#include <AMReX_GpuContainers.H>
#include <ERF_Constants.H>
#include <ERF_EOS.H>
#include <ERF_IndexDefines.H>
#include <ERF_PlaneAverage.H>
#include <ERF_SrcHeaders.H>
#include <ERF_BuoyancyUtils.H>
Include dependency graph for ERF_MakeBuoyancy.cpp:

Functions

void make_buoyancy (Vector< MultiFab > &S_data, const MultiFab &S_prim, MultiFab &buoyancy, const amrex::Geometry geom, const SolverChoice &solverChoice, const MultiFab &base_state, const int n_qstate, const int anelastic)
 

Function Documentation

◆ make_buoyancy()

void make_buoyancy ( Vector< MultiFab > &  S_data,
const MultiFab &  S_prim,
MultiFab &  buoyancy,
const amrex::Geometry  geom,
const SolverChoice solverChoice,
const MultiFab &  base_state,
const int  n_qstate,
const int  anelastic 
)

Function for computing the buoyancy term to be used in the evolution equation for the z-component of momentum in the slow integrator. There are three options for how buoyancy is computed (two are the same in the absence of moisture).

Parameters
[in]S_datacurrent solution
[in]S_primprimitive variables (i.e. conserved variables divided by density)
[out]buoyancybuoyancy term computed here
[in]qmoistmoisture variables (in order: qv, qc, qi, ...)
[in]qv_dlateral average of cloud vapor
[in]qc_dlateral average of cloud vapor
[in]qd_dlateral average of cloud vapor
[in]geomContainer for geometric information
[in]solverChoiceContainer for solver parameters
[in]r0Reference (hydrostatically stratified) density
[in]n_qstateNumber of moist variables used by the current model
40 {
41  BL_PROFILE("make_buoyancy()");
42 
43  const Array<Real,AMREX_SPACEDIM> grav{0.0, 0.0, -solverChoice.gravity};
44  const GpuArray<Real,AMREX_SPACEDIM> grav_gpu{grav[0], grav[1], grav[2]};
45 
46  const int klo = geom.Domain().smallEnd()[2];
47  const int khi = geom.Domain().bigEnd()[2] + 1;
48 
49  Real rd_over_cp = solverChoice.rdOcp;
50  Real rv_over_rd = R_v/R_d;
51 
52  MultiFab r0 (base_state, make_alias, BaseState::r0_comp , 1);
53  MultiFab p0 (base_state, make_alias, BaseState::p0_comp , 1);
54  MultiFab th0(base_state, make_alias, BaseState::th0_comp, 1);
55 
56 #ifdef _OPENMP
57 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
58 #endif
59  for ( MFIter mfi(buoyancy,TilingIfNotGPU()); mfi.isValid(); ++mfi)
60  {
61  Box tbz = mfi.tilebox();
62 
63  // We don't compute a source term for z-momentum on the bottom or top boundary
64  if (tbz.smallEnd(2) == klo) tbz.growLo(2,-1);
65  if (tbz.bigEnd(2) == khi) tbz.growHi(2,-1);
66 
67  const Array4<const Real> & cell_data = S_data[IntVars::cons].array(mfi);
68  const Array4<const Real> & cell_prim = S_prim.array(mfi);
69  const Array4< Real> & buoyancy_fab = buoyancy.array(mfi);
70 
71  // Base state density and pressure
72  const Array4<const Real>& r0_arr = r0.const_array(mfi);
73  const Array4<const Real>& p0_arr = p0.const_array(mfi);
74  const Array4<const Real>& th0_arr = th0.const_array(mfi);
75 
76  if ( anelastic && (solverChoice.moisture_type == MoistureType::None) )
77  {
78  // ******************************************************************************************
79  // Dry anelastic
80  // ******************************************************************************************
81  ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k)
82  {
83  //
84  // Return -rho0 g (thetaprime / theta0)
85  //
86  buoyancy_fab(i, j, k) = buoyancy_dry_anelastic(i,j,k,grav_gpu[2],
87  r0_arr,th0_arr,cell_data);
88  });
89  }
90  else if ( anelastic && (solverChoice.moisture_type != MoistureType::None) )
91  {
92  // ******************************************************************************************
93  // Moist anelastic
94  // ******************************************************************************************
95  ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k)
96  {
97  //
98  // Return -rho0 g (thetaprime / theta0)
99  //
100  buoyancy_fab(i, j, k) = buoyancy_moist_anelastic(i,j,k,grav_gpu[2],rv_over_rd,
101  r0_arr,th0_arr,cell_data);
102  });
103  }
104  else if ( !anelastic && (solverChoice.moisture_type == MoistureType::None) )
105  {
106  // ******************************************************************************************
107  // Dry compressible
108  // ******************************************************************************************
109  int n_q_dry = 0;
110  if (solverChoice.buoyancy_type == 1) {
111 
112  ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k)
113  {
114  //
115  // Return -rho0 g (thetaprime / theta0)
116  //
117  buoyancy_fab(i, j, k) = buoyancy_rhopert(i,j,k,n_q_dry,grav_gpu[2],
118  r0_arr,cell_data);
119  });
120  }
121  else if (solverChoice.buoyancy_type == 2 || solverChoice.buoyancy_type == 3)
122  {
123  ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k)
124  {
125  //
126  // Return -rho0 g (Tprime / T0)
127  //
128  buoyancy_fab(i, j, k) = buoyancy_dry_Tpert(i,j,k,grav_gpu[2],rd_over_cp,
129  r0_arr,p0_arr,th0_arr,cell_data);
130  });
131  }
132  else if (solverChoice.buoyancy_type == 4)
133  {
134  ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k)
135  {
136  //
137  // Return -rho0 g (Theta_prime / Theta_0)
138  //
139  buoyancy_fab(i, j, k) = buoyancy_dry_Thpert(i,j,k,grav_gpu[2],
140  r0_arr,th0_arr,cell_data);
141  });
142  } // buoyancy_type for dry compressible
143  }
144  else // if ( !anelastic && (solverChoice.moisture_type != MoistureType::None) )
145  {
146  // ******************************************************************************************
147  // Moist compressible
148  // ******************************************************************************************
149 
150  if ( (solverChoice.moisture_type == MoistureType::Kessler_NoRain) ||
151  (solverChoice.moisture_type == MoistureType::SAM) ||
152  (solverChoice.moisture_type == MoistureType::SAM_NoPrecip_NoIce) )
153  {
154  AMREX_ALWAYS_ASSERT(solverChoice.buoyancy_type == 1);
155  }
156 
157  if (solverChoice.buoyancy_type == 1)
158  {
159  ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k)
160  {
161  buoyancy_fab(i, j, k) = buoyancy_rhopert(i,j,k,n_qstate,grav_gpu[2],
162  r0_arr,cell_data);
163  });
164  }
165  else if (solverChoice.buoyancy_type == 2 || solverChoice.buoyancy_type == 3)
166  {
167 
168  ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k)
169  {
170  buoyancy_fab(i, j, k) = buoyancy_moist_Tpert(i,j,k,n_qstate,grav_gpu[2],rd_over_cp,
171  r0_arr,th0_arr,p0_arr,
172  cell_prim,cell_data);
173  });
174  }
175  else if (solverChoice.buoyancy_type == 4)
176  {
177  ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k)
178  {
179  buoyancy_fab(i, j, k) = buoyancy_moist_Thpert(i,j,k,n_qstate,grav_gpu[2],
180  r0_arr,th0_arr,cell_prim);
181  });
182  }
183  } // moist compressible
184  } // mfi
185 }
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_rhopert(int &i, int &j, int &k, const int &n_qstate, amrex::Real const &grav_gpu, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &cell_data)
Definition: ERF_BuoyancyUtils.H:59
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_dry_anelastic(int &i, int &j, int &k, amrex::Real const &grav_gpu, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &cell_data)
Definition: ERF_BuoyancyUtils.H:10
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_dry_Thpert(int &i, int &j, int &k, amrex::Real const &grav_gpu, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &cell_prim)
Definition: ERF_BuoyancyUtils.H:103
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_dry_Tpert(int &i, int &j, int &k, amrex::Real const &grav_gpu, amrex::Real const &rd_over_cp, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &p0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &cell_data)
Definition: ERF_BuoyancyUtils.H:77
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_moist_anelastic(int &i, int &j, int &k, amrex::Real const &grav_gpu, amrex::Real const &rv_over_rd, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &cell_data)
Definition: ERF_BuoyancyUtils.H:30
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_moist_Thpert(int &i, int &j, int &k, const int &n_qstate, amrex::Real const &grav_gpu, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &cell_prim)
Definition: ERF_BuoyancyUtils.H:166
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real buoyancy_moist_Tpert(int &i, int &j, int &k, const int &n_qstate, amrex::Real const &grav_gpu, amrex::Real const &rd_over_cp, const amrex::Array4< const amrex::Real > &r0_arr, const amrex::Array4< const amrex::Real > &th0_arr, const amrex::Array4< const amrex::Real > &p0_arr, const amrex::Array4< const amrex::Real > &cell_prim, const amrex::Array4< const amrex::Real > &cell_data)
Definition: ERF_BuoyancyUtils.H:125
constexpr amrex::Real R_v
Definition: ERF_Constants.H:11
constexpr amrex::Real R_d
Definition: ERF_Constants.H:10
@ p0_comp
Definition: ERF_IndexDefines.H:64
@ th0_comp
Definition: ERF_IndexDefines.H:66
@ r0_comp
Definition: ERF_IndexDefines.H:63
@ cons
Definition: ERF_IndexDefines.H:139
amrex::Real rdOcp
Definition: ERF_DataStruct.H:619
amrex::Real gravity
Definition: ERF_DataStruct.H:617
MoistureType moisture_type
Definition: ERF_DataStruct.H:664
int buoyancy_type
Definition: ERF_DataStruct.H:598

Referenced by make_mom_sources().

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