ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Radiation Class Reference

#include <ERF_Radiation.H>

Inheritance diagram for Radiation:
Collaboration diagram for Radiation:

Public Member Functions

 Radiation (const int &lev, SolverChoice &sc)
 
 ~Radiation ()=default
 
virtual void Init (const amrex::Geometry &geom, const amrex::BoxArray &ba, amrex::MultiFab *cons_in) override
 
virtual void Run (int &level, int &step, amrex::Real &time, const amrex::Real &dt, const amrex::BoxArray &ba, amrex::Geometry &geom, amrex::MultiFab *cons_in, amrex::MultiFab *lsm_fluxes, amrex::MultiFab *lsm_zenith, amrex::MultiFab *qheating_rates, amrex::MultiFab *z_phys, amrex::MultiFab *lat, amrex::MultiFab *lon) override
 
void set_grids (int &level, int &step, amrex::Real &time, const amrex::Real &dt, const amrex::BoxArray &ba, amrex::Geometry &geom, amrex::MultiFab *cons_in, amrex::MultiFab *lsm_fluxes, amrex::MultiFab *lsm_zenith, amrex::MultiFab *qheating_rates, amrex::MultiFab *z_phys, amrex::MultiFab *lat, amrex::MultiFab *lon)
 
template<typename LandSurfaceModelType >
void set_lsm_inputs (LandSurfaceModelType *model)
 
void alloc_buffers ()
 
void dealloc_buffers ()
 
void mf_to_yakl_buffers ()
 
void yakl_buffers_to_mf ()
 
void write_rrtmgp_fluxes ()
 
void initialize_impl ()
 
void run_impl ()
 
void finalize_impl ()
 
void rad_run_impl ()
 
void populateDatalogMF ()
 
virtual void WriteDataLog (const amrex::Real &time) override
 
- Public Member Functions inherited from IRadiation
virtual ~IRadiation ()=default
 
void setupDataLog ()
 
void setDataLogFrequency (const int nstep)
 
bool hasDatalog ()
 

Private Attributes

int m_lev
 
int m_step
 
amrex::Real m_time
 
amrex::Real m_dt
 
amrex::Geometry m_geom
 
amrex::BoxArray m_ba
 
bool m_update_rad = false
 
bool m_rad_write_fluxes = false
 
bool m_first_step = true
 
bool m_moist = false
 
bool m_ice = false
 
bool m_lsm = false
 
amrex::MultiFab * m_cons_in = nullptr
 
amrex::MultiFab * m_qheating_rates = nullptr
 
amrex::MultiFab * m_z_phys = nullptr
 
amrex::MultiFab * m_lat = nullptr
 
amrex::MultiFab * m_lon = nullptr
 
amrex::Real m_lat_cons = 39.809860
 
amrex::Real m_lon_cons = -98.555183
 
amrex::MultiFab * m_lsm_fluxes = nullptr
 
amrex::MultiFab * m_lsm_zenith = nullptr
 
amrex::MultiFab datalog_mf
 
std::string rrtmgp_file_path = "."
 
std::string rrtmgp_coeffs_sw = "rrtmgp-data-sw-g224-2018-12-04.nc"
 
std::string rrtmgp_coeffs_lw = "rrtmgp-data-lw-g224-2018-12-04.nc"
 
std::string rrtmgp_cloud_optics_sw = "rrtmgp-cloud-optics-coeffs-sw.nc"
 
std::string rrtmgp_cloud_optics_lw = "rrtmgp-cloud-optics-coeffs-lw.nc"
 
std::string rrtmgp_coeffs_file_sw
 
std::string rrtmgp_coeffs_file_lw
 
std::string rrtmgp_cloud_optics_file_sw
 
std::string rrtmgp_cloud_optics_file_lw
 
int m_ngas = 8
 
const std::vector< std::string > m_gas_names
 
const std::vector< amrex::Real > m_mol_weight_gas
 
amrex::Real m_co2vmr = 388.717e-6
 
amrex::Vector< amrex::Real > m_o3vmr
 
amrex::Real m_n2ovmr = 323.141e-9
 
amrex::Real m_covmr = 1.0e-7
 
amrex::Real m_ch4vmr = 1807.851e-9
 
amrex::Real m_o2vmr = 0.209448
 
amrex::Real m_n2vmr = 0.7906
 
int m_o3_size
 
real1d m_gas_mol_weights
 
string1dv gas_names_yakl_offset
 
GasConcs m_gas_concs
 
int m_ncol
 
int m_nlay
 
amrex::Vector< int > m_col_offsets
 
bool m_do_aerosol_rad = true
 
bool m_extra_clnsky_diag = false
 
bool m_extra_clnclrsky_diag = false
 
int m_orbital_year = -9999
 
int m_orbital_mon = -9999
 
int m_orbital_day = -9999
 
int m_orbital_sec = -9999
 
bool m_fixed_orbital_year = false
 
amrex::Real m_orbital_eccen = -9999.
 
amrex::Real m_orbital_obliq = -9999.
 
amrex::Real m_orbital_mvelp = -9999.
 
amrex::Real m_fixed_total_solar_irradiance = -9999.
 
amrex::Real m_fixed_solar_zenith_angle = -9999.
 
int m_nswbands = 14
 
int m_nlwbands = 16
 
int m_nswgpts = 112
 
int m_nlwgpts = 128
 
int m_rad_freq_in_steps = 1
 
bool m_do_subcol_sampling = true
 
real1d o3_lay
 
real1d cosine_zenith
 
real1d mu0
 
real1d sfc_alb_dir_vis
 
real1d sfc_alb_dir_nir
 
real1d sfc_alb_dif_vis
 
real1d sfc_alb_dif_nir
 
real1d sfc_flux_dir_vis
 
real1d sfc_flux_dir_nir
 
real1d sfc_flux_dif_vis
 
real1d sfc_flux_dif_nir
 
real1d lat
 
real1d lon
 
real1d sfc_emis
 
real1d t_sfc
 
real1d lw_src
 
real2d r_lay
 
real2d p_lay
 
real2d t_lay
 
real2d z_del
 
real2d p_del
 
real2d qv_lay
 
real2d qc_lay
 
real2d qi_lay
 
real2d cldfrac_tot
 
real2d eff_radius_qc
 
real2d eff_radius_qi
 
real2d tmp2d
 
real2d lwp
 
real2d iwp
 
real2d sw_heating
 
real2d lw_heating
 
real2d sw_clrsky_heating
 
real2d lw_clrsky_heating
 
real2d d_tint
 
real2d p_lev
 
real2d t_lev
 
real2d sw_flux_up
 
real2d sw_flux_dn
 
real2d sw_flux_dn_dir
 
real2d lw_flux_up
 
real2d lw_flux_dn
 
real2d sw_clnclrsky_flux_up
 
real2d sw_clnclrsky_flux_dn
 
real2d sw_clnclrsky_flux_dn_dir
 
real2d sw_clrsky_flux_up
 
real2d sw_clrsky_flux_dn
 
real2d sw_clrsky_flux_dn_dir
 
real2d sw_clnsky_flux_up
 
real2d sw_clnsky_flux_dn
 
real2d sw_clnsky_flux_dn_dir
 
real2d lw_clnclrsky_flux_up
 
real2d lw_clnclrsky_flux_dn
 
real2d lw_clrsky_flux_up
 
real2d lw_clrsky_flux_dn
 
real2d lw_clnsky_flux_up
 
real2d lw_clnsky_flux_dn
 
real3d sw_bnd_flux_up
 
real3d sw_bnd_flux_dn
 
real3d sw_bnd_flux_dir
 
real3d sw_bnd_flux_dif
 
real3d lw_bnd_flux_up
 
real3d lw_bnd_flux_dn
 
real2d sfc_alb_dir
 
real2d sfc_alb_dif
 
real2d emis_sfc
 
real3d aero_tau_sw
 
real3d aero_ssa_sw
 
real3d aero_g_sw
 
real3d aero_tau_lw
 
real3d cld_tau_sw_bnd
 
real3d cld_tau_lw_bnd
 
real3d cld_tau_sw_gpt
 
real3d cld_tau_lw_gpt
 

Additional Inherited Members

- Protected Attributes inherited from IRadiation
std::unique_ptr< std::fstream > datalog = nullptr
 
std::string datalogname
 
int datalog_int = -1
 

Constructor & Destructor Documentation

◆ Radiation()

Radiation::Radiation ( const int &  lev,
SolverChoice sc 
)
25 {
26  // Initialize YAKL
27  if (!yakl::isInitialized()) { yakl::init(); }
28 
29  // Check if we have a valid moisture model
30  if (sc.moisture_type != MoistureType::None) { m_moist = true; }
31 
32  // Check if we have a moisture model with ice
33  if (sc.moisture_type == MoistureType::SAM) { m_ice = true; }
34 
35  // Check if we have a land surface model enabled
36  if (sc.lsm_type != LandSurfaceType::None) { m_lsm = true; }
37 
38  // Construct parser object for following reads
39  ParmParse pp("erf");
40 
41  // Radiation timestep, as a number of atm steps
42  pp.query("rad_freq_in_steps", m_rad_freq_in_steps);
43 
44  // Flag to write fluxes to plt file
45  pp.query("rad_write_fluxes", m_rad_write_fluxes);
46 
47  // Do MCICA subcolumn sampling
48  pp.query("rad_do_subcol_sampling", m_do_subcol_sampling);
49 
50  // Determine orbital year. If orbital_year is negative, use current year
51  // from timestamp for orbital year; if positive, use provided orbital year
52  // for duration of simulation.
53  m_fixed_orbital_year = pp.query("rad_orbital_year", m_orbital_year);
54 
55  // Get orbital parameters from inputs file
56  pp.query("rad_orbital_eccentricity", m_orbital_eccen);
57  pp.query("rad_orbital_obliquity" , m_orbital_obliq);
58  pp.query("rad_orbital_mvelp" , m_orbital_mvelp);
59 
60  // Get a constant lat/lon for idealized simulations
61  pp.query("rad_cons_lat", m_lat_cons);
62  pp.query("rad_cons_lon", m_lon_cons);
63 
64  // Value for prescribing an invariant solar constant (i.e. total solar irradiance at
65  // TOA). Used for idealized experiments such as RCE. Disabled when value is less than 0.
66  pp.query("fixed_total_solar_irradiance", m_fixed_total_solar_irradiance);
67 
68  // Determine whether or not we are using a fixed solar zenith angle (positive value)
69  pp.query("fixed_solar_zenith_angle", m_fixed_solar_zenith_angle);
70 
71  // Get prescribed surface values of greenhouse gases
72  pp.query("co2vmr", m_co2vmr);
73  pp.queryarr("o3vmr" , m_o3vmr );
74  pp.query("n2ovmr", m_n2ovmr);
75  pp.query("covmr" , m_covmr );
76  pp.query("ch4vmr", m_ch4vmr);
77  pp.query("o2vmr" , m_o2vmr );
78  pp.query("n2vmr" , m_n2vmr );
79 
80  // Required aerosol optical properties from SPA
81  pp.query("rad_do_aerosol", m_do_aerosol_rad);
82 
83  // Whether we do extra clean/clear sky calculations
84  pp.query("rad_extra_clnclrsky_diag", m_extra_clnclrsky_diag);
85  pp.query("rad_extra_clnsky_diag" , m_extra_clnsky_diag);
86 
87  // Parse the band and gauss pt sizes
88  pp.query("nswbands", m_nswbands);
89  pp.query("nlwbands", m_nlwbands);
90  pp.query("nswgpts" , m_nswgpts );
91  pp.query("nlwgpts" , m_nlwgpts );
92 
93  // Parse path and file names
94  pp.query("rrtmgp_file_path" , rrtmgp_file_path);
95  pp.query("rrtmgp_coeffs_sw" , rrtmgp_coeffs_sw );
96  pp.query("rrtmgp_coeffs_lw" , rrtmgp_coeffs_lw );
97  pp.query("rrtmgp_cloud_optics_sw", rrtmgp_cloud_optics_sw);
98  pp.query("rrtmgp_cloud_optics_lw", rrtmgp_cloud_optics_lw);
99 
100  // Append file names to path
105 
106  // Output for user
107  if (lev == 0) {
108  Print() << "Radiation interface constructed:\n";
109  Print() << "========================================================\n";
110  Print() << "Coeff SW file: " << rrtmgp_coeffs_file_sw << "\n";
111  Print() << "Coeff LW file: " << rrtmgp_coeffs_file_lw << "\n";
112  Print() << "Cloud SW file: " << rrtmgp_cloud_optics_file_sw << "\n";
113  Print() << "Cloud LW file: " << rrtmgp_cloud_optics_file_lw << "\n";
114  Print() << "========================================================\n";
115  }
116 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pp(amrex::Real y)
Definition: ERF_MicrophysicsUtils.H:219
std::string rrtmgp_coeffs_file_sw
Definition: ERF_Radiation.H:272
std::string rrtmgp_coeffs_sw
Definition: ERF_Radiation.H:268
int m_rad_freq_in_steps
Definition: ERF_Radiation.H:350
amrex::Real m_lon_cons
Definition: ERF_Radiation.H:257
int m_nswbands
Definition: ERF_Radiation.H:344
bool m_do_aerosol_rad
Definition: ERF_Radiation.H:311
std::string rrtmgp_coeffs_lw
Definition: ERF_Radiation.H:269
bool m_moist
Definition: ERF_Radiation.H:236
std::string rrtmgp_cloud_optics_file_lw
Definition: ERF_Radiation.H:275
bool m_lsm
Definition: ERF_Radiation.H:240
bool m_do_subcol_sampling
Definition: ERF_Radiation.H:353
bool m_rad_write_fluxes
Definition: ERF_Radiation.H:231
std::string rrtmgp_cloud_optics_file_sw
Definition: ERF_Radiation.H:274
amrex::Real m_orbital_mvelp
Definition: ERF_Radiation.H:331
amrex::Vector< amrex::Real > m_o3vmr
Definition: ERF_Radiation.H:286
std::string rrtmgp_cloud_optics_sw
Definition: ERF_Radiation.H:270
int m_nlwgpts
Definition: ERF_Radiation.H:347
std::string rrtmgp_cloud_optics_lw
Definition: ERF_Radiation.H:271
amrex::Real m_co2vmr
Definition: ERF_Radiation.H:285
bool m_extra_clnsky_diag
Definition: ERF_Radiation.H:314
amrex::Real m_lat_cons
Definition: ERF_Radiation.H:256
amrex::Real m_fixed_total_solar_irradiance
Definition: ERF_Radiation.H:336
amrex::Real m_o2vmr
Definition: ERF_Radiation.H:290
amrex::Real m_n2ovmr
Definition: ERF_Radiation.H:287
std::string rrtmgp_file_path
Definition: ERF_Radiation.H:267
int m_nlwbands
Definition: ERF_Radiation.H:345
amrex::Real m_orbital_eccen
Definition: ERF_Radiation.H:329
amrex::Real m_covmr
Definition: ERF_Radiation.H:288
std::string rrtmgp_coeffs_file_lw
Definition: ERF_Radiation.H:273
amrex::Real m_ch4vmr
Definition: ERF_Radiation.H:289
bool m_ice
Definition: ERF_Radiation.H:237
amrex::Real m_fixed_solar_zenith_angle
Definition: ERF_Radiation.H:340
amrex::Real m_orbital_obliq
Definition: ERF_Radiation.H:330
amrex::Real m_n2vmr
Definition: ERF_Radiation.H:291
bool m_fixed_orbital_year
Definition: ERF_Radiation.H:328
int m_nswgpts
Definition: ERF_Radiation.H:346
bool m_extra_clnclrsky_diag
Definition: ERF_Radiation.H:315
int m_orbital_year
Definition: ERF_Radiation.H:320
LandSurfaceType lsm_type
Definition: ERF_DataStruct.H:807
MoistureType moisture_type
Definition: ERF_DataStruct.H:804
Here is the call graph for this function:

◆ ~Radiation()

Radiation::~Radiation ( )
default

Member Function Documentation

◆ alloc_buffers()

void Radiation::alloc_buffers ( )
198 {
199  // 1d size (m_ngas)
200  m_gas_mol_weights = real1d("m_gas_mol_weights", m_ngas);
201  realHost1d m_gas_mol_weights_h("m_gas_mol_weights_h", m_ngas);
202  gas_names_yakl_offset.clear();
203  parallel_for(m_ngas, YAKL_LAMBDA (int igas)
204  {
205  m_gas_mol_weights_h(igas) = m_mol_weight_gas[igas-1];
206  gas_names_yakl_offset.push_back(m_gas_names[igas-1]);
207  });
208  m_gas_mol_weights_h.deep_copy_to(m_gas_mol_weights);
209 
210  // 1d size (1 or nlay)
211  m_o3_size = m_o3vmr.size();
212  AMREX_ASSERT_WITH_MESSAGE(((m_o3_size==1) || (m_o3_size==m_nlay)), "O3 VMR array must be length 1 or nlay");
213  o3_lay = real1d("o3_lay", m_o3_size);
214  realHost1d o3_lay_h("o3_lay_h", m_o3_size);
215  parallel_for(m_o3_size, YAKL_LAMBDA (int io3)
216  {
217  o3_lay_h(io3) = m_o3vmr[io3-1];
218  });
219  o3_lay_h.deep_copy_to(o3_lay);
220 
221  // 1d size (ncol)
222  cosine_zenith = real1d("cosine_zenith" , m_ncol);
223  mu0 = real1d("mu0" , m_ncol);
224  sfc_alb_dir_vis = real1d("sfc_alb_dir_vis" , m_ncol);
225  sfc_alb_dir_nir = real1d("sfc_alb_dir_nir" , m_ncol);
226  sfc_alb_dif_vis = real1d("sfc_alb_dif_vis" , m_ncol);
227  sfc_alb_dif_nir = real1d("sfc_alb_dif_nir" , m_ncol);
228  sfc_flux_dir_vis = real1d("sfc_flux_dir_vis", m_ncol);
229  sfc_flux_dir_nir = real1d("sfc_flux_dir_nir", m_ncol);
230  sfc_flux_dif_vis = real1d("sfc_flux_dif_vis", m_ncol);
231  sfc_flux_dif_nir = real1d("sfc_flux_dif_nir", m_ncol);
232  lat = real1d("lat" , m_ncol);
233  lon = real1d("lon" , m_ncol);;
234  sfc_emis = real1d("sfc_emis" , m_ncol);
235  t_sfc = real1d("t_sfc" , m_ncol);
236  lw_src = real1d("lw_src" , m_ncol);
237 
238  // 2d size (ncol, nlay)
239  r_lay = real2d("r_lay" , m_ncol, m_nlay);
240  p_lay = real2d("p_lay" , m_ncol, m_nlay);
241  t_lay = real2d("t_lay" , m_ncol, m_nlay);
242  z_del = real2d("z_del" , m_ncol, m_nlay);
243  p_del = real2d("p_del" , m_ncol, m_nlay);
244  qv_lay = real2d("qv" , m_ncol, m_nlay);
245  qc_lay = real2d("qc" , m_ncol, m_nlay);
246  qi_lay = real2d("qi" , m_ncol, m_nlay);
247  cldfrac_tot = real2d("cldfrac_tot" , m_ncol, m_nlay);
248  eff_radius_qc = real2d("eff_radius_qc", m_ncol, m_nlay);
249  eff_radius_qi = real2d("eff_radius_qi", m_ncol, m_nlay);
250  tmp2d = real2d("tmp2d" , m_ncol, m_nlay);
251  lwp = real2d("lwp" , m_ncol, m_nlay);
252  iwp = real2d("iwp" , m_ncol, m_nlay);
253  sw_heating = real2d("sw_heating" , m_ncol, m_nlay);
254  lw_heating = real2d("lw_heating" , m_ncol, m_nlay);
255  sw_clrsky_heating = real2d("sw_clrsky_heating", m_ncol, m_nlay);
256  lw_clrsky_heating = real2d("lw_clrsky_heating", m_ncol, m_nlay);
257 
258  // 2d size (ncol, nlay+1)
259  d_tint = real2d("d_tint" , m_ncol, m_nlay+1);
260  p_lev = real2d("p_lev" , m_ncol, m_nlay+1);
261  t_lev = real2d("t_lev" , m_ncol, m_nlay+1);
262  sw_flux_up = real2d("sw_flux_up" , m_ncol, m_nlay+1);
263  sw_flux_dn = real2d("sw_flux_dn" , m_ncol, m_nlay+1);
264  sw_flux_dn_dir = real2d("sw_flux_dn_dir" , m_ncol, m_nlay+1);
265  lw_flux_up = real2d("sw_flux_up" , m_ncol, m_nlay+1);
266  lw_flux_dn = real2d("sw_flux_dn" , m_ncol, m_nlay+1);
267  sw_clnclrsky_flux_up = real2d("sw_clnclrsky_flux_up" , m_ncol, m_nlay+1);
268  sw_clnclrsky_flux_dn = real2d("sw_clnclrsky_flux_dn" , m_ncol, m_nlay+1);
269  sw_clnclrsky_flux_dn_dir = real2d("sw_clnclrsky_flux_dn_dir", m_ncol, m_nlay+1);
270  sw_clrsky_flux_up = real2d("sw_clrsky_flux_up" , m_ncol, m_nlay+1);
271  sw_clrsky_flux_dn = real2d("sw_clrsky_flux_dn" , m_ncol, m_nlay+1);
272  sw_clrsky_flux_dn_dir = real2d("sw_clrsky_flux_dn_dir" , m_ncol, m_nlay+1);
273  sw_clnsky_flux_up = real2d("sw_clnsky_flux_up" , m_ncol, m_nlay+1);
274  sw_clnsky_flux_dn = real2d("sw_clnsky_flux_dn" , m_ncol, m_nlay+1);
275  sw_clnsky_flux_dn_dir = real2d("sw_clnsky_flux_dn_dir" , m_ncol, m_nlay+1);
276  lw_clnclrsky_flux_up = real2d("lw_clnclrsky_flux_up" , m_ncol, m_nlay+1);
277  lw_clnclrsky_flux_dn = real2d("lw_clnclrsky_flux_dn" , m_ncol, m_nlay+1);
278  lw_clrsky_flux_up = real2d("lw_clrsky_flux_up" , m_ncol, m_nlay+1);
279  lw_clrsky_flux_dn = real2d("lw_clrsky_flux_dn" , m_ncol, m_nlay+1);
280  lw_clnsky_flux_up = real2d("lw_clnsky_flux_up" , m_ncol, m_nlay+1);
281  lw_clnsky_flux_dn = real2d("lw_clnsky_flux_dn" , m_ncol, m_nlay+1);
282 
283  // 3d size (ncol, nlay+1, nswbands)
284  sw_bnd_flux_up = real3d("sw_bnd_flux_up" , m_ncol, m_nlay+1, m_nswbands);
285  sw_bnd_flux_dn = real3d("sw_bnd_flux_dn" , m_ncol, m_nlay+1, m_nswbands);
286  sw_bnd_flux_dir = real3d("sw_bnd_flux_dir", m_ncol, m_nlay+1, m_nswbands);
287  sw_bnd_flux_dif = real3d("sw_bnd_flux_dif", m_ncol, m_nlay+1, m_nswbands);
288 
289  // 3d size (ncol, nlay+1, nlwbands)
290  lw_bnd_flux_up = real3d("lw_bnd_flux_up" , m_ncol, m_nlay+1, m_nlwbands);
291  lw_bnd_flux_dn = real3d("lw_bnd_flux_up" , m_ncol, m_nlay+1, m_nlwbands);
292 
293  // 2d size (ncol, nswbands)
294  sfc_alb_dir = real2d("sfc_alb_dir", m_ncol, m_nswbands);
295  sfc_alb_dif = real2d("sfc_alb_dif", m_ncol, m_nswbands);
296 
297  // 2d size (ncol, nlwbands)
298  emis_sfc = real2d("emis_sfc", m_ncol, m_nlwbands);
299 
300  // 3d size (ncol, nlay, n[sw,lw]bands)
301  aero_tau_sw = real3d("aero_tau_sw", m_ncol, m_nlay, m_nswbands);
302  aero_ssa_sw = real3d("aero_ssa_sw", m_ncol, m_nlay, m_nswbands);
303  aero_g_sw = real3d("aero_g_sw" , m_ncol, m_nlay, m_nswbands);
304  aero_tau_lw = real3d("aero_tau_lw", m_ncol, m_nlay, m_nlwbands);
305 
306  // 3d size (ncol, nlay, n[sw,lw]bnds)
307  cld_tau_sw_bnd = real3d("cld_tau_sw_bnd", m_ncol, m_nlay, m_nswbands);
308  cld_tau_lw_bnd = real3d("cld_tau_lw_bnd", m_ncol, m_nlay, m_nlwbands);
309 
310  // 3d size (ncol, nlay, n[sw,lw]gpts)
311  cld_tau_sw_gpt = real3d("cld_tau_sw_gpt", m_ncol, m_nlay, m_nswgpts);
312  cld_tau_lw_gpt = real3d("cld_tau_lw_gpt", m_ncol, m_nlay, m_nlwgpts);
313 }
real2d z_del
Definition: ERF_Radiation.H:379
real2d qv_lay
Definition: ERF_Radiation.H:381
real1d sfc_flux_dif_nir
Definition: ERF_Radiation.H:368
real2d sw_clrsky_flux_up
Definition: ERF_Radiation.H:407
real1d sfc_alb_dif_vis
Definition: ERF_Radiation.H:363
int m_o3_size
Definition: ERF_Radiation.H:295
real2d sw_clrsky_flux_dn_dir
Definition: ERF_Radiation.H:409
real2d lw_flux_dn
Definition: ERF_Radiation.H:403
real1d sfc_flux_dir_vis
Definition: ERF_Radiation.H:365
real2d lw_clrsky_heating
Definition: ERF_Radiation.H:393
real2d lw_clrsky_flux_dn
Definition: ERF_Radiation.H:416
real2d sw_clnclrsky_flux_dn
Definition: ERF_Radiation.H:405
real2d sw_clnsky_flux_dn
Definition: ERF_Radiation.H:411
real2d sw_clnsky_flux_up
Definition: ERF_Radiation.H:410
real3d cld_tau_lw_bnd
Definition: ERF_Radiation.H:445
real3d aero_ssa_sw
Definition: ERF_Radiation.H:439
real2d qi_lay
Definition: ERF_Radiation.H:383
real1d lw_src
Definition: ERF_Radiation.H:373
real2d sw_flux_dn_dir
Definition: ERF_Radiation.H:401
real1d sfc_flux_dif_vis
Definition: ERF_Radiation.H:367
real2d lw_clrsky_flux_up
Definition: ERF_Radiation.H:415
real1d lat
Definition: ERF_Radiation.H:369
real2d iwp
Definition: ERF_Radiation.H:389
real2d t_lev
Definition: ERF_Radiation.H:398
real2d sw_clnclrsky_flux_dn_dir
Definition: ERF_Radiation.H:406
real2d lw_clnsky_flux_dn
Definition: ERF_Radiation.H:418
real2d eff_radius_qc
Definition: ERF_Radiation.H:385
real3d sw_bnd_flux_dif
Definition: ERF_Radiation.H:424
real2d sw_heating
Definition: ERF_Radiation.H:390
real1d t_sfc
Definition: ERF_Radiation.H:372
real2d sfc_alb_dir
Definition: ERF_Radiation.H:431
real3d aero_tau_sw
Definition: ERF_Radiation.H:438
real2d r_lay
Definition: ERF_Radiation.H:376
real2d emis_sfc
Definition: ERF_Radiation.H:435
real1d o3_lay
Definition: ERF_Radiation.H:356
real2d sfc_alb_dif
Definition: ERF_Radiation.H:432
real1d sfc_emis
Definition: ERF_Radiation.H:371
int m_ncol
Definition: ERF_Radiation.H:304
real2d sw_clnclrsky_flux_up
Definition: ERF_Radiation.H:404
const std::vector< amrex::Real > m_mol_weight_gas
Definition: ERF_Radiation.H:281
real3d cld_tau_lw_gpt
Definition: ERF_Radiation.H:449
real1d sfc_flux_dir_nir
Definition: ERF_Radiation.H:366
real1d lon
Definition: ERF_Radiation.H:370
real3d lw_bnd_flux_up
Definition: ERF_Radiation.H:427
real3d cld_tau_sw_gpt
Definition: ERF_Radiation.H:448
real3d lw_bnd_flux_dn
Definition: ERF_Radiation.H:428
real2d lw_flux_up
Definition: ERF_Radiation.H:402
real1d mu0
Definition: ERF_Radiation.H:360
real3d sw_bnd_flux_up
Definition: ERF_Radiation.H:421
real2d sw_clrsky_heating
Definition: ERF_Radiation.H:392
real2d cldfrac_tot
Definition: ERF_Radiation.H:384
real3d aero_tau_lw
Definition: ERF_Radiation.H:441
real3d sw_bnd_flux_dn
Definition: ERF_Radiation.H:422
real1d cosine_zenith
Definition: ERF_Radiation.H:359
real2d p_lay
Definition: ERF_Radiation.H:377
real2d lw_clnclrsky_flux_up
Definition: ERF_Radiation.H:413
real2d lw_heating
Definition: ERF_Radiation.H:391
real2d lw_clnclrsky_flux_dn
Definition: ERF_Radiation.H:414
real3d aero_g_sw
Definition: ERF_Radiation.H:440
real1d sfc_alb_dif_nir
Definition: ERF_Radiation.H:364
real1d sfc_alb_dir_vis
Definition: ERF_Radiation.H:361
int m_ngas
Definition: ERF_Radiation.H:278
real2d p_del
Definition: ERF_Radiation.H:380
real2d t_lay
Definition: ERF_Radiation.H:378
real2d sw_flux_up
Definition: ERF_Radiation.H:399
real2d p_lev
Definition: ERF_Radiation.H:397
real2d lw_clnsky_flux_up
Definition: ERF_Radiation.H:417
real1d sfc_alb_dir_nir
Definition: ERF_Radiation.H:362
int m_nlay
Definition: ERF_Radiation.H:305
real2d lwp
Definition: ERF_Radiation.H:388
const std::vector< std::string > m_gas_names
Definition: ERF_Radiation.H:279
real2d sw_clnsky_flux_dn_dir
Definition: ERF_Radiation.H:412
string1dv gas_names_yakl_offset
Definition: ERF_Radiation.H:297
real3d cld_tau_sw_bnd
Definition: ERF_Radiation.H:444
real2d eff_radius_qi
Definition: ERF_Radiation.H:386
real2d tmp2d
Definition: ERF_Radiation.H:387
real2d qc_lay
Definition: ERF_Radiation.H:382
real2d sw_flux_dn
Definition: ERF_Radiation.H:400
real2d sw_clrsky_flux_dn
Definition: ERF_Radiation.H:408
real2d d_tint
Definition: ERF_Radiation.H:396
real1d m_gas_mol_weights
Definition: ERF_Radiation.H:296
real3d sw_bnd_flux_dir
Definition: ERF_Radiation.H:423

◆ dealloc_buffers()

void Radiation::dealloc_buffers ( )
317 {
318  // 1d size (m_ngas)
319  m_gas_mol_weights.deallocate();
320 
321  // 1d size (1 or nlay)
322  o3_lay.deallocate();
323 
324  // 1d size (ncol)
325  cosine_zenith.deallocate();
326  mu0.deallocate();
327  sfc_alb_dir_vis.deallocate();
328  sfc_alb_dir_nir.deallocate();
329  sfc_alb_dif_vis.deallocate();
330  sfc_alb_dif_nir.deallocate();
331  sfc_flux_dir_vis.deallocate();
332  sfc_flux_dir_nir.deallocate();
333  sfc_flux_dif_vis.deallocate();
334  sfc_flux_dif_nir.deallocate();
335  lat.deallocate();
336  lon.deallocate();
337  sfc_emis.deallocate();
338  t_sfc.deallocate();
339  lw_src.deallocate();
340 
341  // 2d size (ncol, nlay)
342  r_lay.deallocate();
343  p_lay.deallocate();
344  t_lay.deallocate();
345  z_del.deallocate();
346  p_del.deallocate();
347  qv_lay.deallocate();
348  qc_lay.deallocate();
349  qi_lay.deallocate();
350  cldfrac_tot.deallocate();
351  eff_radius_qc.deallocate();
352  eff_radius_qi.deallocate();
353  tmp2d.deallocate();
354  lwp.deallocate();
355  iwp.deallocate();
356 
357  sw_heating.deallocate();
358  lw_heating.deallocate();
359  sw_clrsky_heating.deallocate();
360  lw_clrsky_heating.deallocate();
361 
362  // 2d size (ncol, nlay+1)
363  d_tint.deallocate();
364  p_lev.deallocate();
365  t_lev.deallocate();
366 
367  sw_flux_up.deallocate();
368  sw_flux_dn.deallocate();
369  sw_flux_dn_dir.deallocate();
370  lw_flux_up.deallocate();
371  lw_flux_dn.deallocate();
372  sw_clnclrsky_flux_up.deallocate();
373  sw_clnclrsky_flux_dn.deallocate();
374  sw_clnclrsky_flux_dn_dir.deallocate();
375  sw_clrsky_flux_up.deallocate();
376  sw_clrsky_flux_dn.deallocate();
377  sw_clrsky_flux_dn_dir.deallocate();
378  sw_clnsky_flux_up.deallocate();
379  sw_clnsky_flux_dn.deallocate();
380  sw_clnsky_flux_dn_dir.deallocate();
381  lw_clnclrsky_flux_up.deallocate();
382  lw_clnclrsky_flux_dn.deallocate();
383  lw_clrsky_flux_up.deallocate();
384  lw_clrsky_flux_dn.deallocate();
385  lw_clnsky_flux_up.deallocate();
386  lw_clnsky_flux_dn.deallocate();
387 
388  // 3d size (ncol, nlay+1, nswbands)
389  sw_bnd_flux_up.deallocate();
390  sw_bnd_flux_dn.deallocate();
391  sw_bnd_flux_dir.deallocate();
392  sw_bnd_flux_dif.deallocate();
393 
394  // 3d size (ncol, nlay+1, nlwbands)
395  lw_bnd_flux_up.deallocate();
396  lw_bnd_flux_dn.deallocate();
397 
398  // 2d size (ncol, nswbands)
399  sfc_alb_dir.deallocate();
400  sfc_alb_dif.deallocate();
401 
402  // 2d size (ncol, nlwbands)
403  emis_sfc.deallocate();
404 
405  // 3d size (ncol, nlay, n[sw,lw]bands)
406  aero_tau_sw.deallocate();
407  aero_ssa_sw.deallocate();
408  aero_g_sw.deallocate();
409  aero_tau_lw.deallocate();
410 
411  // 3d size (ncol, nlay, n[sw,lw]bnds)
412  cld_tau_sw_bnd.deallocate();
413  cld_tau_lw_bnd.deallocate();
414 
415  // 3d size (ncol, nlay, n[sw,lw]gpts)
416  cld_tau_sw_gpt.deallocate();
417  cld_tau_lw_gpt.deallocate();
418 }

◆ finalize_impl()

void Radiation::finalize_impl ( )
1088 {
1089  // Finish rrtmgp
1090  m_gas_concs.reset();
1092 
1093  // Fill the AMReX MFs from YAKL Arrays
1095 
1096  // Write fluxes if requested
1098 
1099  // Fill output data for datalog before deallocating
1100  if (datalog_int > 0 && m_step % datalog_int == 0) {
1103 
1105  }
1106 
1107  // Deallocate the buffer arrays
1108  dealloc_buffers();
1109 }
int datalog_int
Definition: ERF_RadiationInterface.H:58
void dealloc_buffers()
Definition: ERF_Radiation.cpp:316
int m_step
Definition: ERF_Radiation.H:213
void populateDatalogMF()
Definition: ERF_Radiation.cpp:648
void write_rrtmgp_fluxes()
Definition: ERF_Radiation.cpp:614
void yakl_buffers_to_mf()
Definition: ERF_Radiation.cpp:540
GasConcs m_gas_concs
Definition: ERF_Radiation.H:298
void rrtmgp_finalize()
Definition: ERF_RRTMGP_Interface.cpp:257
void compute_heating_rate(yakl::Array< T, 2, myMem, myStyle > const &flux_up, yakl::Array< T, 2, myMem, myStyle > const &flux_dn, yakl::Array< T, 2, myMem, myStyle > const &rho, yakl::Array< T, 2, myMem, myStyle > const &dz, yakl::Array< T, 2, myMem, myStyle > &heating_rate)
Definition: ERF_RRTMGP_Utils.H:73

Referenced by rad_run_impl().

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

◆ Init()

virtual void Radiation::Init ( const amrex::Geometry &  geom,
const amrex::BoxArray &  ba,
amrex::MultiFab *  cons_in 
)
inlineoverridevirtual

Implements IRadiation.

57  {};

◆ initialize_impl()

void Radiation::initialize_impl ( )
844 {
845  // Call API to initialize
850 }
void rrtmgp_initialize(GasConcs &gas_concs, const std::string &coefficients_file_sw, const std::string &coefficients_file_lw, const std::string &cloud_optics_file_sw, const std::string &cloud_optics_file_lw)
Definition: ERF_RRTMGP_Interface.cpp:234

Referenced by rad_run_impl().

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

◆ mf_to_yakl_buffers()

void Radiation::mf_to_yakl_buffers ( )
423 {
424  bool moist = m_moist;
425  bool ice = m_ice;
426  const bool lsm = m_lsm;
427  int ncol = m_ncol;
428  int nlay = m_nlay;
429  Real dz = m_geom.CellSize(2);
430  Real cons_lat = m_lat_cons;
431  Real cons_lon = m_lon_cons;
432  for (MFIter mfi(*m_cons_in); mfi.isValid(); ++mfi) {
433  const auto& vbx = mfi.validbox();
434  const int nx = vbx.length(0);
435  const int imin = vbx.smallEnd(0);
436  const int jmin = vbx.smallEnd(1);
437  const int offset = m_col_offsets[mfi.index()];
438  const Array4<const Real>& cons_arr = m_cons_in->const_array(mfi);
439  const Array4<const Real>& z_arr = (m_z_phys) ? m_z_phys->const_array(mfi) :
440  Array4<const Real>{};
441  const Array4<const Real>& lat_arr = (m_lat) ? m_lat->const_array(mfi) :
442  Array4<const Real>{};
443  const Array4<const Real>& lon_arr = (m_lon) ? m_lon->const_array(mfi) :
444  Array4<const Real>{};
445  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
446  {
447  // map [i,j,k] 0-based to [icol, ilay] 1-based
448  const int icol = (j-jmin)*nx + (i-imin) + 1 + offset;
449  const int ilay = k+1;
450 
451  // EOS input (at CC)
452  Real r = cons_arr(i,j,k,Rho_comp);
453  Real rt = cons_arr(i,j,k,RhoTheta_comp);
454  Real qv = (moist) ? cons_arr(i,j,k,RhoQ1_comp)/r : 0.0;
455  Real qc = (moist) ? cons_arr(i,j,k,RhoQ2_comp)/r : 0.0;
456  Real qi = (ice) ? cons_arr(i,j,k,RhoQ3_comp)/r : 0.0;
457 
458  // EOS avg to z-face
459  Real r_lo = cons_arr(i,j,k-1,Rho_comp);
460  Real rt_lo = cons_arr(i,j,k-1,RhoTheta_comp);
461  Real qv_lo = (moist) ? cons_arr(i,j,k-1,RhoQ1_comp)/r_lo : 0.0;
462  Real r_avg = 0.5 * (r + r_lo);
463  Real rt_avg = 0.5 * (rt + rt_lo);
464  Real qv_avg = 0.5 * (qv + qv_lo);
465 
466  // Buffers at CC
467  r_lay(icol,ilay) = r;
468  p_lay(icol,ilay) = getPgivenRTh(rt, qv);
469  t_lay(icol,ilay) = getTgivenRandRTh(r, rt, qv);
470  z_del(icol,ilay) = (z_arr) ? 0.25 * ( (z_arr(i ,j ,k+1) - z_arr(i ,j ,k))
471  + (z_arr(i+1,j ,k+1) - z_arr(i+1,j ,k))
472  + (z_arr(i ,j+1,k+1) - z_arr(i ,j+1,k))
473  + (z_arr(i+1,j ,k+1) - z_arr(i+1,j ,k)) ) : dz;
474  qv_lay(icol,ilay) = qv;
475  qc_lay(icol,ilay) = qc;
476  qi_lay(icol,ilay) = qi;
477  cldfrac_tot(icol,ilay) = ((qc+qi)>1.0e-5) ? 1. : 0.;
478 
479  // NOTE: These are populated in 'mixing_ratio_to_cloud_mass'
480  lwp(icol,ilay) = 0.0;
481  iwp(icol,ilay) = 0.0;
482 
483  // NOTE: These would be populated from P3 (we use the constants in p3_main_impl.hpp)
484  eff_radius_qc(icol,ilay) = (qc>1.0e-12) ? 10.0e-6 : 0.0;
485  eff_radius_qi(icol,ilay) = (qi>1.0e-12) ? 25.0e-6 : 0.0;
486 
487  // Buffers on z-faces (nlay+1)
488  p_lev(icol,ilay) = getPgivenRTh(rt_avg, qv_avg);
489  t_lev(icol,ilay) = getTgivenRandRTh(r_avg, rt_avg, qv_avg);
490  if (ilay==nlay) {
491  Real r_hi = cons_arr(i,j,k+1,Rho_comp);
492  Real rt_hi = cons_arr(i,j,k+1,RhoTheta_comp);
493  Real qv_hi = (moist) ? cons_arr(i,j,k+1,RhoQ1_comp)/r_hi : 0.0;
494  r_avg = 0.5 * (r + r_hi);
495  rt_avg = 0.5 * (rt + rt_hi);
496  qv_avg = 0.5 * (qv + qv_hi);
497  p_lev(icol,ilay+1) = getPgivenRTh(rt_avg, qv_avg);
498  t_lev(icol,ilay+1) = getTgivenRandRTh(r_avg, rt_avg, qv_avg);
499  }
500 
501  // 1D data structures
502  if (k==0) {
503  lat(icol) = (m_lat) ? lat_arr(i,j,0) : cons_lat;
504  lon(icol) = (m_lon) ? lon_arr(i,j,0) : cons_lon;
505 
506  if (!lsm) {
507  // if no LSM, then set surface temperature as temperature at k=0
508  t_sfc(icol) = t_lev(icol, 1);
509  }
510  }
511 
512  });
513  }
514 
515  // Separate YAKL kernel for derived quantities
516  parallel_for(SimpleBounds<2>(ncol, nlay), YAKL_LAMBDA (int icol, int ilay)
517  {
518  p_del(icol,ilay) = std::abs(p_lev(icol,ilay+1) - p_lev(icol,ilay));
519  });
520 
521  // TODO: Fill properly
522  // No LSM, so follow EAMXX dummy atmos and set constants
523  if (!lsm) {
524  yakl::memset(mu0, 0.86);
525  yakl::memset(sfc_alb_dir_vis, 0.06);
526  yakl::memset(sfc_alb_dir_nir, 0.06);
527  yakl::memset(sfc_alb_dif_vis, 0.06);
528  yakl::memset(sfc_alb_dif_nir, 0.06);
529  }
530 
531  // TODO: Fill properly
532  yakl::memset(aero_tau_sw, 0.0);
533  yakl::memset(aero_ssa_sw, 0.0);
534  yakl::memset(aero_g_sw , 0.0);
535  yakl::memset(aero_tau_lw, 0.0);
536 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=0.)
Definition: ERF_EOS.H:84
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getTgivenRandRTh(const amrex::Real rho, const amrex::Real rhotheta, const amrex::Real qv=0.0)
Definition: ERF_EOS.H:46
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:43
#define RhoQ3_comp
Definition: ERF_IndexDefines.H:44
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
AMREX_FORCE_INLINE IntVect offset(const int face_dir, const int normal)
Definition: ERF_ReadBndryPlanes.cpp:28
amrex::MultiFab * m_lon
Definition: ERF_Radiation.H:253
amrex::MultiFab * m_cons_in
Definition: ERF_Radiation.H:243
amrex::MultiFab * m_z_phys
Definition: ERF_Radiation.H:249
amrex::Geometry m_geom
Definition: ERF_Radiation.H:222
amrex::MultiFab * m_lat
Definition: ERF_Radiation.H:252
amrex::Vector< int > m_col_offsets
Definition: ERF_Radiation.H:308
@ qv
Definition: ERF_Kessler.H:28
@ qc
Definition: ERF_SatAdj.H:36
Here is the call graph for this function:

◆ populateDatalogMF()

void Radiation::populateDatalogMF ( )
649 {
650  for (MFIter mfi(datalog_mf); mfi.isValid(); ++mfi) {
651  const auto& vbx = mfi.validbox();
652  const int nx = vbx.length(0);
653  const int imin = vbx.smallEnd(0);
654  const int jmin = vbx.smallEnd(1);
655  const int offset = m_col_offsets[mfi.index()];
656  const Array4<Real>& dst_arr = datalog_mf.array(mfi);
657  const Array4<Real>& q_arr = m_qheating_rates->array(mfi);
658  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
659  {
660  // map [i,j,k] 0-based to [icol, ilay] 1-based
661  const int icol = (j-jmin)*nx + (i-imin) + 1 + offset;
662  const int ilay = k+1;
663 
664  dst_arr(i,j,k,0) = q_arr(i, j, k, 0);
665  dst_arr(i,j,k,1) = q_arr(i, j, k, 1);
666 
667  // SW and LW fluxes
668  dst_arr(i,j,k,2) = sw_flux_up(icol,ilay);
669  dst_arr(i,j,k,3) = sw_flux_dn(icol,ilay);
670  dst_arr(i,j,k,4) = sw_flux_dn_dir(icol,ilay);
671  dst_arr(i,j,k,5) = lw_flux_up(icol,ilay);
672  dst_arr(i,j,k,6) = lw_flux_dn(icol,ilay);
673 
674  // Cosine zenith angle
675  dst_arr(i,j,k,7) = mu0(icol);
676 
677  // Clear sky heating rates and fluxes:
678  dst_arr(i,j,k,8) = sw_clrsky_heating(icol, ilay);
679  dst_arr(i,j,k,9) = lw_clrsky_heating(icol, ilay);
680 
681  dst_arr(i,j,k,10) = sw_clrsky_flux_up(icol,ilay);
682  dst_arr(i,j,k,11) = sw_clrsky_flux_dn(icol,ilay);
683  dst_arr(i,j,k,12) = sw_clrsky_flux_dn_dir(icol,ilay);
684  dst_arr(i,j,k,13) = lw_clrsky_flux_up(icol,ilay);
685  dst_arr(i,j,k,14) = lw_clrsky_flux_dn(icol,ilay);
686 
687  // Clean sky fluxes:
688  if (m_extra_clnsky_diag) {
689  dst_arr(i,j,k,15) = sw_clnsky_flux_up(icol,ilay);
690  dst_arr(i,j,k,16) = sw_clnsky_flux_dn(icol,ilay);
691  dst_arr(i,j,k,17) = sw_clnsky_flux_dn_dir(icol,ilay);
692  dst_arr(i,j,k,18) = lw_clnsky_flux_up(icol,ilay);
693  dst_arr(i,j,k,19) = lw_clnsky_flux_dn(icol,ilay);
694  }
695 
696  // Clean-clear sky fluxes:
698  dst_arr(i,j,k,20) = sw_clnclrsky_flux_up(icol,ilay);
699  dst_arr(i,j,k,21) = sw_clnclrsky_flux_dn(icol,ilay);
700  dst_arr(i,j,k,22) = sw_clnclrsky_flux_dn_dir(icol,ilay);
701  dst_arr(i,j,k,23) = lw_clnclrsky_flux_up(icol,ilay);
702  dst_arr(i,j,k,24) = lw_clnclrsky_flux_dn(icol,ilay);
703  }
704  });
705  }
706 }
amrex::MultiFab datalog_mf
Definition: ERF_Radiation.H:264
amrex::MultiFab * m_qheating_rates
Definition: ERF_Radiation.H:246
Here is the call graph for this function:

◆ rad_run_impl()

void Radiation::rad_run_impl ( )
inline
190  {
191  if (m_update_rad) {
192  amrex::Print() << "Advancing radiation at level: " << m_lev << " ...";
193  this->initialize_impl();
194  this->run_impl();
195  this->finalize_impl();
196  amrex::Print() << "DONE\n";
197  }
198  }
void initialize_impl()
Definition: ERF_Radiation.cpp:843
void run_impl()
Definition: ERF_Radiation.cpp:854
void finalize_impl()
Definition: ERF_Radiation.cpp:1087
int m_lev
Definition: ERF_Radiation.H:210
bool m_update_rad
Definition: ERF_Radiation.H:228

Referenced by Run().

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

◆ Run()

virtual void Radiation::Run ( int &  level,
int &  step,
amrex::Real &  time,
const amrex::Real &  dt,
const amrex::BoxArray &  ba,
amrex::Geometry &  geom,
amrex::MultiFab *  cons_in,
amrex::MultiFab *  lsm_fluxes,
amrex::MultiFab *  lsm_zenith,
amrex::MultiFab *  qheating_rates,
amrex::MultiFab *  z_phys,
amrex::MultiFab *  lat,
amrex::MultiFab *  lon 
)
inlineoverridevirtual

Implements IRadiation.

72  {
73  set_grids(level, step, time, dt, ba, geom, cons_in, lsm_fluxes, lsm_zenith, qheating_rates, z_phys, lat, lon);
74  rad_run_impl();
75  }
void set_grids(int &level, int &step, amrex::Real &time, const amrex::Real &dt, const amrex::BoxArray &ba, amrex::Geometry &geom, amrex::MultiFab *cons_in, amrex::MultiFab *lsm_fluxes, amrex::MultiFab *lsm_zenith, amrex::MultiFab *qheating_rates, amrex::MultiFab *z_phys, amrex::MultiFab *lat, amrex::MultiFab *lon)
Definition: ERF_Radiation.cpp:119
void rad_run_impl()
Definition: ERF_Radiation.H:189
Here is the call graph for this function:

◆ run_impl()

void Radiation::run_impl ( )
855 {
856  // Local copies
857  const auto ncol = m_ncol;
858  const auto nlay = m_nlay;
859  const auto nswbands = m_nswbands;
860 
861  // Compute orbital parameters; these are used both for computing
862  // the solar zenith angle and also for computing total solar
863  // irradiance scaling (tsi_scaling).
864  real obliqr, lambm0, mvelpp;
865  int orbital_year = m_orbital_year;
866  real eccen = m_orbital_eccen;
867  real obliq = m_orbital_obliq;
868  real mvelp = m_orbital_mvelp;
869  if (eccen >= 0 && obliq >= 0 && mvelp >= 0) {
870  // fixed orbital parameters forced with orbital_year == ORB_UNDEF_INT
871  orbital_year = ORB_UNDEF_INT;
872  }
873  orbital_params(orbital_year, eccen, obliq,
874  mvelp, obliqr, lambm0, mvelpp);
875 
876  // Use the orbital parameters to calculate the solar declination and eccentricity factor
877  real delta, eccf;
878  // Want day + fraction; calday 1 == Jan 1 0Z
879  static constexpr real dpy[] = {0.0, 31.0, 59.0, 90.0, 120.0, 151.0, 181.0, 212.0, 243.0, 273.0, 304.0, 334.0};
880  bool leap = (m_orbital_year % 4 == 0 && (!(m_orbital_year % 100 == 0) || (m_orbital_year % 400 == 0))) ? true : false;
881  real calday = dpy[m_orbital_mon] + m_orbital_day + m_orbital_sec/86400.0;
882  // add extra day if leap year
883  if (leap) {
884  calday += 1.0;
885  }
886  orbital_decl(calday, eccen, mvelpp, lambm0, obliqr, delta, eccf);
887 
888  // Overwrite eccf if using a fixed solar constant.
889  auto fixed_total_solar_irradiance = m_fixed_total_solar_irradiance;
890  if (fixed_total_solar_irradiance >= 0){
891  eccf = fixed_total_solar_irradiance/1360.9;
892  }
893 
894  // Precompute volume mixing ratio (VMR) for all gases
895  //
896  // H2O is obtained from qv.
897  // All other comps are set to constants for now
898  for (int igas(0); igas < m_ngas; ++igas) {
899  auto name = m_gas_names[igas];
900  auto gas_mol_weight = m_mol_weight_gas[igas];
901  if (name == "H2O") {
902  parallel_for(SimpleBounds<2>(ncol, nlay), YAKL_LAMBDA (int icol, int ilay)
903  {
904  tmp2d(icol,ilay) = qv_lay(icol,ilay) * mwdair/ gas_mol_weight;
905  });
906  } else if (name == "CO2") {
907  yakl::memset(tmp2d, m_co2vmr);
908  } else if (name == "O3") {
909  if (m_o3_size==1) {
910  yakl::memset(tmp2d, m_o3vmr[0] );
911  } else {
912  parallel_for(SimpleBounds<2>(ncol, nlay), YAKL_LAMBDA (int icol, int ilay)
913  {
914  tmp2d(icol,ilay) = o3_lay(ilay);
915  });
916  }
917  } else if (name == "N2O") {
918  yakl::memset(tmp2d, m_n2ovmr);
919  } else if (name == "CO") {
920  yakl::memset(tmp2d, m_covmr );
921  } else if (name == "CH4") {
922  yakl::memset(tmp2d, m_ch4vmr);
923  } else if (name == "O2") {
924  yakl::memset(tmp2d, m_o2vmr );
925  } else if (name == "N2") {
926  yakl::memset(tmp2d, m_n2vmr );
927  } else {
928  Abort("Radiation: Unknown gas component.");
929  }
930 
931  // Populate GasConcs object
932  m_gas_concs.set_vmr(name, tmp2d);
933  }
934 
935 
936  // TODO: No LSM so leaving comment for code
937  // Calculate T_int from longwave flux up from the surface, assuming
938  // blackbody emission with emissivity of 1.
939  if (!m_lsm) {
940  // If no LSM, set default values for surface emissivity and LW src
941  yakl::memset(emis_sfc, 0.98);
942  yakl::memset(lw_src, 0.0);
943  }
944 
945  // Determine the cosine zenith angle.
946  // This must be done on HOST and copied to device.
947  realHost1d h_mu0("h_mu0", ncol);
948  if (m_fixed_solar_zenith_angle > 0) {
949  yakl::memset(h_mu0, m_fixed_solar_zenith_angle);
950  } else {
951  realHost1d h_lat("h_lat", ncol);
952  realHost1d h_lon("h_lon", ncol);
953  lat.deep_copy_to(h_lat);
954  lon.deep_copy_to(h_lon);
955  parallel_for(ncol, YAKL_LAMBDA (int icol)
956  {
957  // Convert lat/lon to radians
958  real dt = real(m_dt);
959  real lat_col = h_lat(icol)*PI/180.0;
960  real lon_col = h_lon(icol)*PI/180.0;
961  real lcalday = calday;
962  real ldelta = delta;
963  h_mu0(icol) = orbital_cos_zenith(lcalday, lat_col, lon_col, ldelta, m_rad_freq_in_steps * dt);
964  });
965  }
966  h_mu0.deep_copy_to(mu0);
967 
968  // Compute layer cloud mass (per unit area), populates lwp/iwp
971 
972  // Convert to g/m2 (needed by RRTMGP)
973  parallel_for(SimpleBounds<2>(ncol, nlay), YAKL_LAMBDA (int icol, int ilay)
974  {
975  lwp(icol,ilay) *= 1.e3;
976  iwp(icol,ilay) *= 1.e3;
977  });
978 
979  // Compute band-by-band surface_albedos. This is needed since
980  // the AD passes broadband albedos, but rrtmgp require band-by-band.
985 
986  // Run RRTMGP driver
988  p_lay, t_lay, p_lev, t_lev,
989  m_gas_concs,
1005 
1006 #if 0
1007  // UNIT TEST
1008  //================================================================================
1009  yakl::memset(mu0, 0.86);
1010  yakl::memset(sfc_alb_dir_vis, 0.06);
1011  yakl::memset(sfc_alb_dir_nir, 0.06);
1012  yakl::memset(sfc_alb_dif_vis, 0.06);
1013  yakl::memset(sfc_alb_dif_nir, 0.06);
1014 
1015  // Generate some fake liquid and ice water data. We pick values to be midway between
1016  // the min and max of the valid lookup table values for effective radii
1017  real rel_val = 0.5 * (rrtmgp::cloud_optics_sw.get_min_radius_liq()
1018  + rrtmgp::cloud_optics_sw.get_max_radius_liq());
1019  real rei_val = 0.5 * (rrtmgp::cloud_optics_sw.get_min_radius_ice()
1020  + rrtmgp::cloud_optics_sw.get_max_radius_ice());
1021 
1022  // Restrict clouds to troposphere (> 100 hPa = 100*100 Pa) and not very close to the ground (< 900 hPa), and
1023  // put them in 2/3 of the columns since that's roughly the total cloudiness of earth.
1024  // Set sane values for liquid and ice water path.
1025  // NOTE: these "sane" values are in g/m2!
1026  parallel_for( SimpleBounds<2>(nlay,ncol) , YAKL_LAMBDA (int ilay, int icol)
1027  {
1028  cldfrac_tot(icol,ilay) = (p_lay(icol,ilay) > 100._wp * 100._wp) &&
1029  (p_lay(icol,ilay) < 900._wp * 100._wp) &&
1030  (icol%3 != 0);
1031  // Ice and liquid will overlap in a few layers
1032  lwp(icol,ilay) = (cldfrac_tot(icol,ilay) && t_lay(icol,ilay) > 263._wp) ? 10._wp : 0._wp;
1033  iwp(icol,ilay) = (cldfrac_tot(icol,ilay) && t_lay(icol,ilay) < 273._wp) ? 10._wp : 0._wp;
1034  eff_radius_qc(icol,ilay) = (lwp(icol,ilay) > 0._wp) ? rel_val : 0._wp;
1035  eff_radius_qi(icol,ilay) = (iwp(icol,ilay) > 0._wp) ? rei_val : 0._wp;
1036  });
1037 
1042 
1043  yakl::memset(aero_tau_sw, 0.0);
1044  yakl::memset(aero_ssa_sw, 0.0);
1045  yakl::memset(aero_g_sw , 0.0);
1046  yakl::memset(aero_tau_lw, 0.0);
1047 
1049  p_lay, t_lay, p_lev, t_lev,
1050  m_gas_concs,
1064  1.0);
1065  //================================================================================
1066 #endif
1067 
1068  // Update heating tendency
1071 
1072  // Compute surface fluxes
1073  //const int kbot = nlay + 1; // Should this be 1 for our layout?
1074  const int kbot = 1;
1075  parallel_for(SimpleBounds<3>(ncol, nlay+1, nswbands), YAKL_LAMBDA (int icol, int ilay, int ibnd)
1076  {
1077  sw_bnd_flux_dif(icol,ilay,ibnd) = sw_bnd_flux_dn(icol,ilay,ibnd) - sw_bnd_flux_dir(icol,ilay,ibnd);
1078  });
1079  rrtmgp::compute_broadband_surface_fluxes(ncol, kbot, nswbands,
1083 }
static constexpr int ORB_UNDEF_INT
Definition: ERF_Constants.H:96
constexpr amrex::Real mwdair
Definition: ERF_Constants.H:64
constexpr amrex::Real PI
Definition: ERF_Constants.H:6
double real
Definition: ERF_OrbCosZenith.H:9
real orbital_cos_zenith(real &jday, real &lat, real &lon, real &declin, real dt_avg, real uniform_angle, real constant_zenith_angle_deg)
Definition: ERF_OrbCosZenith.cpp:4
void orbital_params(int &iyear_AD, real &eccen, real &obliq, real &mvelp, real &obliqr, real &lambm0, real &mvelpp)
Definition: ERF_OrbCosZenith.cpp:139
void orbital_decl(real &calday, real &eccen, real &mvelpp, real &lambm0, real &obliqr, real &delta, real &eccf)
Definition: ERF_OrbCosZenith.cpp:512
amrex::Real m_dt
Definition: ERF_Radiation.H:219
int m_orbital_mon
Definition: ERF_Radiation.H:321
int m_orbital_sec
Definition: ERF_Radiation.H:323
int m_orbital_day
Definition: ERF_Radiation.H:322
CloudOptics cloud_optics_sw
Definition: ERF_RRTMGP_Interface.cpp:34
void compute_band_by_band_surface_albedos(const int ncol, const int nswbands, real1d &sfc_alb_dir_vis, real1d &sfc_alb_dir_nir, real1d &sfc_alb_dif_vis, real1d &sfc_alb_dif_nir, real2d &sfc_alb_dir, real2d &sfc_alb_dif)
Definition: ERF_RRTMGP_Interface.cpp:268
void compute_broadband_surface_fluxes(const int ncol, const int ktop, const int nswbands, real3d &sw_bnd_flux_dir, real3d &sw_bnd_flux_dif, real1d &sfc_flux_dir_vis, real1d &sfc_flux_dir_nir, real1d &sfc_flux_dif_vis, real1d &sfc_flux_dif_nir)
Definition: ERF_RRTMGP_Interface.cpp:328
void rrtmgp_main(const int ncol, const int nlay, real2d &p_lay, real2d &t_lay, real2d &p_lev, real2d &t_lev, GasConcs &gas_concs, real2d &sfc_alb_dir, real2d &sfc_alb_dif, real1d &mu0, real1d &t_sfc, real2d &emis_sfc, real1d &lw_src, real2d &lwp, real2d &iwp, real2d &rel, real2d &rei, real2d &cldfrac, real3d &aer_tau_sw, real3d &aer_ssa_sw, real3d &aer_asm_sw, real3d &aer_tau_lw, real3d &cld_tau_sw_bnd, real3d &cld_tau_lw_bnd, real3d &cld_tau_sw_gpt, real3d &cld_tau_lw_gpt, real2d &sw_flux_up, real2d &sw_flux_dn, real2d &sw_flux_dn_dir, real2d &lw_flux_up, real2d &lw_flux_dn, real2d &sw_clnclrsky_flux_up, real2d &sw_clnclrsky_flux_dn, real2d &sw_clnclrsky_flux_dn_dir, real2d &sw_clrsky_flux_up, real2d &sw_clrsky_flux_dn, real2d &sw_clrsky_flux_dn_dir, real2d &sw_clnsky_flux_up, real2d &sw_clnsky_flux_dn, real2d &sw_clnsky_flux_dn_dir, real2d &lw_clnclrsky_flux_up, real2d &lw_clnclrsky_flux_dn, real2d &lw_clrsky_flux_up, real2d &lw_clrsky_flux_dn, real2d &lw_clnsky_flux_up, real2d &lw_clnsky_flux_dn, real3d &sw_bnd_flux_up, real3d &sw_bnd_flux_dn, real3d &sw_bnd_flux_dn_dir, real3d &lw_bnd_flux_up, real3d &lw_bnd_flux_dn, const real tsi_scaling, const bool extra_clnclrsky_diag, const bool extra_clnsky_diag)
Definition: ERF_RRTMGP_Interface.cpp:391
void mixing_ratio_to_cloud_mass(yakl::Array< T, 2, myMem, myStyle > const &mixing_ratio, yakl::Array< T, 2, myMem, myStyle > const &cloud_fraction, yakl::Array< T, 2, myMem, myStyle > const &dp, yakl::Array< T, 2, myMem, myStyle > &cloud_mass)
Definition: ERF_RRTMGP_Utils.H:23

Referenced by rad_run_impl().

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

◆ set_grids()

void Radiation::set_grids ( int &  level,
int &  step,
amrex::Real &  time,
const amrex::Real &  dt,
const amrex::BoxArray &  ba,
amrex::Geometry &  geom,
amrex::MultiFab *  cons_in,
amrex::MultiFab *  lsm_fluxes,
amrex::MultiFab *  lsm_zenith,
amrex::MultiFab *  qheating_rates,
amrex::MultiFab *  z_phys,
amrex::MultiFab *  lat,
amrex::MultiFab *  lon 
)
133 {
134  // Set data members that may change
135  m_lev = level;
136  m_step = step;
137  m_time = time;
138  m_dt = dt;
139  m_geom = geom;
140  m_cons_in = cons_in;
141  m_lsm_fluxes = lsm_fluxes;
142  m_lsm_zenith = lsm_zenith;
143  m_qheating_rates = qheating_rates;
144  m_z_phys = z_phys;
145  m_lat = lat;
146  m_lon = lon;
147 
148  // Update the day and month
149  time_t timestamp = time_t(time);
150  struct tm *timeinfo = gmtime(&timestamp);
151  if (m_fixed_orbital_year) {
152  m_orbital_mon = timeinfo->tm_mon + 1;
153  m_orbital_day = timeinfo->tm_mday;
154  m_orbital_sec = timeinfo->tm_hour*3600 + timeinfo->tm_min*60 + timeinfo->tm_sec;
155  } else {
156  m_orbital_year = timeinfo->tm_year + 1900;
157  m_orbital_mon = timeinfo->tm_mon + 1;
158  m_orbital_day = timeinfo->tm_mday;
159  m_orbital_sec = timeinfo->tm_hour*3600 + timeinfo->tm_min*60 + timeinfo->tm_sec;
160  }
161 
162  // Only allocate and proceed if we are going to update radiation
163  m_update_rad = false;
164  if (m_rad_freq_in_steps > 0) { m_update_rad = ( (m_step == 0) || (m_step % m_rad_freq_in_steps == 0) ); }
165 
166  if (m_update_rad) {
167  // Reset vector of offsets for columnar data
168  m_nlay = geom.Domain().length(2);
169 
170  m_ncol = 0;
171  m_col_offsets.clear();
172  m_col_offsets.resize(int(ba.size()));
173  for (MFIter mfi(*m_cons_in); mfi.isValid(); ++mfi) {
174  const auto& vbx = mfi.validbox();
175  int nx = vbx.length(0);
176  int ny = vbx.length(1);
177  m_col_offsets[mfi.index()] = m_ncol;
178  m_ncol += nx * ny;
179  }
180 
181  // Allocate the buffer arrays
182  alloc_buffers();
183 
184  // Fill the YAKL Arrays from AMReX MFs
186 
187  if (m_first_step) {
188  // Initialize datalog MF on first step
189  m_first_step = false;
190  datalog_mf.define(cons_in->boxArray(), cons_in->DistributionMap(), 25, 0);
191  datalog_mf.setVal(0.0);
192  }
193  }
194 }
void mf_to_yakl_buffers()
Definition: ERF_Radiation.cpp:422
amrex::MultiFab * m_lsm_fluxes
Definition: ERF_Radiation.H:260
amrex::MultiFab * m_lsm_zenith
Definition: ERF_Radiation.H:261
bool m_first_step
Definition: ERF_Radiation.H:233
void alloc_buffers()
Definition: ERF_Radiation.cpp:197
amrex::Real m_time
Definition: ERF_Radiation.H:216

Referenced by Run().

Here is the caller graph for this function:

◆ set_lsm_inputs()

template<typename LandSurfaceModelType >
void Radiation::set_lsm_inputs ( LandSurfaceModelType *  model)
inline
95  {
96  if constexpr(std::is_same_v<LandSurfaceModelType, SLM>)
97  {
98  if (!m_update_rad)
99  {
100  // skip getting LSM inputs if radiation not updating this timestep
101  return;
102  }
103 
104  // get surface temperature, LW flux, and emissivities from SLM
105  /*
106  auto slm_to_rad_vars = model->export_to_RRTMGP();
107 
108  for (amrex::MFIter mfi(*slm_to_rad_vars[0]); mfi.isValid(); ++mfi) {
109  const auto& vbx = mfi.validbox();
110  const auto& sbx = amrex::makeSlab(vbx, 2, 0);
111 
112  const int nx = vbx.length(0);
113  const int imin = vbx.smallEnd(0);
114  const int jmin = vbx.smallEnd(1);
115  const int offset = m_col_offsets[mfi.index()];
116 
117  const auto &slm_tsurf = slm_to_rad_vars[0]->const_array(mfi);
118  const auto &slm_alb_dir_vis_arr = slm_to_rad_vars[2]->const_array(mfi);
119  const auto &slm_alb_dir_nir_arr = slm_to_rad_vars[4]->const_array(mfi);
120  const auto &slm_IR_emis_arr = slm_to_rad_vars[5]->const_array(mfi);
121  const auto &slm_net_rad_arr = slm_to_rad_vars[6]->const_array(mfi);
122  amrex::ParallelFor(sbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
123  {
124  // map [i,j,k] 0-based to [icol, ilay] 1-based
125  const int icol = (j-jmin)*nx + (i-imin) + 1 + offset;
126  const int ilay = 1;
127 
128  t_sfc(icol) = slm_tsurf(i, j, k);
129 
130  sfc_alb_dir_vis(icol) = slm_alb_dir_vis_arr(i, j, k);
131  sfc_alb_dir_nir(icol) = slm_alb_dir_nir_arr(i, j, k);
132  sfc_alb_dif_vis(icol) = slm_alb_dir_vis_arr(i, j, k);
133  sfc_alb_dif_nir(icol) = slm_alb_dir_nir_arr(i, j, k);
134 
135  sfc_emis(icol) = slm_IR_emis_arr(i, j, k);
136 
137  //lw_src(icol) = slm_net_rad_arr(i, j, k, SLM_NetRad::net_lwup1);
138  lw_src(icol) = 0.0; // TODO
139  });
140  }
141 
142  // expand sfc_emis and lw_src over nlwbands
143  // TODO: check if this is correct - should emissivity vary based on band?
144  yakl::fortran::parallel_for(yakl::fortran::SimpleBounds<2>(m_nlwbands, m_ncol), YAKL_LAMBDA(const int ibnd, const int icol)
145  {
146  emis_sfc(icol, ibnd) = sfc_emis(icol);
147  });
148  */
149 
150  yakl::memset(emis_sfc, 0.95);
151  yakl::memset(lw_src, 0.0);
152  }
153  }

◆ write_rrtmgp_fluxes()

void Radiation::write_rrtmgp_fluxes ( )
615 {
616  int n_fluxes = 5;
617  MultiFab mf_flux(m_cons_in->boxArray(), m_cons_in->DistributionMap(), n_fluxes, 0);
618 
619  for (MFIter mfi(mf_flux); mfi.isValid(); ++mfi) {
620  const auto& vbx = mfi.validbox();
621  const int nx = vbx.length(0);
622  const int imin = vbx.smallEnd(0);
623  const int jmin = vbx.smallEnd(1);
624  const int offset = m_col_offsets[mfi.index()];
625  const Array4<Real>& dst_arr = mf_flux.array(mfi);
626  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
627  {
628  // map [i,j,k] 0-based to [icol, ilay] 1-based
629  const int icol = (j-jmin)*nx + (i-imin) + 1 + offset;
630  const int ilay = k+1;
631 
632  // SW and LW fluxes
633  dst_arr(i,j,k,0) = sw_flux_up(icol,ilay);
634  dst_arr(i,j,k,1) = sw_flux_dn(icol,ilay);
635  dst_arr(i,j,k,2) = sw_flux_dn_dir(icol,ilay);
636  dst_arr(i,j,k,3) = lw_flux_up(icol,ilay);
637  dst_arr(i,j,k,4) = lw_flux_dn(icol,ilay);
638  });
639  }
640 
641 
642  std::string plotfilename = amrex::Concatenate("plt_rad", m_step, 5);
643  Vector<std::string> flux_names = {"sw_flux_up", "sw_flux_dn", "sw_flux_dir",
644  "lw_flux_up", "lw_flux_dn"};
645  WriteSingleLevelPlotfile(plotfilename, mf_flux, flux_names, m_geom, m_time, m_step);
646 }
Here is the call graph for this function:

◆ WriteDataLog()

void Radiation::WriteDataLog ( const amrex::Real &  time)
overridevirtual

Implements IRadiation.

709 {
710  constexpr int datwidth = 14;
711  constexpr int datprecision = 9;
712  constexpr int timeprecision = 13;
713 
714  Gpu::HostVector<Real> h_avg_radqrsw, h_avg_radqrlw, h_avg_sw_up, h_avg_sw_dn, h_avg_sw_dn_dir, h_avg_lw_up, h_avg_lw_dn, h_avg_zenith;
715  // Clear sky
716  Gpu::HostVector<Real> h_avg_radqrcsw, h_avg_radqrclw, h_avg_sw_clr_up, h_avg_sw_clr_dn, h_avg_sw_clr_dn_dir, h_avg_lw_clr_up, h_avg_lw_clr_dn;
717  // Clean sky
718  Gpu::HostVector<Real> h_avg_sw_cln_up, h_avg_sw_cln_dn, h_avg_sw_cln_dn_dir, h_avg_lw_cln_up, h_avg_lw_cln_dn;
719  // Clean clear sky
720  Gpu::HostVector<Real> h_avg_sw_clnclr_up, h_avg_sw_clnclr_dn, h_avg_sw_clnclr_dn_dir, h_avg_lw_clnclr_up, h_avg_lw_clnclr_dn;
721 
722 
723  auto domain = m_geom.Domain();
724  h_avg_radqrsw = sumToLine(datalog_mf, 0, 1, domain, 2);
725  h_avg_radqrlw = sumToLine(datalog_mf, 1, 1, domain, 2);
726  h_avg_sw_up = sumToLine(datalog_mf, 2, 1, domain, 2);
727  h_avg_sw_dn = sumToLine(datalog_mf, 3, 1, domain, 2);
728  h_avg_sw_dn_dir = sumToLine(datalog_mf, 4, 1, domain, 2);
729  h_avg_lw_up = sumToLine(datalog_mf, 5, 1, domain, 2);
730  h_avg_lw_dn = sumToLine(datalog_mf, 6, 1, domain, 2);
731  h_avg_zenith = sumToLine(datalog_mf, 7, 1, domain, 2);
732 
733  h_avg_radqrcsw = sumToLine(datalog_mf, 8, 1, domain, 2);
734  h_avg_radqrclw = sumToLine(datalog_mf, 9, 1, domain, 2);
735  h_avg_sw_clr_up = sumToLine(datalog_mf, 10, 1, domain, 2);
736  h_avg_sw_clr_dn = sumToLine(datalog_mf, 11, 1, domain, 2);
737  h_avg_sw_clr_dn_dir = sumToLine(datalog_mf, 12, 1, domain, 2);
738  h_avg_lw_clr_up = sumToLine(datalog_mf, 13, 1, domain, 2);
739  h_avg_lw_clr_dn = sumToLine(datalog_mf, 14, 1, domain, 2);
740 
741  if (m_extra_clnsky_diag) {
742  h_avg_sw_cln_up = sumToLine(datalog_mf, 15, 1, domain, 2);
743  h_avg_sw_cln_dn = sumToLine(datalog_mf, 16, 1, domain, 2);
744  h_avg_sw_cln_dn_dir = sumToLine(datalog_mf, 17, 1, domain, 2);
745  h_avg_lw_cln_up = sumToLine(datalog_mf, 18, 1, domain, 2);
746  h_avg_lw_cln_dn = sumToLine(datalog_mf, 19, 1, domain, 2);
747  }
748 
750  h_avg_sw_clnclr_up = sumToLine(datalog_mf, 20, 1, domain, 2);
751  h_avg_sw_clnclr_dn = sumToLine(datalog_mf, 21, 1, domain, 2);
752  h_avg_sw_clnclr_dn_dir = sumToLine(datalog_mf, 22, 1, domain, 2);
753  h_avg_lw_clnclr_up = sumToLine(datalog_mf, 23, 1, domain, 2);
754  h_avg_lw_clnclr_dn = sumToLine(datalog_mf, 24, 1, domain, 2);
755  }
756 
757  Real area_z = static_cast<Real>(domain.length(0)*domain.length(1));
758  int nz = domain.length(2);
759  for (int k = 0; k < nz; k++) {
760  h_avg_radqrsw[k] /= area_z;
761  h_avg_radqrlw[k] /= area_z;
762  h_avg_sw_up[k] /= area_z;
763  h_avg_sw_dn[k] /= area_z;
764  h_avg_sw_dn_dir[k] /= area_z;
765  h_avg_lw_up[k] /= area_z;
766  h_avg_lw_dn[k] /= area_z;
767  h_avg_zenith[k] /= area_z;
768 
769  h_avg_radqrcsw[k] /= area_z;
770  h_avg_radqrclw[k] /= area_z;
771  h_avg_sw_clr_up[k] /= area_z;
772  h_avg_sw_clr_dn[k] /= area_z;
773  h_avg_sw_clr_dn_dir[k] /= area_z;
774  h_avg_lw_clr_up[k] /= area_z;
775  h_avg_lw_clr_dn[k] /= area_z;
776  }
777 
778  if (m_extra_clnsky_diag) {
779  for (int k = 0; k < nz; k++) {
780  h_avg_sw_cln_up[k] /= area_z;
781  h_avg_sw_cln_dn[k] /= area_z;
782  h_avg_sw_cln_dn_dir[k] /= area_z;
783  h_avg_lw_cln_up[k] /= area_z;
784  h_avg_lw_cln_dn[k] /= area_z;
785  }
786  }
787 
789  for (int k = 0; k < nz; k++) {
790  h_avg_sw_clnclr_up[k] /= area_z;
791  h_avg_sw_clnclr_dn[k] /= area_z;
792  h_avg_sw_clnclr_dn_dir[k] /= area_z;
793  h_avg_lw_clnclr_up[k] /= area_z;
794  h_avg_lw_clnclr_dn[k] /= area_z;
795  }
796  }
797 
798  if (ParallelDescriptor::IOProcessor()) {
799  std::ostream& log = *datalog;
800  if (log.good()) {
801 
802  for (int k = 0; k < nz; k++)
803  {
804  Real z = k * m_geom.CellSize(2);
805  log << std::setw(datwidth) << std::setprecision(timeprecision) << time << " "
806  << std::setw(datwidth) << std::setprecision(datprecision) << z << " "
807  << h_avg_radqrsw[k] << " " << h_avg_radqrlw[k] << " " << h_avg_sw_up[k] << " "
808  << h_avg_sw_dn[k] << " " << h_avg_sw_dn_dir[k] << " " << h_avg_lw_up[k] << " "
809  << h_avg_lw_dn[k] << " " << h_avg_zenith[k] << " "
810  << h_avg_radqrcsw[k] << " " << h_avg_radqrclw[k] << " " << h_avg_sw_clr_up[k] << " "
811  << h_avg_sw_clr_dn[k] << " " << h_avg_sw_clr_dn_dir[k] << " " << h_avg_lw_clr_up[k] << " "
812  << h_avg_lw_clr_dn[k] << " ";
813  if (m_extra_clnsky_diag) {
814  log << h_avg_sw_cln_up[k] << " " << h_avg_sw_cln_dn[k] << " " << h_avg_sw_cln_dn_dir[k] << " "
815  << h_avg_lw_cln_up[k] << " " << h_avg_lw_cln_dn[k] << " ";
816  } else {
817  log << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " ";
818  }
819 
821  log << h_avg_sw_clnclr_up[k] << " " << h_avg_sw_clnclr_dn[k] << " " << h_avg_sw_clnclr_dn_dir[k] << " "
822  << h_avg_lw_clnclr_up[k] << " " << h_avg_lw_clnclr_dn[k] << std::endl;
823  } else {
824  log << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << std::endl;
825  }
826  }
827  // Write top face values
828  Real z = nz * m_geom.CellSize(2);
829  log << std::setw(datwidth) << std::setprecision(timeprecision) << time << " "
830  << std::setw(datwidth) << std::setprecision(datprecision) << z << " "
831  << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " "
832  << 0.0 << " " << 0.0 << " "
833  << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " "
834  << 0.0 << " "
835  << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " "
836  << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0
837  << std::endl;
838  }
839  }
840 }
std::unique_ptr< std::fstream > datalog
Definition: ERF_RadiationInterface.H:55

◆ yakl_buffers_to_mf()

void Radiation::yakl_buffers_to_mf ( )
541 {
542  for (MFIter mfi(*m_cons_in); mfi.isValid(); ++mfi) {
543  const auto& vbx = mfi.validbox();
544  const auto& sbx = makeSlab(vbx,2,vbx.smallEnd(2));
545  const int nx = vbx.length(0);
546  const int imin = vbx.smallEnd(0);
547  const int jmin = vbx.smallEnd(1);
548  const int offset = m_col_offsets[mfi.index()];
549  const Array4<Real>& q_arr = m_qheating_rates->array(mfi);
550  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
551  {
552  // map [i,j,k] 0-based to [icol, ilay] 1-based
553  const int icol = (j-jmin)*nx + (i-imin) + 1 + offset;
554  const int ilay = k+1;
555 
556  // Temperature heating rate for SW and LW
557  q_arr(i,j,k,0) = sw_heating(icol,ilay);
558  q_arr(i,j,k,1) = lw_heating(icol,ilay);
559 
560  // Convert the rates for theta_d
561  Real exner = getExnergivenP(Real(p_lay(icol,ilay)), R_d/Cp_d);
562  q_arr(i,j,k,0) *= exner;
563  q_arr(i,j,k,1) *= exner;
564 
565  /*
566  if (i==0 && j==0) {
567  AllPrint() << "Qsrcs: " << IntVect(i,j,k) << ' '
568  << IntVect(icol,0,ilay) << ' '
569  << q_arr(i,j,k,0) << ' '
570  << q_arr(i,j,k,1) << ' '
571  << sw_heating(icol,ilay) << ' '
572  << lw_heating(icol,ilay) << ' '
573  << exner << "\n";
574  }
575  */
576 
577  });
578  if (m_lsm_fluxes) {
579  const Array4<Real>& lsm_arr = m_lsm_fluxes->array(mfi);
580  ParallelFor(sbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
581  {
582  // map [i,j,k] 0-based to [icol, ilay] 1-based
583  const int icol = (j-jmin)*nx + (i-imin) + 1 + offset;
584 
585  // SW fluxes for LSM
586  lsm_arr(i,j,k,0) = sfc_flux_dir_vis(icol);
587  lsm_arr(i,j,k,1) = sfc_flux_dir_nir(icol);
588  lsm_arr(i,j,k,2) = sfc_flux_dif_vis(icol);
589  lsm_arr(i,j,k,3) = sfc_flux_dif_nir(icol);
590 
591  // Net SW flux for LSM
592  lsm_arr(i,j,k,4) = sfc_flux_dir_vis(icol) + sfc_flux_dir_nir(icol)
593  + sfc_flux_dif_vis(icol) + sfc_flux_dif_nir(icol);
594 
595  // LW flux for LSM (at bottom surface)
596  lsm_arr(i,j,k,5) = lw_flux_dn(icol,1);
597  });
598  }
599  if (m_lsm_zenith) {
600  const Array4<Real>& lsm_zenith_arr = m_lsm_zenith->array(mfi);
601  ParallelFor(sbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
602  {
603  // map [i,j,k] 0-based to [icol, ilay] 1-based
604  const int icol = (j-jmin)*nx + (i-imin) + 1 + offset;
605 
606  // export cosine zenith angle for LSM
607  lsm_zenith_arr(i,j,k) = mu0(icol);
608  });
609  }
610  }
611 }
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:12
constexpr amrex::Real R_d
Definition: ERF_Constants.H:10
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenP(const amrex::Real P, const amrex::Real rdOcp)
Definition: ERF_EOS.H:144
Here is the call graph for this function:

Member Data Documentation

◆ aero_g_sw

real3d Radiation::aero_g_sw
private

◆ aero_ssa_sw

real3d Radiation::aero_ssa_sw
private

◆ aero_tau_lw

real3d Radiation::aero_tau_lw
private

◆ aero_tau_sw

real3d Radiation::aero_tau_sw
private

◆ cld_tau_lw_bnd

real3d Radiation::cld_tau_lw_bnd
private

◆ cld_tau_lw_gpt

real3d Radiation::cld_tau_lw_gpt
private

◆ cld_tau_sw_bnd

real3d Radiation::cld_tau_sw_bnd
private

◆ cld_tau_sw_gpt

real3d Radiation::cld_tau_sw_gpt
private

◆ cldfrac_tot

real2d Radiation::cldfrac_tot
private

◆ cosine_zenith

real1d Radiation::cosine_zenith
private

◆ d_tint

real2d Radiation::d_tint
private

◆ datalog_mf

amrex::MultiFab Radiation::datalog_mf
private

◆ eff_radius_qc

real2d Radiation::eff_radius_qc
private

◆ eff_radius_qi

real2d Radiation::eff_radius_qi
private

◆ emis_sfc

real2d Radiation::emis_sfc
private

Referenced by set_lsm_inputs().

◆ gas_names_yakl_offset

string1dv Radiation::gas_names_yakl_offset
private

◆ iwp

real2d Radiation::iwp
private

◆ lat

real1d Radiation::lat
private

Referenced by Run().

◆ lon

real1d Radiation::lon
private

Referenced by Run().

◆ lw_bnd_flux_dn

real3d Radiation::lw_bnd_flux_dn
private

◆ lw_bnd_flux_up

real3d Radiation::lw_bnd_flux_up
private

◆ lw_clnclrsky_flux_dn

real2d Radiation::lw_clnclrsky_flux_dn
private

◆ lw_clnclrsky_flux_up

real2d Radiation::lw_clnclrsky_flux_up
private

◆ lw_clnsky_flux_dn

real2d Radiation::lw_clnsky_flux_dn
private

◆ lw_clnsky_flux_up

real2d Radiation::lw_clnsky_flux_up
private

◆ lw_clrsky_flux_dn

real2d Radiation::lw_clrsky_flux_dn
private

◆ lw_clrsky_flux_up

real2d Radiation::lw_clrsky_flux_up
private

◆ lw_clrsky_heating

real2d Radiation::lw_clrsky_heating
private

◆ lw_flux_dn

real2d Radiation::lw_flux_dn
private

◆ lw_flux_up

real2d Radiation::lw_flux_up
private

◆ lw_heating

real2d Radiation::lw_heating
private

◆ lw_src

real1d Radiation::lw_src
private

Referenced by set_lsm_inputs().

◆ lwp

real2d Radiation::lwp
private

◆ m_ba

amrex::BoxArray Radiation::m_ba
private

◆ m_ch4vmr

amrex::Real Radiation::m_ch4vmr = 1807.851e-9
private

◆ m_co2vmr

amrex::Real Radiation::m_co2vmr = 388.717e-6
private

◆ m_col_offsets

amrex::Vector<int> Radiation::m_col_offsets
private

◆ m_cons_in

amrex::MultiFab* Radiation::m_cons_in = nullptr
private

◆ m_covmr

amrex::Real Radiation::m_covmr = 1.0e-7
private

◆ m_do_aerosol_rad

bool Radiation::m_do_aerosol_rad = true
private

◆ m_do_subcol_sampling

bool Radiation::m_do_subcol_sampling = true
private

◆ m_dt

amrex::Real Radiation::m_dt
private

◆ m_extra_clnclrsky_diag

bool Radiation::m_extra_clnclrsky_diag = false
private

◆ m_extra_clnsky_diag

bool Radiation::m_extra_clnsky_diag = false
private

◆ m_first_step

bool Radiation::m_first_step = true
private

◆ m_fixed_orbital_year

bool Radiation::m_fixed_orbital_year = false
private

◆ m_fixed_solar_zenith_angle

amrex::Real Radiation::m_fixed_solar_zenith_angle = -9999.
private

◆ m_fixed_total_solar_irradiance

amrex::Real Radiation::m_fixed_total_solar_irradiance = -9999.
private

◆ m_gas_concs

GasConcs Radiation::m_gas_concs
private

◆ m_gas_mol_weights

real1d Radiation::m_gas_mol_weights
private

◆ m_gas_names

const std::vector<std::string> Radiation::m_gas_names
private
Initial value:
= {"H2O", "CO2", "O3", "N2O",
"CO" , "CH4", "O2", "N2" }

◆ m_geom

amrex::Geometry Radiation::m_geom
private

◆ m_ice

bool Radiation::m_ice = false
private

◆ m_lat

amrex::MultiFab* Radiation::m_lat = nullptr
private

◆ m_lat_cons

amrex::Real Radiation::m_lat_cons = 39.809860
private

◆ m_lev

int Radiation::m_lev
private

Referenced by rad_run_impl().

◆ m_lon

amrex::MultiFab* Radiation::m_lon = nullptr
private

◆ m_lon_cons

amrex::Real Radiation::m_lon_cons = -98.555183
private

◆ m_lsm

bool Radiation::m_lsm = false
private

◆ m_lsm_fluxes

amrex::MultiFab* Radiation::m_lsm_fluxes = nullptr
private

◆ m_lsm_zenith

amrex::MultiFab* Radiation::m_lsm_zenith = nullptr
private

◆ m_moist

bool Radiation::m_moist = false
private

◆ m_mol_weight_gas

const std::vector<amrex::Real> Radiation::m_mol_weight_gas
private
Initial value:
= {18.01528, 44.00950, 47.9982, 44.0128,
28.01010, 16.04246, 31.9980, 28.0134}

◆ m_n2ovmr

amrex::Real Radiation::m_n2ovmr = 323.141e-9
private

◆ m_n2vmr

amrex::Real Radiation::m_n2vmr = 0.7906
private

◆ m_ncol

int Radiation::m_ncol
private

◆ m_ngas

int Radiation::m_ngas = 8
private

◆ m_nlay

int Radiation::m_nlay
private

◆ m_nlwbands

int Radiation::m_nlwbands = 16
private

◆ m_nlwgpts

int Radiation::m_nlwgpts = 128
private

◆ m_nswbands

int Radiation::m_nswbands = 14
private

◆ m_nswgpts

int Radiation::m_nswgpts = 112
private

◆ m_o2vmr

amrex::Real Radiation::m_o2vmr = 0.209448
private

◆ m_o3_size

int Radiation::m_o3_size
private

◆ m_o3vmr

amrex::Vector<amrex::Real> Radiation::m_o3vmr
private

◆ m_orbital_day

int Radiation::m_orbital_day = -9999
private

◆ m_orbital_eccen

amrex::Real Radiation::m_orbital_eccen = -9999.
private

◆ m_orbital_mon

int Radiation::m_orbital_mon = -9999
private

◆ m_orbital_mvelp

amrex::Real Radiation::m_orbital_mvelp = -9999.
private

◆ m_orbital_obliq

amrex::Real Radiation::m_orbital_obliq = -9999.
private

◆ m_orbital_sec

int Radiation::m_orbital_sec = -9999
private

◆ m_orbital_year

int Radiation::m_orbital_year = -9999
private

◆ m_qheating_rates

amrex::MultiFab* Radiation::m_qheating_rates = nullptr
private

◆ m_rad_freq_in_steps

int Radiation::m_rad_freq_in_steps = 1
private

◆ m_rad_write_fluxes

bool Radiation::m_rad_write_fluxes = false
private

◆ m_step

int Radiation::m_step
private

◆ m_time

amrex::Real Radiation::m_time
private

◆ m_update_rad

bool Radiation::m_update_rad = false
private

Referenced by rad_run_impl(), and set_lsm_inputs().

◆ m_z_phys

amrex::MultiFab* Radiation::m_z_phys = nullptr
private

◆ mu0

real1d Radiation::mu0
private

◆ o3_lay

real1d Radiation::o3_lay
private

◆ p_del

real2d Radiation::p_del
private

◆ p_lay

real2d Radiation::p_lay
private

◆ p_lev

real2d Radiation::p_lev
private

◆ qc_lay

real2d Radiation::qc_lay
private

◆ qi_lay

real2d Radiation::qi_lay
private

◆ qv_lay

real2d Radiation::qv_lay
private

◆ r_lay

real2d Radiation::r_lay
private

◆ rrtmgp_cloud_optics_file_lw

std::string Radiation::rrtmgp_cloud_optics_file_lw
private

◆ rrtmgp_cloud_optics_file_sw

std::string Radiation::rrtmgp_cloud_optics_file_sw
private

◆ rrtmgp_cloud_optics_lw

std::string Radiation::rrtmgp_cloud_optics_lw = "rrtmgp-cloud-optics-coeffs-lw.nc"
private

◆ rrtmgp_cloud_optics_sw

std::string Radiation::rrtmgp_cloud_optics_sw = "rrtmgp-cloud-optics-coeffs-sw.nc"
private

◆ rrtmgp_coeffs_file_lw

std::string Radiation::rrtmgp_coeffs_file_lw
private

◆ rrtmgp_coeffs_file_sw

std::string Radiation::rrtmgp_coeffs_file_sw
private

◆ rrtmgp_coeffs_lw

std::string Radiation::rrtmgp_coeffs_lw = "rrtmgp-data-lw-g224-2018-12-04.nc"
private

◆ rrtmgp_coeffs_sw

std::string Radiation::rrtmgp_coeffs_sw = "rrtmgp-data-sw-g224-2018-12-04.nc"
private

◆ rrtmgp_file_path

std::string Radiation::rrtmgp_file_path = "."
private

◆ sfc_alb_dif

real2d Radiation::sfc_alb_dif
private

◆ sfc_alb_dif_nir

real1d Radiation::sfc_alb_dif_nir
private

◆ sfc_alb_dif_vis

real1d Radiation::sfc_alb_dif_vis
private

◆ sfc_alb_dir

real2d Radiation::sfc_alb_dir
private

◆ sfc_alb_dir_nir

real1d Radiation::sfc_alb_dir_nir
private

◆ sfc_alb_dir_vis

real1d Radiation::sfc_alb_dir_vis
private

◆ sfc_emis

real1d Radiation::sfc_emis
private

◆ sfc_flux_dif_nir

real1d Radiation::sfc_flux_dif_nir
private

◆ sfc_flux_dif_vis

real1d Radiation::sfc_flux_dif_vis
private

◆ sfc_flux_dir_nir

real1d Radiation::sfc_flux_dir_nir
private

◆ sfc_flux_dir_vis

real1d Radiation::sfc_flux_dir_vis
private

◆ sw_bnd_flux_dif

real3d Radiation::sw_bnd_flux_dif
private

◆ sw_bnd_flux_dir

real3d Radiation::sw_bnd_flux_dir
private

◆ sw_bnd_flux_dn

real3d Radiation::sw_bnd_flux_dn
private

◆ sw_bnd_flux_up

real3d Radiation::sw_bnd_flux_up
private

◆ sw_clnclrsky_flux_dn

real2d Radiation::sw_clnclrsky_flux_dn
private

◆ sw_clnclrsky_flux_dn_dir

real2d Radiation::sw_clnclrsky_flux_dn_dir
private

◆ sw_clnclrsky_flux_up

real2d Radiation::sw_clnclrsky_flux_up
private

◆ sw_clnsky_flux_dn

real2d Radiation::sw_clnsky_flux_dn
private

◆ sw_clnsky_flux_dn_dir

real2d Radiation::sw_clnsky_flux_dn_dir
private

◆ sw_clnsky_flux_up

real2d Radiation::sw_clnsky_flux_up
private

◆ sw_clrsky_flux_dn

real2d Radiation::sw_clrsky_flux_dn
private

◆ sw_clrsky_flux_dn_dir

real2d Radiation::sw_clrsky_flux_dn_dir
private

◆ sw_clrsky_flux_up

real2d Radiation::sw_clrsky_flux_up
private

◆ sw_clrsky_heating

real2d Radiation::sw_clrsky_heating
private

◆ sw_flux_dn

real2d Radiation::sw_flux_dn
private

◆ sw_flux_dn_dir

real2d Radiation::sw_flux_dn_dir
private

◆ sw_flux_up

real2d Radiation::sw_flux_up
private

◆ sw_heating

real2d Radiation::sw_heating
private

◆ t_lay

real2d Radiation::t_lay
private

◆ t_lev

real2d Radiation::t_lev
private

◆ t_sfc

real1d Radiation::t_sfc
private

◆ tmp2d

real2d Radiation::tmp2d
private

◆ z_del

real2d Radiation::z_del
private

The documentation for this class was generated from the following files: