ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
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 ()
 
virtual void Init (const amrex::Geometry &geom, const amrex::BoxArray &ba, amrex::MultiFab *cons_in) override
 
virtual void Run (int &level, int &step, double &time, const double &dt, const amrex::BoxArray &ba, amrex::Geometry &geom, amrex::MultiFab *cons_in, amrex::iMultiFab *lmask, amrex::MultiFab *t_surf, amrex::Vector< amrex::MultiFab * > &lsm_input_ptrs, amrex::Vector< amrex::MultiFab * > &lsm_output_ptrs, amrex::MultiFab *qheating_rates, amrex::MultiFab *rad_fluxes, amrex::MultiFab *z_phys, amrex::MultiFab *lat_ptr, amrex::MultiFab *lon_ptr, const bool updated_lsm) override
 
void set_grids (int &level, int &step, double &time, const double &dt, const amrex::BoxArray &ba, amrex::Geometry &geom, amrex::MultiFab *cons_in, amrex::iMultiFab *lmask, amrex::MultiFab *t_surf, amrex::Vector< amrex::MultiFab * > &lsm_input_ptrs, amrex::MultiFab *qheating_rates, amrex::MultiFab *rad_fluxes, amrex::MultiFab *z_phys, amrex::MultiFab *lat, amrex::MultiFab *lon, const bool updated_lsm)
 
void alloc_buffers ()
 
void dealloc_buffers ()
 
void mf_to_kokkos_buffers (amrex::iMultiFab *lmask, amrex::MultiFab *t_surf, amrex::Vector< amrex::MultiFab * > &lsm_input_ptrs)
 
void kokkos_buffers_to_mf (amrex::Vector< amrex::MultiFab * > &lsm_output_ptrs)
 
void write_rrtmgp_fluxes ()
 
void initialize_impl ()
 
void run_impl ()
 
void finalize_impl (amrex::Vector< amrex::MultiFab * > &lsm_output_ptrs)
 
void rad_run_impl (amrex::Vector< amrex::MultiFab * > &lsm_output_ptrs)
 
virtual amrex::Vector< std::string > get_lsm_input_varnames () override
 
virtual amrex::Vector< std::string > get_lsm_output_varnames () override
 
void populateDatalogMF ()
 
virtual void WriteDataLog (const double &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
 
double m_time
 
double 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::Vector< std::string > m_lsm_input_names
 
amrex::Vector< std::string > m_lsm_output_names
 
amrex::Real m_rad_t_sfc = -1
 
amrex::MultiFab * m_cons_in = nullptr
 
amrex::MultiFab * m_qheating_rates = nullptr
 
amrex::MultiFab * m_rad_fluxes = nullptr
 
amrex::MultiFab * m_z_phys = nullptr
 
amrex::MultiFab * m_lat = nullptr
 
amrex::MultiFab * m_lon = nullptr
 
amrex::Real m_lat_cons = amrex::Real(39.809860)
 
amrex::Real m_lon_cons = -amrex::Real(98.555183)
 
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-g256-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::Realm_mol_weight_gas
 
amrex::Real m_co2vmr = amrex::Real(388.717e-6)
 
amrex::Vector< amrex::Realm_o3vmr
 
amrex::Real m_n2ovmr = amrex::Real(323.141e-9)
 
amrex::Real m_covmr = amrex::Real(1.0e-7)
 
amrex::Real m_ch4vmr = amrex::Real(1807.851e-9)
 
amrex::Real m_o2vmr = amrex::Real(0.209448)
 
amrex::Real m_n2vmr = amrex::Real(0.7906)
 
int m_o3_size
 
real1d_k m_gas_mol_weights
 
std::vector< std::string > gas_names_offset
 
GasConcsK< amrex::Real, layout_t, KokkosDefaultDevicem_gas_concs
 
int m_ncol
 
int m_nlay
 
amrex::Vector< int > m_col_offsets
 
bool m_do_aerosol_rad = false
 
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 = -amrex::Real(9999.)
 
amrex::Real m_orbital_obliq = -amrex::Real(9999.)
 
amrex::Real m_orbital_mvelp = -amrex::Real(9999.)
 
amrex::Real m_fixed_total_solar_irradiance = -amrex::Real(9999.)
 
amrex::Real m_fixed_solar_zenith_angle = -amrex::Real(9999.)
 
int m_nswbands
 
int m_nlwbands
 
int m_nswgpts
 
int m_nlwgpts
 
int m_rad_freq_in_steps = 1
 
int m_ncol_chunk = 1024
 
int m_rad_nvar = 12
 
bool m_do_subcol_sampling = true
 
real1d_k o3_lay
 
real1d_k mu0
 
real1d_k sfc_alb_dir_vis
 
real1d_k sfc_alb_dir_nir
 
real1d_k sfc_alb_dif_vis
 
real1d_k sfc_alb_dif_nir
 
real1d_k sfc_flux_dir_vis
 
real1d_k sfc_flux_dir_nir
 
real1d_k sfc_flux_dif_vis
 
real1d_k sfc_flux_dif_nir
 
real1d_k lat
 
real1d_k lon
 
real1d_k sfc_emis
 
real1d_k t_sfc
 
real1d_k lw_src
 
real2d_k r_lay
 
real2d_k p_lay
 
real2d_k t_lay
 
real2d_k z_del
 
real2d_k qv_lay
 
real2d_k qc_lay
 
real2d_k qi_lay
 
real2d_k cldfrac_tot
 
real2d_k eff_radius_qc
 
real2d_k eff_radius_qi
 
real2d_k lwp
 
real2d_k iwp
 
real2d_k sw_heating
 
real2d_k lw_heating
 
real2d_k sw_clrsky_heating
 
real2d_k lw_clrsky_heating
 
real2d_k d_tint
 
real2d_k p_lev
 
real2d_k t_lev
 
real2d_k sw_flux_up
 
real2d_k sw_flux_dn
 
real2d_k sw_flux_dn_dir
 
real2d_k lw_flux_up
 
real2d_k lw_flux_dn
 
real2d_k sw_clnclrsky_flux_up
 
real2d_k sw_clnclrsky_flux_dn
 
real2d_k sw_clnclrsky_flux_dn_dir
 
real2d_k sw_clrsky_flux_up
 
real2d_k sw_clrsky_flux_dn
 
real2d_k sw_clrsky_flux_dn_dir
 
real2d_k sw_clnsky_flux_up
 
real2d_k sw_clnsky_flux_dn
 
real2d_k sw_clnsky_flux_dn_dir
 
real2d_k lw_clnclrsky_flux_up
 
real2d_k lw_clnclrsky_flux_dn
 
real2d_k lw_clrsky_flux_up
 
real2d_k lw_clrsky_flux_dn
 
real2d_k lw_clnsky_flux_up
 
real2d_k lw_clnsky_flux_dn
 
real3d_k sw_bnd_flux_up
 
real3d_k sw_bnd_flux_dn
 
real3d_k sw_bnd_flux_dir
 
real3d_k sw_bnd_flux_dif
 
real3d_k lw_bnd_flux_up
 
real3d_k lw_bnd_flux_dn
 
real2d_k sfc_alb_dir
 
real2d_k sfc_alb_dif
 
real3d_k aero_tau_sw
 
real3d_k aero_ssa_sw
 
real3d_k aero_g_sw
 
real3d_k aero_tau_lw
 

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 
)
22 {
23  // Note that Kokkos is now initialized in main.cpp
24 
25  // Check if we have a valid moisture model
26  if (sc.moisture_type != MoistureType::None) { m_moist = true; }
27 
28  // Check if we have a moisture model with ice
29  if (sc.moisture_type == MoistureType::SAM) { m_ice = true; }
30 
31  // Check if we have a land surface model enabled
32  if (sc.lsm_type != LandSurfaceType::None) { m_lsm = true; }
33 
34  // Construct parser object for following reads
35  ParmParse pp("erf");
36 
37  // Must specify a surface temp (LSM can overwrite)
38  pp.get("rad_t_sfc", m_rad_t_sfc);
39 
40  // Radiation timestep, as a number of atm steps
41  pp.query("rad_freq_in_steps", m_rad_freq_in_steps);
42 
43  // Get nvar if specified
44  pp.query("rad_nvar", m_rad_nvar);
45  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_rad_nvar >= 0,
46  "erf.rad_nvar must be greater than 0. "
47  "It controls the amount of memory allocated for temporaries with RRTMGP; "
48  "a value of 0 would allocate no memory.");
49 
50  // Number of columns per RRTMGP chunk (controls peak GPU memory)
51  pp.query("rad_ncol_chunk", m_ncol_chunk);
52  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_ncol_chunk > 0,
53  "erf.rad_ncol_chunk must be a positive integer (default 5000). "
54  "It controls the number of columns processed per RRTMGP kernel launch; "
55  "a value of 0 or negative would produce an infinite loop.");
56 
57  // Flag to write fluxes to plt file
58  pp.query("rad_write_fluxes", m_rad_write_fluxes);
59 
60  // Do MCICA subcolumn sampling
61  pp.query("rad_do_subcol_sampling", m_do_subcol_sampling);
62 
63  // Determine orbital year. If orbital_year is negative, use current year
64  // from timestamp for orbital year; if positive, use provided orbital year
65  // for duration of simulation.
66  m_fixed_orbital_year = pp.query("rad_orbital_year", m_orbital_year);
67 
68  // Get orbital parameters from inputs file
69  pp.query("rad_orbital_eccentricity", m_orbital_eccen);
70  pp.query("rad_orbital_obliquity" , m_orbital_obliq);
71  pp.query("rad_orbital_mvelp" , m_orbital_mvelp);
72 
73  // Get a constant lat/lon for idealized simulations
74  pp.query("rad_cons_lat", m_lat_cons);
75  pp.query("rad_cons_lon", m_lon_cons);
76 
77  // Value for prescribing an invariant solar constant (i.e. total solar irradiance at
78  // TOA). Used for idealized experiments such as RCE. Disabled when value is less than zero
79  pp.query("fixed_total_solar_irradiance", m_fixed_total_solar_irradiance);
80 
81  // Determine whether or not we are using a fixed solar zenith angle (positive value)
82  pp.query("fixed_solar_zenith_angle", m_fixed_solar_zenith_angle);
83 
84  // Get prescribed surface values of greenhouse gases
85  pp.query("co2vmr", m_co2vmr);
86  pp.queryarr("o3vmr" , m_o3vmr );
87  pp.query("n2ovmr", m_n2ovmr);
88  pp.query("covmr" , m_covmr );
89  pp.query("ch4vmr", m_ch4vmr);
90  pp.query("o2vmr" , m_o2vmr );
91  pp.query("n2vmr" , m_n2vmr );
92 
93  // Aerosol forcing hook (not implemented). The aerosol arrays that used to be
94  // passed through rrtmgp_main were never populated with real data, so enabling
95  // this flag only ever multiplied radiation by zero aerosol optics. The hook is
96  // kept so a future SPA/prescribed-aerosol scheme can wire in without touching
97  // the ParmParse surface.
98  pp.query("rad_do_aerosol", m_do_aerosol_rad);
99  if (m_do_aerosol_rad) {
100  amrex::Abort("erf.rad_do_aerosol = true is not supported: aerosol forcing is "
101  "currently not implemented in the ERF RRTMGP interface. The hook "
102  "is retained for a future aerosol coupling; set rad_do_aerosol = "
103  "false (or remove it) to continue.");
104  }
105 
106  // Whether we do extra clean/clear sky calculations
107  pp.query("rad_extra_clnclrsky_diag", m_extra_clnclrsky_diag);
108  pp.query("rad_extra_clnsky_diag" , m_extra_clnsky_diag);
109 
110  // Parse path and file names
111  pp.query("rrtmgp_file_path" , rrtmgp_file_path);
112  pp.query("rrtmgp_coeffs_sw" , rrtmgp_coeffs_sw );
113  pp.query("rrtmgp_coeffs_lw" , rrtmgp_coeffs_lw );
114  pp.query("rrtmgp_cloud_optics_sw", rrtmgp_cloud_optics_sw);
115  pp.query("rrtmgp_cloud_optics_lw", rrtmgp_cloud_optics_lw);
116 
117  // Append file names to path
122 
123  // Get dimensions from lookup data
124  if (ParallelDescriptor::IOProcessor()) {
125  auto ncf_sw = ncutils::NCFile::open(rrtmgp_coeffs_file_sw, NC_CLOBBER | NC_NETCDF4);
126  m_nswbands = ncf_sw.dim("bnd").len();
127  m_nswgpts = ncf_sw.dim("gpt").len();
128  ncf_sw.close();
129 
130  auto ncf_lw = ncutils::NCFile::open(rrtmgp_coeffs_file_lw, NC_CLOBBER | NC_NETCDF4);
131  m_nlwbands = ncf_lw.dim("bnd").len();
132  m_nlwgpts = ncf_lw.dim("gpt").len();
133  ncf_lw.close();
134  }
135  int ioproc = ParallelDescriptor::IOProcessorNumber(); // I/O rank
136  ParallelDescriptor::Bcast(&m_nswbands, 1, ioproc);
137  ParallelDescriptor::Bcast(&m_nlwbands, 1, ioproc);
138  ParallelDescriptor::Bcast(&m_nswgpts, 1, ioproc);
139  ParallelDescriptor::Bcast(&m_nlwgpts, 1, ioproc);
140 
141  // Output for user
142  if (lev == 0) {
143  Print() << "Radiation interface constructed:\n";
144  Print() << "========================================================\n";
145  Print() << "Coeff SW file: " << rrtmgp_coeffs_file_sw << "\n";
146  Print() << "Coeff LW file: " << rrtmgp_coeffs_file_lw << "\n";
147  Print() << "Cloud SW file: " << rrtmgp_cloud_optics_file_sw << "\n";
148  Print() << "Cloud LW file: " << rrtmgp_cloud_optics_file_lw << "\n";
149  Print() << "Number of short/longwave bands: "
150  << m_nswbands << " " << m_nlwbands << "\n";
151  Print() << "Number of short/longwave gauss points: "
152  << m_nswgpts << " " << m_nlwgpts << "\n";
153  Print() << "========================================================\n";
154  }
155 }
ParmParse pp("prob")
std::string rrtmgp_coeffs_file_sw
Definition: ERF_Radiation.H:295
std::string rrtmgp_coeffs_sw
Definition: ERF_Radiation.H:291
int m_rad_freq_in_steps
Definition: ERF_Radiation.H:376
amrex::Real m_lon_cons
Definition: ERF_Radiation.H:284
int m_nswbands
Definition: ERF_Radiation.H:370
bool m_do_aerosol_rad
Definition: ERF_Radiation.H:338
std::string rrtmgp_coeffs_lw
Definition: ERF_Radiation.H:292
bool m_moist
Definition: ERF_Radiation.H:246
std::string rrtmgp_cloud_optics_file_lw
Definition: ERF_Radiation.H:298
bool m_lsm
Definition: ERF_Radiation.H:250
bool m_do_subcol_sampling
Definition: ERF_Radiation.H:385
bool m_rad_write_fluxes
Definition: ERF_Radiation.H:241
std::string rrtmgp_cloud_optics_file_sw
Definition: ERF_Radiation.H:297
amrex::Real m_orbital_mvelp
Definition: ERF_Radiation.H:358
amrex::Vector< amrex::Real > m_o3vmr
Definition: ERF_Radiation.H:309
std::string rrtmgp_cloud_optics_sw
Definition: ERF_Radiation.H:293
int m_nlwgpts
Definition: ERF_Radiation.H:373
std::string rrtmgp_cloud_optics_lw
Definition: ERF_Radiation.H:294
amrex::Real m_co2vmr
Definition: ERF_Radiation.H:308
bool m_extra_clnsky_diag
Definition: ERF_Radiation.H:341
amrex::Real m_lat_cons
Definition: ERF_Radiation.H:283
amrex::Real m_fixed_total_solar_irradiance
Definition: ERF_Radiation.H:363
amrex::Real m_o2vmr
Definition: ERF_Radiation.H:313
amrex::Real m_n2ovmr
Definition: ERF_Radiation.H:310
amrex::Real m_rad_t_sfc
Definition: ERF_Radiation.H:264
std::string rrtmgp_file_path
Definition: ERF_Radiation.H:290
int m_nlwbands
Definition: ERF_Radiation.H:371
amrex::Real m_orbital_eccen
Definition: ERF_Radiation.H:356
amrex::Real m_covmr
Definition: ERF_Radiation.H:311
int m_ncol_chunk
Definition: ERF_Radiation.H:379
std::string rrtmgp_coeffs_file_lw
Definition: ERF_Radiation.H:296
amrex::Real m_ch4vmr
Definition: ERF_Radiation.H:312
bool m_ice
Definition: ERF_Radiation.H:247
amrex::Real m_fixed_solar_zenith_angle
Definition: ERF_Radiation.H:367
amrex::Real m_orbital_obliq
Definition: ERF_Radiation.H:357
amrex::Real m_n2vmr
Definition: ERF_Radiation.H:314
bool m_fixed_orbital_year
Definition: ERF_Radiation.H:355
int m_nswgpts
Definition: ERF_Radiation.H:372
bool m_extra_clnclrsky_diag
Definition: ERF_Radiation.H:342
int m_rad_nvar
Definition: ERF_Radiation.H:382
int m_orbital_year
Definition: ERF_Radiation.H:347
LandSurfaceType lsm_type
Definition: ERF_DataStruct.H:1427
MoistureType moisture_type
Definition: ERF_DataStruct.H:1424
Here is the call graph for this function:

◆ ~Radiation()

Radiation::~Radiation ( )
inline
56  {
57  // Release k-distribution data and memory pool
58  if (rrtmgp::initialized) {
60  }
61  // Note that Kokkos is now finalized in main.cpp
62  }
void rrtmgp_finalize()
Definition: ERF_RRTMGP_Interface.cpp:266
bool initialized
Definition: ERF_RRTMGP_Interface.cpp:24
Here is the call graph for this function:

Member Function Documentation

◆ alloc_buffers()

void Radiation::alloc_buffers ( )
229 {
230  // 1d size (m_ngas)
231  const Real* mol_weight_gas_p = m_mol_weight_gas.data();
232  const std::string* gas_names_p = m_gas_names.data();
233  m_gas_mol_weights = real1d_k("m_gas_mol_weights", m_ngas);
234  realHost1d_k m_gas_mol_weights_h("m_gas_mol_weights_h", m_ngas);
235  gas_names_offset.clear(); gas_names_offset.resize(m_ngas);
236  std::string* gas_names_offset_p = gas_names_offset.data();
237  Kokkos::parallel_for(Kokkos::RangePolicy<Kokkos::Serial>(0, m_ngas),
238  [&] (int igas)
239  {
240  m_gas_mol_weights_h(igas) = mol_weight_gas_p[igas];
241  gas_names_offset_p[igas] = gas_names_p[igas];
242  });
243  Kokkos::deep_copy(m_gas_mol_weights, m_gas_mol_weights_h);
244 
245  // 1d size (1 or nlay)
246  m_o3_size = m_o3vmr.size();
247  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(((m_o3_size==1) || (m_o3_size==m_nlay)),
248  "O3 VMR array must be length 1 or nlay");
249  Real* o3vmr_p = m_o3vmr.data();
250  o3_lay = real1d_k("o3_lay", m_o3_size);
251  realHost1d_k o3_lay_h("o3_lay_h", m_o3_size);
252  Kokkos::parallel_for(Kokkos::RangePolicy<Kokkos::Serial>(0, m_o3_size),
253  [&] (int io3)
254  {
255  o3_lay_h(io3) = o3vmr_p[io3];
256  });
257  Kokkos::deep_copy(o3_lay, o3_lay_h);
258 
259  // 1d size (ncol)
260  mu0 = real1d_k("mu0" , m_ncol);
261  sfc_alb_dir_vis = real1d_k("sfc_alb_dir_vis" , m_ncol);
262  sfc_alb_dir_nir = real1d_k("sfc_alb_dir_nir" , m_ncol);
263  sfc_alb_dif_vis = real1d_k("sfc_alb_dif_vis" , m_ncol);
264  sfc_alb_dif_nir = real1d_k("sfc_alb_dif_nir" , m_ncol);
265  sfc_flux_dir_vis = real1d_k("sfc_flux_dir_vis", m_ncol);
266  sfc_flux_dir_nir = real1d_k("sfc_flux_dir_nir", m_ncol);
267  sfc_flux_dif_vis = real1d_k("sfc_flux_dif_vis", m_ncol);
268  sfc_flux_dif_nir = real1d_k("sfc_flux_dif_nir", m_ncol);
269  lat = real1d_k("lat" , m_ncol);
270  lon = real1d_k("lon" , m_ncol);
271  sfc_emis = real1d_k("sfc_emis" , m_ncol);
272  t_sfc = real1d_k("t_sfc" , m_ncol);
273  lw_src = real1d_k("lw_src" , m_ncol);
274 
275  // 2d size (ncol, nlay)
276  r_lay = real2d_k("r_lay" , m_ncol, m_nlay);
277  p_lay = real2d_k("p_lay" , m_ncol, m_nlay);
278  t_lay = real2d_k("t_lay" , m_ncol, m_nlay);
279  z_del = real2d_k("z_del" , m_ncol, m_nlay);
280  qv_lay = real2d_k("qv" , m_ncol, m_nlay);
281  qc_lay = real2d_k("qc" , m_ncol, m_nlay);
282  qi_lay = real2d_k("qi" , m_ncol, m_nlay);
283  cldfrac_tot = real2d_k("cldfrac_tot" , m_ncol, m_nlay);
284  eff_radius_qc = real2d_k("eff_radius_qc", m_ncol, m_nlay);
285  eff_radius_qi = real2d_k("eff_radius_qi", m_ncol, m_nlay);
286  lwp = real2d_k("lwp" , m_ncol, m_nlay);
287  iwp = real2d_k("iwp" , m_ncol, m_nlay);
288  sw_heating = real2d_k("sw_heating" , m_ncol, m_nlay);
289  lw_heating = real2d_k("lw_heating" , m_ncol, m_nlay);
290  if (datalog_int > 0) {
291  sw_clrsky_heating = real2d_k("sw_clrsky_heating", m_ncol, m_nlay);
292  lw_clrsky_heating = real2d_k("lw_clrsky_heating", m_ncol, m_nlay);
293  }
294 
295  // 2d size (ncol, nlay+1)
296  d_tint = real2d_k("d_tint" , m_ncol, m_nlay+1);
297  p_lev = real2d_k("p_lev" , m_ncol, m_nlay+1);
298  t_lev = real2d_k("t_lev" , m_ncol, m_nlay+1);
299 
300  sw_flux_up = real2d_k("sw_flux_up" , m_ncol, m_nlay+1);
301  sw_flux_dn = real2d_k("sw_flux_dn" , m_ncol, m_nlay+1);
302  sw_flux_dn_dir = real2d_k("sw_flux_dn_dir" , m_ncol, m_nlay+1);
303 
304  lw_flux_up = real2d_k("lw_flux_up" , m_ncol, m_nlay+1);
305  lw_flux_dn = real2d_k("lw_flux_dn" , m_ncol, m_nlay+1);
306 
307  // Clear-sky flux arrays are always needed
308  if (datalog_int > 0) {
309  sw_clrsky_flux_up = real2d_k("sw_clrsky_flux_up" , m_ncol, m_nlay+1);
310  sw_clrsky_flux_dn = real2d_k("sw_clrsky_flux_dn" , m_ncol, m_nlay+1);
311  sw_clrsky_flux_dn_dir = real2d_k("sw_clrsky_flux_dn_dir", m_ncol, m_nlay+1);
312  lw_clrsky_flux_up = real2d_k("lw_clrsky_flux_up" , m_ncol, m_nlay+1);
313  lw_clrsky_flux_dn = real2d_k("lw_clrsky_flux_dn" , m_ncol, m_nlay+1);
314  } else {
315  sw_clrsky_flux_up = real2d_k("sw_clrsky_flux_up" , m_ncol_chunk, m_nlay+1);
316  sw_clrsky_flux_dn = real2d_k("sw_clrsky_flux_dn" , m_ncol_chunk, m_nlay+1);
317  sw_clrsky_flux_dn_dir = real2d_k("sw_clrsky_flux_dn_dir", m_ncol_chunk, m_nlay+1);
318  lw_clrsky_flux_up = real2d_k("lw_clrsky_flux_up" , m_ncol_chunk, m_nlay+1);
319  lw_clrsky_flux_dn = real2d_k("lw_clrsky_flux_dn" , m_ncol_chunk, m_nlay+1);
320  }
321 
322  // Clean-clear-sky diagnostic fluxes (only when enabled)
324  sw_clnclrsky_flux_up = real2d_k("sw_clnclrsky_flux_up" , m_ncol, m_nlay+1);
325  sw_clnclrsky_flux_dn = real2d_k("sw_clnclrsky_flux_dn" , m_ncol, m_nlay+1);
326  sw_clnclrsky_flux_dn_dir = real2d_k("sw_clnclrsky_flux_dn_dir", m_ncol, m_nlay+1);
327  lw_clnclrsky_flux_up = real2d_k("lw_clnclrsky_flux_up" , m_ncol, m_nlay+1);
328  lw_clnclrsky_flux_dn = real2d_k("lw_clnclrsky_flux_dn" , m_ncol, m_nlay+1);
329  } else {
330  sw_clnclrsky_flux_up = real2d_k("sw_clnclrsky_flux_up" , 1, 1);
331  sw_clnclrsky_flux_dn = real2d_k("sw_clnclrsky_flux_dn" , 1, 1);
332  sw_clnclrsky_flux_dn_dir = real2d_k("sw_clnclrsky_flux_dn_dir", 1, 1);
333  lw_clnclrsky_flux_up = real2d_k("lw_clnclrsky_flux_up" , 1, 1);
334  lw_clnclrsky_flux_dn = real2d_k("lw_clnclrsky_flux_dn" , 1, 1);
335  }
336 
337  // Clean-sky diagnostic fluxes (only when enabled)
338  if (m_extra_clnsky_diag) {
339  sw_clnsky_flux_up = real2d_k("sw_clnsky_flux_up" , m_ncol, m_nlay+1);
340  sw_clnsky_flux_dn = real2d_k("sw_clnsky_flux_dn" , m_ncol, m_nlay+1);
341  sw_clnsky_flux_dn_dir = real2d_k("sw_clnsky_flux_dn_dir" , m_ncol, m_nlay+1);
342  lw_clnsky_flux_up = real2d_k("lw_clnsky_flux_up" , m_ncol, m_nlay+1);
343  lw_clnsky_flux_dn = real2d_k("lw_clnsky_flux_dn" , m_ncol, m_nlay+1);
344  } else {
345  sw_clnsky_flux_up = real2d_k("sw_clnsky_flux_up" , 1, 1);
346  sw_clnsky_flux_dn = real2d_k("sw_clnsky_flux_dn" , 1, 1);
347  sw_clnsky_flux_dn_dir = real2d_k("sw_clnsky_flux_dn_dir" , 1, 1);
348  lw_clnsky_flux_up = real2d_k("lw_clnsky_flux_up" , 1, 1);
349  lw_clnsky_flux_dn = real2d_k("lw_clnsky_flux_dn" , 1, 1);
350  }
351 
352  // 3d size (ncol_chunk, nlay+1, nswbands)
353  sw_bnd_flux_up = real3d_k("sw_bnd_flux_up" , m_ncol_chunk, m_nlay+1, m_nswbands);
354  sw_bnd_flux_dn = real3d_k("sw_bnd_flux_dn" , m_ncol_chunk, m_nlay+1, m_nswbands);
355  sw_bnd_flux_dir = real3d_k("sw_bnd_flux_dir", m_ncol_chunk, m_nlay+1, m_nswbands);
356  sw_bnd_flux_dif = real3d_k("sw_bnd_flux_dif", m_ncol_chunk, m_nlay+1, m_nswbands);
357 
358  // 3d size (ncol_chunk, nlay+1, nlwbands)
359  lw_bnd_flux_up = real3d_k("lw_bnd_flux_up" , m_ncol_chunk, m_nlay+1, m_nlwbands);
360  lw_bnd_flux_dn = real3d_k("lw_bnd_flux_dn" , m_ncol_chunk, m_nlay+1, m_nlwbands);
361 
362  // 2d size (ncol, nswbands)
363  sfc_alb_dir = real2d_k("sfc_alb_dir", m_ncol, m_nswbands);
364  sfc_alb_dif = real2d_k("sfc_alb_dif", m_ncol, m_nswbands);
365 
366  // Aerosol optical properties — allocated only when aerosol coupling is on.
367  // The flag gates allocation so today (coupling not implemented, abort fires
368  // in the constructor) these stay as empty Views and cost nothing. When a
369  // future aerosol scheme populates them, hook up the plumbing into
370  // rrtmgp_main as well.
371  if (m_do_aerosol_rad) {
372  aero_tau_sw = real3d_k("aero_tau_sw", m_ncol, m_nlay, m_nswbands);
373  aero_ssa_sw = real3d_k("aero_ssa_sw", m_ncol, m_nlay, m_nswbands);
374  aero_g_sw = real3d_k("aero_g_sw", m_ncol, m_nlay, m_nswbands);
375  aero_tau_lw = real3d_k("aero_tau_lw", m_ncol, m_nlay, m_nlwbands);
376  }
377 }
Kokkos::View< RealT *, KokkosDefaultDevice > real1d_k
Definition: ERF_Kokkos.H:18
Kokkos::View< RealT ***, layout_t, KokkosDefaultDevice > real3d_k
Definition: ERF_Kokkos.H:20
Kokkos::View< RealT **, layout_t, KokkosDefaultDevice > real2d_k
Definition: ERF_Kokkos.H:19
Kokkos::View< RealT *, KokkosHostDevice > realHost1d_k
Definition: ERF_Kokkos.H:16
amrex::Real Real
Definition: ERF_ShocInterface.H:19
int datalog_int
Definition: ERF_RadiationInterface.H:89
real3d_k sw_bnd_flux_dn
Definition: ERF_Radiation.H:451
real2d_k lw_flux_up
Definition: ERF_Radiation.H:431
real3d_k aero_tau_sw
Definition: ERF_Radiation.H:470
int m_o3_size
Definition: ERF_Radiation.H:318
real3d_k sw_bnd_flux_dir
Definition: ERF_Radiation.H:452
real2d_k sw_clnsky_flux_dn
Definition: ERF_Radiation.H:440
real2d_k d_tint
Definition: ERF_Radiation.H:425
real2d_k lw_clnclrsky_flux_dn
Definition: ERF_Radiation.H:443
real2d_k lwp
Definition: ERF_Radiation.H:417
real1d_k lw_src
Definition: ERF_Radiation.H:404
real2d_k eff_radius_qi
Definition: ERF_Radiation.H:416
real1d_k m_gas_mol_weights
Definition: ERF_Radiation.H:319
real2d_k sw_heating
Definition: ERF_Radiation.H:419
real3d_k lw_bnd_flux_dn
Definition: ERF_Radiation.H:457
real3d_k sw_bnd_flux_up
Definition: ERF_Radiation.H:450
real2d_k qv_lay
Definition: ERF_Radiation.H:411
real2d_k sw_clnclrsky_flux_dn_dir
Definition: ERF_Radiation.H:435
real1d_k sfc_flux_dif_vis
Definition: ERF_Radiation.H:398
real2d_k lw_clnclrsky_flux_up
Definition: ERF_Radiation.H:442
real1d_k lat
Definition: ERF_Radiation.H:400
real2d_k qi_lay
Definition: ERF_Radiation.H:413
real2d_k sw_clrsky_flux_up
Definition: ERF_Radiation.H:436
real2d_k t_lev
Definition: ERF_Radiation.H:427
real1d_k o3_lay
Definition: ERF_Radiation.H:388
real1d_k sfc_alb_dif_vis
Definition: ERF_Radiation.H:394
real1d_k mu0
Definition: ERF_Radiation.H:391
real2d_k cldfrac_tot
Definition: ERF_Radiation.H:414
real1d_k sfc_flux_dir_nir
Definition: ERF_Radiation.H:397
real2d_k sw_clnclrsky_flux_up
Definition: ERF_Radiation.H:433
real3d_k aero_g_sw
Definition: ERF_Radiation.H:472
real2d_k sw_flux_up
Definition: ERF_Radiation.H:428
real3d_k sw_bnd_flux_dif
Definition: ERF_Radiation.H:453
real2d_k sfc_alb_dif
Definition: ERF_Radiation.H:461
real1d_k sfc_alb_dif_nir
Definition: ERF_Radiation.H:395
real2d_k lw_clnsky_flux_dn
Definition: ERF_Radiation.H:447
real2d_k p_lay
Definition: ERF_Radiation.H:408
real2d_k r_lay
Definition: ERF_Radiation.H:407
int m_ncol
Definition: ERF_Radiation.H:328
real2d_k sw_flux_dn_dir
Definition: ERF_Radiation.H:430
const std::vector< amrex::Real > m_mol_weight_gas
Definition: ERF_Radiation.H:304
std::vector< std::string > gas_names_offset
Definition: ERF_Radiation.H:320
real2d_k sw_clrsky_flux_dn
Definition: ERF_Radiation.H:437
real3d_k aero_ssa_sw
Definition: ERF_Radiation.H:471
real2d_k sw_clnsky_flux_dn_dir
Definition: ERF_Radiation.H:441
real2d_k qc_lay
Definition: ERF_Radiation.H:412
real2d_k lw_clrsky_flux_up
Definition: ERF_Radiation.H:444
real2d_k sw_flux_dn
Definition: ERF_Radiation.H:429
real2d_k lw_clrsky_flux_dn
Definition: ERF_Radiation.H:445
real2d_k z_del
Definition: ERF_Radiation.H:410
real3d_k aero_tau_lw
Definition: ERF_Radiation.H:473
real2d_k lw_flux_dn
Definition: ERF_Radiation.H:432
real2d_k sw_clrsky_flux_dn_dir
Definition: ERF_Radiation.H:438
real1d_k sfc_flux_dif_nir
Definition: ERF_Radiation.H:399
int m_ngas
Definition: ERF_Radiation.H:301
real2d_k lw_heating
Definition: ERF_Radiation.H:420
real1d_k sfc_alb_dir_nir
Definition: ERF_Radiation.H:393
real2d_k lw_clnsky_flux_up
Definition: ERF_Radiation.H:446
real2d_k sfc_alb_dir
Definition: ERF_Radiation.H:460
real1d_k lon
Definition: ERF_Radiation.H:401
real1d_k sfc_emis
Definition: ERF_Radiation.H:402
real2d_k sw_clnsky_flux_up
Definition: ERF_Radiation.H:439
int m_nlay
Definition: ERF_Radiation.H:329
real3d_k lw_bnd_flux_up
Definition: ERF_Radiation.H:456
real1d_k sfc_alb_dir_vis
Definition: ERF_Radiation.H:392
const std::vector< std::string > m_gas_names
Definition: ERF_Radiation.H:302
real2d_k sw_clrsky_heating
Definition: ERF_Radiation.H:421
real2d_k t_lay
Definition: ERF_Radiation.H:409
real1d_k sfc_flux_dir_vis
Definition: ERF_Radiation.H:396
real2d_k iwp
Definition: ERF_Radiation.H:418
real2d_k p_lev
Definition: ERF_Radiation.H:426
real2d_k lw_clrsky_heating
Definition: ERF_Radiation.H:422
real2d_k eff_radius_qc
Definition: ERF_Radiation.H:415
real1d_k t_sfc
Definition: ERF_Radiation.H:403
real2d_k sw_clnclrsky_flux_dn
Definition: ERF_Radiation.H:434

◆ dealloc_buffers()

void Radiation::dealloc_buffers ( )
381 {
382  // 1d size (m_ngas)
384 
385  // 1d size (1 or nlay)
386  o3_lay = real1d_k();
387 
388  // 1d size (ncol)
389  mu0 = real1d_k();
398  lat = real1d_k();
399  lon = real1d_k();
400  sfc_emis = real1d_k();
401  t_sfc = real1d_k();
402  lw_src = real1d_k();
403 
404  // 2d size (ncol, nlay)
405  r_lay = real2d_k();
406  p_lay = real2d_k();
407  t_lay = real2d_k();
408  z_del = real2d_k();
409  qv_lay = real2d_k();
410  qc_lay = real2d_k();
411  qi_lay = real2d_k();
412  cldfrac_tot = real2d_k();
415  lwp = real2d_k();
416  iwp = real2d_k();
417  sw_heating = real2d_k();
418  lw_heating = real2d_k();
421 
422  // 2d size (ncol, nlay+1)
423  d_tint = real2d_k();
424  p_lev = real2d_k();
425  t_lev = real2d_k();
426  sw_flux_up = real2d_k();
427  sw_flux_dn = real2d_k();
429  lw_flux_up = real2d_k();
430  lw_flux_dn = real2d_k();
446 
447  // 3d size (ncol, nlay+1, nswbands)
452 
453  // 3d size (ncol, nlay+1, nlwbands)
456 
457  // 2d size (ncol, nswbands)
458  sfc_alb_dir = real2d_k();
459  sfc_alb_dif = real2d_k();
460 
461  // Aerosol scaffolding (no-op unless m_do_aerosol_rad enabled allocation above)
462  aero_tau_sw = real3d_k();
463  aero_ssa_sw = real3d_k();
464  aero_g_sw = real3d_k();
465  aero_tau_lw = real3d_k();
466 }

◆ finalize_impl()

void Radiation::finalize_impl ( amrex::Vector< amrex::MultiFab * > &  lsm_output_ptrs)
1369 {
1370  // Reset gas concentrations (k-dist data persists across steps)
1371  m_gas_concs.reset();
1372 
1373  // Fill the AMReX MFs from Kokkos Views
1374  kokkos_buffers_to_mf(lsm_output_ptrs);
1375 
1376  // Write fluxes if requested
1378 
1379  // Fill output data for datalog before deallocating
1380  if (datalog_int > 0) {
1383  Kokkos::fence();
1385  }
1386 
1387  // Deallocate the buffer arrays
1388  dealloc_buffers();
1389 }
void dealloc_buffers()
Definition: ERF_Radiation.cpp:380
void populateDatalogMF()
Definition: ERF_Radiation.cpp:803
void kokkos_buffers_to_mf(amrex::Vector< amrex::MultiFab * > &lsm_output_ptrs)
Definition: ERF_Radiation.cpp:683
GasConcsK< amrex::Real, layout_t, KokkosDefaultDevice > m_gas_concs
Definition: ERF_Radiation.H:322
void write_rrtmgp_fluxes()
Definition: ERF_Radiation.cpp:763
void compute_heating_rate(View1 const &flux_up, View2 const &flux_dn, View3 const &rho, View4 const &dz, View5 &heating_rate)
Definition: ERF_RRTMGP_Utils.H:81

Referenced by rad_run_impl().

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

◆ get_lsm_input_varnames()

virtual amrex::Vector<std::string> Radiation::get_lsm_input_varnames ( )
inlineoverridevirtual

Reimplemented from IRadiation.

193  {
194  return m_lsm_input_names;
195  }
amrex::Vector< std::string > m_lsm_input_names
Definition: ERF_Radiation.H:253

◆ get_lsm_output_varnames()

virtual amrex::Vector<std::string> Radiation::get_lsm_output_varnames ( )
inlineoverridevirtual

Reimplemented from IRadiation.

201  {
202  return m_lsm_output_names;
203  }
amrex::Vector< std::string > m_lsm_output_names
Definition: ERF_Radiation.H:258

◆ Init()

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

Implements IRadiation.

69  {
70  // Ensure the boxes span klo -> khi
71  int klo = geom.Domain().smallEnd(2);
72  int khi = geom.Domain().bigEnd(2);
73 
74  // Reset vector of offsets for columnar data
75  m_nlay = geom.Domain().length(2);
76 
77  m_ncol = 0;
78  m_col_offsets.clear();
79  m_col_offsets.resize(int(ba.size()));
80  for (amrex::MFIter mfi(*cons_in); mfi.isValid(); ++mfi) {
81  const amrex::Box& vbx = mfi.validbox();
82  AMREX_ALWAYS_ASSERT_WITH_MESSAGE((klo == vbx.smallEnd(2)) &&
83  (khi == vbx.bigEnd(2)),
84  "Vertical decomposition with radiation is not allowed.");
85  int nx = vbx.length(0);
86  int ny = vbx.length(1);
87  m_col_offsets[mfi.index()] = m_ncol;
88  m_ncol += nx * ny;
89  }
90 
91  m_ncol_chunk = amrex::min(m_ncol, m_ncol_chunk);
92  };
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
amrex::Vector< int > m_col_offsets
Definition: ERF_Radiation.H:332

◆ initialize_impl()

void Radiation::initialize_impl ( )
1045 {
1046  // Initialize gas concentrations for this step
1048 
1049  // Load k-distribution and cloud optics data only once.
1050  // These are static lookup tables that never change.
1051  // Size the memory pool for m_ncol_chunk (not min with current m_ncol) so that
1052  // the pool remains valid even if m_ncol grows after regridding/load balancing.
1053  if (!rrtmgp::initialized) {
1054  gas_concs_t gas_concs_pool;
1055  gas_concs_pool.init(gas_names_offset, m_ncol_chunk, m_nlay);
1056  rrtmgp::rrtmgp_initialize(gas_concs_pool,
1059  m_rad_nvar);
1060  gas_concs_pool.reset();
1061  }
1062 }
GasConcsK< RealT, layout_t, KokkosDefaultDevice > gas_concs_t
Definition: ERF_RRTMGP_Interface.H:32
void rrtmgp_initialize(gas_concs_t &gas_concs_k, 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, const int &nvar)
Definition: ERF_RRTMGP_Interface.cpp:229

Referenced by rad_run_impl().

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

◆ kokkos_buffers_to_mf()

void Radiation::kokkos_buffers_to_mf ( amrex::Vector< amrex::MultiFab * > &  lsm_output_ptrs)
684 {
685  // Heating rate, fluxes, zenith, lsm ptrs
686 
687  Table2D<Real,Order::C> p_lay_tab(p_lay.data(), {0,0}, {static_cast<int>(p_lay.extent(0)),static_cast<int>(p_lay.extent(1))});
688  Table2D<Real,Order::C> sw_heating_tab(sw_heating.data(), {0,0}, {static_cast<int>(sw_heating.extent(0)),static_cast<int>(sw_heating.extent(1))});
689  Table2D<Real,Order::C> lw_heating_tab(lw_heating.data(), {0,0}, {static_cast<int>(lw_heating.extent(0)),static_cast<int>(lw_heating.extent(1))});
690  Table2D<Real,Order::C> sw_flux_up_tab(sw_flux_up.data(), {0,0}, {static_cast<int>(sw_flux_up.extent(0)),static_cast<int>(sw_flux_up.extent(1))});
691  Table2D<Real,Order::C> sw_flux_dn_tab(sw_flux_dn.data(), {0,0}, {static_cast<int>(sw_flux_dn.extent(0)),static_cast<int>(sw_flux_dn.extent(1))});
692  Table2D<Real,Order::C> lw_flux_up_tab(lw_flux_up.data(), {0,0}, {static_cast<int>(lw_flux_up.extent(0)),static_cast<int>(lw_flux_up.extent(1))});
693  Table2D<Real,Order::C> lw_flux_dn_tab(lw_flux_dn.data(), {0,0}, {static_cast<int>(lw_flux_dn.extent(0)),static_cast<int>(lw_flux_dn.extent(1))});
694 
695  TableData<Real,1> sfc_flux_sw_dn; sfc_flux_sw_dn.resize({0}, {static_cast<int>(sw_flux_dn.extent(0))});
696  TableData<Real,1> sfc_flux_lw_dn; sfc_flux_lw_dn.resize({0}, {static_cast<int>(lw_flux_dn.extent(0))});
697  Table1D<Real> sfc_flux_sw_dn_tab = sfc_flux_sw_dn.table();
698  Table1D<Real> sfc_flux_lw_dn_tab = sfc_flux_lw_dn.table();
699  Table1D<Real> sfc_flux_sw_dir_vis_tab(sfc_flux_dir_vis.data(), {0}, {static_cast<int>(sfc_flux_dir_vis.extent(0))});
700  Table1D<Real> sfc_flux_sw_dir_nir_tab(sfc_flux_dir_nir.data(), {0}, {static_cast<int>(sfc_flux_dir_nir.extent(0))});
701  Table1D<Real> sfc_flux_sw_dif_vis_tab(sfc_flux_dif_vis.data(), {0}, {static_cast<int>(sfc_flux_dif_vis.extent(0))});
702  Table1D<Real> sfc_flux_sw_dif_nir_tab(sfc_flux_dif_nir.data(), {0}, {static_cast<int>(sfc_flux_dif_nir.extent(0))});
703  Table1D<Real> mu0_tab(mu0.data(), {0}, {static_cast<int>(mu0.extent(0))});
704  Vector<Table1D<Real>> rrtmgp_out_vars = {mu0_tab , sfc_flux_sw_dn_tab ,
705  sfc_flux_sw_dir_vis_tab, sfc_flux_sw_dir_nir_tab,
706  sfc_flux_sw_dif_vis_tab, sfc_flux_sw_dif_nir_tab,
707  sfc_flux_lw_dn_tab };
708 
709  for (MFIter mfi(*m_cons_in); mfi.isValid(); ++mfi) {
710  const auto& vbx = mfi.validbox();
711  const auto& sbx = makeSlab(vbx,2,vbx.smallEnd(2));
712  const int nx = vbx.length(0);
713  const int imin = vbx.smallEnd(0);
714  const int jmin = vbx.smallEnd(1);
715  const int offset = m_col_offsets[mfi.index()];
716  const Array4<Real>& q_arr = m_qheating_rates->array(mfi);
717  const Array4<Real>& f_arr = m_rad_fluxes->array(mfi);
718  ParallelFor(vbx, [=]
719  AMREX_GPU_DEVICE (int i, int j, int k)
720  {
721  // map [i,j,k] 0-based to [icol, ilay] 0-based
722  const int icol = (j-jmin)*nx + (i-imin) + offset;
723  const int ilay = k;
724 
725  // Temperature heating rate for SW and LW
726  q_arr(i,j,k,0) = sw_heating_tab(icol,ilay);
727  q_arr(i,j,k,1) = lw_heating_tab(icol,ilay);
728 
729  // Convert the dT/dz to dTheta/dz
730  Real iexner = one/getExnergivenP(Real(p_lay_tab(icol,ilay)), RdoCp);
731  q_arr(i,j,k,0) *= iexner;
732  q_arr(i,j,k,1) *= iexner;
733 
734  // Populate the fluxes
735  f_arr(i,j,k,0) = sw_flux_up_tab(icol,ilay);
736  f_arr(i,j,k,1) = sw_flux_dn_tab(icol,ilay);
737  f_arr(i,j,k,2) = lw_flux_up_tab(icol,ilay);
738  f_arr(i,j,k,3) = lw_flux_dn_tab(icol,ilay);
739 
740  if (k==0) {
741  sfc_flux_sw_dn_tab(icol) = sw_flux_dn_tab(icol,ilay);
742  sfc_flux_lw_dn_tab(icol) = lw_flux_dn_tab(icol,ilay);
743  }
744  });
745  for (int ivar(0); ivar<lsm_output_ptrs.size(); ivar++) {
746  if (lsm_output_ptrs[ivar]) {
747  auto rrtmgp_for_fill = rrtmgp_out_vars[ivar];
748  const Array4<Real>& lsm_out_arr = lsm_output_ptrs[ivar]->array(mfi);
749  ParallelFor(sbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
750  {
751  // map [i,j,k] 0-based to [icol, ilay] 0-based
752  const int icol = (j-jmin)*nx + (i-imin) + offset;
753 
754  // export the desired variable at surface
755  lsm_out_arr(i,j,k) = rrtmgp_for_fill(icol);
756  });
757  } // valid ptr
758  } // ivar
759  }// mfi
760 }
constexpr amrex::Real one
Definition: ERF_Constants.H:9
constexpr amrex::Real RdoCp
Definition: ERF_Constants.H:54
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenP(const amrex::Real P, const amrex::Real rdOcp)
Definition: ERF_EOS.H:141
ParallelFor(grown_box, [=] AMREX_GPU_DEVICE(int i, int j, int k) { qrcuten_arr(i, j, k)=Real(0);qscuten_arr(i, j, k)=Real(0);qicuten_arr(i, j, k)=Real(0);})
AMREX_FORCE_INLINE IntVect offset(const int face_dir, const int normal)
Definition: ERF_ReadBndryPlanes.cpp:28
amrex::MultiFab * m_cons_in
Definition: ERF_Radiation.H:267
amrex::MultiFab * m_rad_fluxes
Definition: ERF_Radiation.H:273
amrex::MultiFab * m_qheating_rates
Definition: ERF_Radiation.H:270
Here is the call graph for this function:

◆ mf_to_kokkos_buffers()

void Radiation::mf_to_kokkos_buffers ( amrex::iMultiFab *  lmask,
amrex::MultiFab *  t_surf,
amrex::Vector< amrex::MultiFab * > &  lsm_input_ptrs 
)
473 {
474  Table2D<Real,Order::C> r_lay_tab(r_lay.data(), {0,0}, {static_cast<int>(r_lay.extent(0)),static_cast<int>(r_lay.extent(1))});
475  Table2D<Real,Order::C> p_lay_tab(p_lay.data(), {0,0}, {static_cast<int>(p_lay.extent(0)),static_cast<int>(p_lay.extent(1))});
476  Table2D<Real,Order::C> t_lay_tab(t_lay.data(), {0,0}, {static_cast<int>(t_lay.extent(0)),static_cast<int>(t_lay.extent(1))});
477  Table2D<Real,Order::C> z_del_tab(z_del.data(), {0,0}, {static_cast<int>(z_del.extent(0)),static_cast<int>(z_del.extent(1))});
478  Table2D<Real,Order::C> qv_lay_tab(qv_lay.data(), {0,0}, {static_cast<int>(qv_lay.extent(0)),static_cast<int>(qv_lay.extent(1))});
479  Table2D<Real,Order::C> qc_lay_tab(qc_lay.data(), {0,0}, {static_cast<int>(qc_lay.extent(0)),static_cast<int>(qc_lay.extent(1))});
480  Table2D<Real,Order::C> qi_lay_tab(qi_lay.data(), {0,0}, {static_cast<int>(qi_lay.extent(0)),static_cast<int>(qi_lay.extent(1))});
481  Table2D<Real,Order::C> cldfrac_tot_tab(cldfrac_tot.data(), {0,0}, {static_cast<int>(cldfrac_tot.extent(0)),static_cast<int>(cldfrac_tot.extent(1))});
482 
483  Table2D<Real,Order::C> lwp_tab(lwp.data(), {0,0}, {static_cast<int>(lwp.extent(0)),static_cast<int>(lwp.extent(1))});
484  Table2D<Real,Order::C> iwp_tab(iwp.data(), {0,0}, {static_cast<int>(iwp.extent(0)),static_cast<int>(iwp.extent(1))});
485  Table2D<Real,Order::C> eff_radius_qc_tab(eff_radius_qc.data(), {0,0}, {static_cast<int>(eff_radius_qc.extent(0)),static_cast<int>(eff_radius_qc.extent(1))});
486  Table2D<Real,Order::C> eff_radius_qi_tab(eff_radius_qi.data(), {0,0}, {static_cast<int>(eff_radius_qi.extent(0)),static_cast<int>(eff_radius_qi.extent(1))});
487 
488  Table2D<Real,Order::C> p_lev_tab(p_lev.data(), {0,0}, {static_cast<int>(p_lev.extent(0)),static_cast<int>(p_lev.extent(1))});
489  Table2D<Real,Order::C> t_lev_tab(t_lev.data(), {0,0}, {static_cast<int>(t_lev.extent(0)),static_cast<int>(t_lev.extent(1))});
490 
491  Table1D<Real> lat_tab(lat.data(), {0}, {static_cast<int>(lat.extent(0))});
492  Table1D<Real> lon_tab(lon.data(), {0}, {static_cast<int>(lon.extent(0))});
493  Table1D<Real> t_sfc_tab(t_sfc.data(), {0}, {static_cast<int>(t_sfc.extent(0))});
494 
495  bool moist = m_moist;
496  bool ice = m_ice;
497  const bool has_lsm = m_lsm;
498  const bool has_lat = m_lat;
499  const bool has_lon = m_lon;
500  const bool has_surflayer = (t_surf);
501  int ncol = m_ncol;
502  int nlay = m_nlay;
503  Real dz = m_geom.CellSize(2);
504  Real cons_lat = m_lat_cons;
505  Real cons_lon = m_lon_cons;
506  Real rad_t_sfc = m_rad_t_sfc;
507 
508  for (MFIter mfi(*m_cons_in); mfi.isValid(); ++mfi) {
509  const auto& vbx = mfi.validbox();
510  const int nx = vbx.length(0);
511  const int imin = vbx.smallEnd(0);
512  const int jmin = vbx.smallEnd(1);
513  const int offset = m_col_offsets[mfi.index()];
514  const Array4<const Real>& cons_arr = m_cons_in->const_array(mfi);
515  const Array4<const Real>& z_arr = (m_z_phys) ? m_z_phys->const_array(mfi) :
516  Array4<const Real>{};
517  const Array4<const Real>& lat_arr = (m_lat) ? m_lat->const_array(mfi) :
518  Array4<const Real>{};
519  const Array4<const Real>& lon_arr = (m_lon) ? m_lon->const_array(mfi) :
520  Array4<const Real>{};
521  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
522  {
523  // map [i,j,k] 0-based to [icol, ilay] 0-based
524  const int icol = (j-jmin)*nx + (i-imin) + offset;
525  const int ilay = k;
526 
527  // EOS input (at CC)
528  Real r = cons_arr(i,j,k,Rho_comp);
529  Real rt = cons_arr(i,j,k,RhoTheta_comp);
530  Real qv = (moist) ? std::max(cons_arr(i,j,k,RhoQ1_comp)/r,Real(0.)) : Real(0.);
531  Real qc = (moist) ? std::max(cons_arr(i,j,k,RhoQ2_comp)/r,Real(0.)) : Real(0.);
532  Real qi = (ice) ? std::max(cons_arr(i,j,k,RhoQ3_comp)/r,Real(0.)) : Real(0.);
533 
534  // EOS avg to z-face
535  Real r_lo = cons_arr(i,j,k-1,Rho_comp);
536  Real rt_lo = cons_arr(i,j,k-1,RhoTheta_comp);
537  Real qv_lo = (moist) ? cons_arr(i,j,k-1,RhoQ1_comp)/r_lo : Real(0.);
538  Real dz_k = (z_arr) ? Real(0.125) * ( (z_arr(i ,j ,k+1) - z_arr(i ,j ,k))
539  + (z_arr(i+1,j ,k+1) - z_arr(i+1,j ,k))
540  + (z_arr(i ,j+1,k+1) - z_arr(i ,j+1,k))
541  + (z_arr(i+1,j+1,k+1) - z_arr(i+1,j+1,k)) ) : Real(0.5)*dz; // Dist from w-face to CC at k
542  Real dz_km1 = (z_arr) ? Real(0.125) * ( (z_arr(i ,j ,k ) - z_arr(i ,j ,k-1))
543  + (z_arr(i+1,j ,k ) - z_arr(i+1,j ,k-1))
544  + (z_arr(i ,j+1,k ) - z_arr(i ,j+1,k-1))
545  + (z_arr(i+1,j+1,k ) - z_arr(i+1,j+1,k-1)) ) : Real(0.5)*dz; // Dist from w-face to CC at k-1
546  Real r_avg = (dz_k*r + dz_km1*r_lo ) / (dz_k + dz_km1);
547  Real rt_avg = (dz_k*rt + dz_km1*rt_lo) / (dz_k + dz_km1);
548  Real qv_avg = (dz_k*qv + dz_km1*qv_lo) / (dz_k + dz_km1);
549 
550  // Views at CC
551  r_lay_tab(icol,ilay) = r;
552 
553  p_lay_tab(icol,ilay) = getPgivenRTh(rt, qv);
554  t_lay_tab(icol,ilay) = getTgivenRandRTh(r, rt, qv);
555  z_del_tab(icol,ilay) = (z_arr) ? Real(0.25) * ( (z_arr(i ,j ,k+1) - z_arr(i ,j ,k))
556  + (z_arr(i+1,j ,k+1) - z_arr(i+1,j ,k))
557  + (z_arr(i ,j+1,k+1) - z_arr(i ,j+1,k))
558  + (z_arr(i+1,j+1,k+1) - z_arr(i+1,j+1,k)) ) : dz;
559  qv_lay_tab(icol,ilay) = qv;
560  qc_lay_tab(icol,ilay) = qc;
561  qi_lay_tab(icol,ilay) = qi;
562  cldfrac_tot_tab(icol,ilay) = ((qc+qi)>Real(0.)) ? Real(1.) : Real(0.);
563 
564  // NOTE: These are populated in 'mixing_ratio_to_cloud_mass'
565  lwp_tab(icol,ilay) = Real(0.);
566  iwp_tab(icol,ilay) = Real(0.);
567 
568  // NOTE: These would be populated from P3 (we use the constants in p3_main_impl.hpp)
569  // NOTE: These are in units of micron!
570  eff_radius_qc_tab(icol,ilay) = (qc>Real(0.)) ? Real(10.0) : Real(0.);
571  eff_radius_qi_tab(icol,ilay) = (qi>Real(0.)) ? Real(25.0) : Real(0.);
572 
573  // Buffers on z-faces (nlay+1)
574  p_lev_tab(icol,ilay) = getPgivenRTh(rt_avg, qv_avg);
575  t_lev_tab(icol,ilay) = getTgivenRandRTh(r_avg, rt_avg, qv_avg);
576  if (ilay==(nlay-1)) {
577  Real r_hi = cons_arr(i,j,k+1,Rho_comp);
578  Real rt_hi = cons_arr(i,j,k+1,RhoTheta_comp);
579  Real qv_hi = (moist) ? std::max(cons_arr(i,j,k+1,RhoQ1_comp)/r_hi,Real(0.)) : Real(0.);
580  Real dz_kp1 = (z_arr) ? Real(0.125) * ( (z_arr(i ,j ,k+2) - z_arr(i ,j ,k+1))
581  + (z_arr(i+1,j ,k+2) - z_arr(i+1,j ,k+1))
582  + (z_arr(i ,j+1,k+2) - z_arr(i ,j+1,k+1))
583  + (z_arr(i+1,j+1,k+2) - z_arr(i+1,j+1,k+1)) ) : Real(0.5)*dz; // Dist from w-face to CC at k+1
584  r_avg = (dz_k*r + dz_kp1*r_hi ) / (dz_k + dz_kp1);
585  rt_avg = (dz_k*rt + dz_kp1*rt_hi) / (dz_k + dz_kp1);
586  qv_avg = (dz_k*qv + dz_kp1*qv_hi) / (dz_k + dz_kp1);
587  p_lev_tab(icol,ilay+1) = getPgivenRTh(rt_avg, qv_avg);
588  t_lev_tab(icol,ilay+1) = getTgivenRandRTh(r_avg, rt_avg, qv_avg);
589  }
590 
591  // 1D data structures
592  if (k==0) {
593  lat_tab(icol) = (has_lat) ? lat_arr(i,j,0) : cons_lat;
594  lon_tab(icol) = (has_lon) ? lon_arr(i,j,0) : cons_lon;
595  }
596 
597  });
598  } // mfi
599 
600  // Populate vars LSM would provide
601  if (!has_lsm && !has_surflayer) {
602  // Parsed surface temp
603  Kokkos::deep_copy(t_sfc, rad_t_sfc);
604 
605  // EAMXX dummy atmos constants
606  Kokkos::deep_copy(sfc_alb_dir_vis, Real(0.06));
607  Kokkos::deep_copy(sfc_alb_dir_nir, Real(0.06));
608  Kokkos::deep_copy(sfc_alb_dif_vis, Real(0.06));
609  Kokkos::deep_copy(sfc_alb_dif_nir, Real(0.06));
610 
611  // AML NOTE: These are not used in current EAMXX, I've left
612  // the code to plug into these if we need it.
613  //
614  // Current EAMXX constants
615  Kokkos::deep_copy(sfc_emis, Real(0.98));
616  Kokkos::deep_copy(lw_src , zero );
617  } else {
618  Vector<real1d_k> rrtmgp_in_vars = {t_sfc, sfc_emis,
621  Vector<Real> rrtmgp_default_vals = {rad_t_sfc, Real(0.98),
622  Real(0.06), Real(0.06),
623  Real(0.06), Real(0.06)};
624  for (int ivar(0); ivar<lsm_input_ptrs.size(); ivar++) {
625  auto rrtmgp_default_val = rrtmgp_default_vals[ivar];
626  auto rrtmgp_to_fill_k = rrtmgp_in_vars[ivar];
627  amrex::Table1D<amrex::Real> rrtmgp_to_fill(rrtmgp_to_fill_k.data(),
628  0, rrtmgp_to_fill_k.extent(0));
629  for (MFIter mfi(*m_cons_in); mfi.isValid(); ++mfi) {
630  const auto& vbx = mfi.validbox();
631  const auto& sbx = makeSlab(vbx,2,vbx.smallEnd(2));
632  const int nx = vbx.length(0);
633  const int imin = vbx.smallEnd(0);
634  const int jmin = vbx.smallEnd(1);
635  const int offset = m_col_offsets[mfi.index()];
636  const Array4<const int>& lmask_arr = (lmask) ? lmask->const_array(mfi) :
637  Array4<const int> {};
638  const Array4<const Real>& tsurf_arr = (t_surf) ? t_surf->const_array(mfi) :
639  Array4<const Real> {};
640  const Array4< Real>& lsm_in_arr = (lsm_input_ptrs[ivar]) ? lsm_input_ptrs[ivar]->array(mfi) :
641  Array4< Real> {};
642  ParallelFor(sbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
643  {
644  // map [i,j,k] 0-based to [icol, ilay] 0-based
645  const int icol = (j-jmin)*nx + (i-imin) + offset;
646 
647  // Check if over land
648  bool is_land = (lmask_arr) ? lmask_arr(i,j,k) : 1;
649 
650  // Check if valid LSM data
651  bool valid_lsm_data = (lsm_in_arr && (lsm_in_arr(i,j,k) < lsm_undefined));
652 
653  // Have LSM and are over land
654  if (is_land && valid_lsm_data) {
655  rrtmgp_to_fill(icol) = lsm_in_arr(i,j,k);
656  }
657  // We have a SurfLayer (enforce consistency with temperature)
658  else if (tsurf_arr && (ivar==0)) {
659  rrtmgp_to_fill(icol) = tsurf_arr(i,j,k);
660  if (lsm_in_arr) { lsm_in_arr(i,j,k) = tsurf_arr(i,j,k); }
661  }
662  // Use the default value
663  else {
664  rrtmgp_to_fill(icol) = rrtmgp_default_val;
665  if (lsm_in_arr) { lsm_in_arr(i,j,k) = rrtmgp_default_val; }
666  }
667  });
668  } //mfi
669  } // ivar
670  Kokkos::deep_copy(lw_src, zero );
671  } // have lsm
672 
673  // Enforce consistency between t_sfc and t_lev at bottom surface
674  Kokkos::parallel_for(Kokkos::RangePolicy(0, ncol),
675  KOKKOS_LAMBDA (int icol)
676  {
677  t_lev_tab(icol,0) = t_sfc_tab(icol);
678  });
679 }
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
constexpr amrex::Real lsm_undefined
Definition: ERF_Constants.H:35
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getTgivenRandRTh(const amrex::Real rho, const amrex::Real rhotheta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:46
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:81
#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::MultiFab * m_lon
Definition: ERF_Radiation.H:280
amrex::MultiFab * m_z_phys
Definition: ERF_Radiation.H:276
amrex::Geometry m_geom
Definition: ERF_Radiation.H:232
amrex::MultiFab * m_lat
Definition: ERF_Radiation.H:279
@ t_surf
Definition: ERF_OceanSurf.H:14
@ qv
Definition: ERF_Kessler.H:30
@ qc
Definition: ERF_SatAdj.H:40
@ qi
Definition: ERF_WSM6.H:27
@ dz
Definition: ERF_AdvanceWSM6.cpp:104
Here is the call graph for this function:

◆ populateDatalogMF()

void Radiation::populateDatalogMF ( )
804 {
805  Table2D<Real,Order::C> sw_flux_up_tab(sw_flux_up.data(), {0,0}, {static_cast<int>(sw_flux_up.extent(0)),static_cast<int>(sw_flux_up.extent(1))});
806  Table2D<Real,Order::C> sw_flux_dn_tab(sw_flux_dn.data(), {0,0}, {static_cast<int>(sw_flux_dn.extent(0)),static_cast<int>(sw_flux_dn.extent(1))});
807  Table2D<Real,Order::C> sw_flux_dn_dir_tab(sw_flux_dn_dir.data(), {0,0}, {static_cast<int>(sw_flux_dn_dir.extent(0)),static_cast<int>(sw_flux_dn_dir.extent(1))});
808  Table2D<Real,Order::C> lw_flux_up_tab(lw_flux_up.data(), {0,0}, {static_cast<int>(lw_flux_up.extent(0)),static_cast<int>(lw_flux_up.extent(1))});
809  Table2D<Real,Order::C> lw_flux_dn_tab(lw_flux_dn.data(), {0,0}, {static_cast<int>(lw_flux_dn.extent(0)),static_cast<int>(lw_flux_dn.extent(1))});
810 
811  Table2D<Real,Order::C> sw_clrsky_flux_up_tab(sw_clrsky_flux_up.data(), {0,0},
812  {static_cast<int>(sw_clrsky_flux_up.extent(0)),static_cast<int>(sw_clrsky_flux_up.extent(1))});
813  Table2D<Real,Order::C> sw_clrsky_flux_dn_tab(sw_clrsky_flux_dn.data(), {0,0},
814  {static_cast<int>(sw_clrsky_flux_dn.extent(0)),static_cast<int>(sw_clrsky_flux_dn.extent(1))});
815  Table2D<Real,Order::C> sw_clrsky_flux_dn_dir_tab(sw_clrsky_flux_dn_dir.data(), {0,0},
816  {static_cast<int>(sw_clrsky_flux_dn_dir.extent(0)),static_cast<int>(sw_clrsky_flux_dn_dir.extent(1))});
817  Table2D<Real,Order::C> lw_clrsky_flux_up_tab(lw_clrsky_flux_up.data(), {0,0},
818  {static_cast<int>(lw_clrsky_flux_up.extent(0)),static_cast<int>(lw_clrsky_flux_up.extent(1))});
819  Table2D<Real,Order::C> lw_clrsky_flux_dn_tab(lw_clrsky_flux_dn.data(), {0,0},
820  {static_cast<int>(lw_clrsky_flux_dn.extent(0)),static_cast<int>(lw_clrsky_flux_dn.extent(1))});
821  Table2D<Real,Order::C> sw_clrsky_heating_tab(sw_clrsky_heating.data(), {0,0},
822  {static_cast<int>(sw_clrsky_heating.extent(0)),static_cast<int>(sw_clrsky_heating.extent(1))});
823  Table2D<Real,Order::C> lw_clrsky_heating_tab(lw_clrsky_heating.data(), {0,0},
824  {static_cast<int>(lw_clrsky_heating.extent(0)),static_cast<int>(lw_clrsky_heating.extent(1))});
825  Table2D<Real,Order::C> sw_clnsky_flux_up_tab(sw_clnsky_flux_up.data(), {0,0},
826  {static_cast<int>(sw_clnsky_flux_up.extent(0)),static_cast<int>(sw_clnsky_flux_up.extent(1))});
827  Table2D<Real,Order::C> sw_clnsky_flux_dn_tab(sw_clnsky_flux_dn.data(), {0,0},
828  {static_cast<int>(sw_clnsky_flux_dn.extent(0)),static_cast<int>(sw_clnsky_flux_dn.extent(1))});
829  Table2D<Real,Order::C> sw_clnsky_flux_dn_dir_tab(sw_clnsky_flux_dn_dir.data(), {0,0},
830  {static_cast<int>(sw_clnsky_flux_dn_dir.extent(0)),static_cast<int>(sw_clnsky_flux_dn_dir.extent(1))});
831  Table2D<Real,Order::C> lw_clnsky_flux_up_tab(lw_clnsky_flux_up.data(), {0,0},
832  {static_cast<int>(lw_clnsky_flux_up.extent(0)),static_cast<int>(lw_clnsky_flux_up.extent(1))});
833  Table2D<Real,Order::C> lw_clnsky_flux_dn_tab(lw_clnsky_flux_dn.data(), {0,0},
834  {static_cast<int>(lw_clnsky_flux_dn.extent(0)),static_cast<int>(lw_clnsky_flux_dn.extent(1))});
835  Table2D<Real,Order::C> sw_clnclrsky_flux_up_tab(sw_clnclrsky_flux_up.data(), {0,0},
836  {static_cast<int>(sw_clnclrsky_flux_up.extent(0)),static_cast<int>(sw_clnclrsky_flux_up.extent(1))});
837  Table2D<Real,Order::C> sw_clnclrsky_flux_dn_tab(sw_clnclrsky_flux_dn.data(), {0,0},
838  {static_cast<int>(sw_clnclrsky_flux_dn.extent(0)),static_cast<int>(sw_clnclrsky_flux_dn.extent(1))});
839  Table2D<Real,Order::C> sw_clnclrsky_flux_dn_dir_tab(sw_clnclrsky_flux_dn_dir.data(), {0,0},
840  {static_cast<int>(sw_clnclrsky_flux_dn_dir.extent(0)),static_cast<int>(sw_clnclrsky_flux_dn_dir.extent(1))});
841  Table2D<Real,Order::C> lw_clnclrsky_flux_up_tab(lw_clnclrsky_flux_up.data(), {0,0},
842  {static_cast<int>(lw_clnclrsky_flux_up.extent(0)),static_cast<int>(lw_clnclrsky_flux_up.extent(1))});
843  Table2D<Real,Order::C> lw_clnclrsky_flux_dn_tab(lw_clnclrsky_flux_dn.data(), {0,0},
844  {static_cast<int>(lw_clnclrsky_flux_dn.extent(0)),static_cast<int>(lw_clnclrsky_flux_dn.extent(1))});
845 
846  Table1D<Real> mu0_tab(mu0.data(), {0}, {static_cast<int>(mu0.extent(0))});
847 
848  auto extra_clnsky_diag = m_extra_clnsky_diag;
849  auto extra_clnclrsky_diag = m_extra_clnclrsky_diag;
850 
851  for (MFIter mfi(datalog_mf); mfi.isValid(); ++mfi) {
852  const auto& vbx = mfi.validbox();
853  const int nx = vbx.length(0);
854  const int imin = vbx.smallEnd(0);
855  const int jmin = vbx.smallEnd(1);
856  const int offset = m_col_offsets[mfi.index()];
857  const Array4<Real>& dst_arr = datalog_mf.array(mfi);
858  const Array4<Real>& q_arr = m_qheating_rates->array(mfi);
859  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
860  {
861  // map [i,j,k] 0-based to [icol, ilay] 0-based
862  const int icol = (j-jmin)*nx + (i-imin) + offset;
863  const int ilay = k;
864 
865  dst_arr(i,j,k,0) = q_arr(i, j, k, 0);
866  dst_arr(i,j,k,1) = q_arr(i, j, k, 1);
867 
868  // SW and LW fluxes
869  dst_arr(i,j,k,2) = sw_flux_up_tab(icol,ilay);
870  dst_arr(i,j,k,3) = sw_flux_dn_tab(icol,ilay);
871  dst_arr(i,j,k,4) = sw_flux_dn_dir_tab(icol,ilay);
872  dst_arr(i,j,k,5) = lw_flux_up_tab(icol,ilay);
873  dst_arr(i,j,k,6) = lw_flux_dn_tab(icol,ilay);
874 
875  // Cosine zenith angle
876  dst_arr(i,j,k,7) = mu0_tab(icol);
877 
878  // Clear sky heating rates and fluxes:
879  dst_arr(i,j,k,8) = sw_clrsky_heating_tab(icol, ilay);
880  dst_arr(i,j,k,9) = lw_clrsky_heating_tab(icol, ilay);
881 
882  dst_arr(i,j,k,10) = sw_clrsky_flux_up_tab(icol,ilay);
883  dst_arr(i,j,k,11) = sw_clrsky_flux_dn_tab(icol,ilay);
884  dst_arr(i,j,k,12) = sw_clrsky_flux_dn_dir_tab(icol,ilay);
885  dst_arr(i,j,k,13) = lw_clrsky_flux_up_tab(icol,ilay);
886  dst_arr(i,j,k,14) = lw_clrsky_flux_dn_tab(icol,ilay);
887 
888  // Clean sky fluxes:
889  if (extra_clnsky_diag) {
890  dst_arr(i,j,k,15) = sw_clnsky_flux_up_tab(icol,ilay);
891  dst_arr(i,j,k,16) = sw_clnsky_flux_dn_tab(icol,ilay);
892  dst_arr(i,j,k,17) = sw_clnsky_flux_dn_dir_tab(icol,ilay);
893  dst_arr(i,j,k,18) = lw_clnsky_flux_up_tab(icol,ilay);
894  dst_arr(i,j,k,19) = lw_clnsky_flux_dn_tab(icol,ilay);
895  }
896 
897  // Clean-clear sky fluxes:
898  if (extra_clnclrsky_diag) {
899  dst_arr(i,j,k,20) = sw_clnclrsky_flux_up_tab(icol,ilay);
900  dst_arr(i,j,k,21) = sw_clnclrsky_flux_dn_tab(icol,ilay);
901  dst_arr(i,j,k,22) = sw_clnclrsky_flux_dn_dir_tab(icol,ilay);
902  dst_arr(i,j,k,23) = lw_clnclrsky_flux_up_tab(icol,ilay);
903  dst_arr(i,j,k,24) = lw_clnclrsky_flux_dn_tab(icol,ilay);
904  }
905  });
906  }
907 }
amrex::MultiFab datalog_mf
Definition: ERF_Radiation.H:287
Here is the call graph for this function:

◆ rad_run_impl()

void Radiation::rad_run_impl ( amrex::Vector< amrex::MultiFab * > &  lsm_output_ptrs)
inline
178  {
179  if (m_update_rad) {
180  amrex::Print() << "Radiation advancing level " << m_lev << " at (YY-MM-DD SS) " << m_orbital_year << '-'
181  << m_orbital_mon << '-' << m_orbital_day << ' ' << m_orbital_sec << " ...";
182  this->initialize_impl();
183  this->run_impl();
184  this->finalize_impl(lsm_output_ptrs);
185  amrex::Print() << "DONE\n";
186  }
187  }
void initialize_impl()
Definition: ERF_Radiation.cpp:1044
void run_impl()
Definition: ERF_Radiation.cpp:1066
int m_orbital_mon
Definition: ERF_Radiation.H:348
void finalize_impl(amrex::Vector< amrex::MultiFab * > &lsm_output_ptrs)
Definition: ERF_Radiation.cpp:1368
int m_orbital_sec
Definition: ERF_Radiation.H:350
int m_lev
Definition: ERF_Radiation.H:220
bool m_update_rad
Definition: ERF_Radiation.H:238
int m_orbital_day
Definition: ERF_Radiation.H:349

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,
double &  time,
const double &  dt,
const amrex::BoxArray &  ba,
amrex::Geometry &  geom,
amrex::MultiFab *  cons_in,
amrex::iMultiFab *  lmask,
amrex::MultiFab *  t_surf,
amrex::Vector< amrex::MultiFab * > &  lsm_input_ptrs,
amrex::Vector< amrex::MultiFab * > &  lsm_output_ptrs,
amrex::MultiFab *  qheating_rates,
amrex::MultiFab *  rad_fluxes,
amrex::MultiFab *  z_phys,
amrex::MultiFab *  lat_ptr,
amrex::MultiFab *  lon_ptr,
const bool  updated_lsm 
)
inlineoverridevirtual

Implements IRadiation.

113  {
114  set_grids(level, step, time, dt, ba, geom,
115  cons_in, lmask, t_surf,
116  lsm_input_ptrs, qheating_rates,
117  rad_fluxes, z_phys, lat_ptr, lon_ptr,
118  updated_lsm);
119  rad_run_impl(lsm_output_ptrs);
120  }
void set_grids(int &level, int &step, double &time, const double &dt, const amrex::BoxArray &ba, amrex::Geometry &geom, amrex::MultiFab *cons_in, amrex::iMultiFab *lmask, amrex::MultiFab *t_surf, amrex::Vector< amrex::MultiFab * > &lsm_input_ptrs, amrex::MultiFab *qheating_rates, amrex::MultiFab *rad_fluxes, amrex::MultiFab *z_phys, amrex::MultiFab *lat, amrex::MultiFab *lon, const bool updated_lsm)
Definition: ERF_Radiation.cpp:158
void rad_run_impl(amrex::Vector< amrex::MultiFab * > &lsm_output_ptrs)
Definition: ERF_Radiation.H:177
Here is the call graph for this function:

◆ run_impl()

void Radiation::run_impl ( )
1067 {
1068  // Local copies
1069  const auto ncol = m_ncol;
1070  const auto nlay = m_nlay;
1071  const auto nswbands = m_nswbands;
1072 
1073  // Compute orbital parameters; these are used both for computing
1074  // the solar zenith angle and also for computing total solar
1075  // irradiance scaling (tsi_scaling).
1076  double obliqr, lambm0, mvelpp;
1077  int orbital_year = m_orbital_year;
1078  double eccen = m_orbital_eccen;
1079  double obliq = m_orbital_obliq;
1080  double mvelp = m_orbital_mvelp;
1081  if (eccen >= 0 && obliq >= 0 && mvelp >= 0) {
1082  // fixed orbital parameters forced with orbital_year == ORB_UNDEF_INT
1083  orbital_year = ORB_UNDEF_INT;
1084  }
1085  orbital_params(orbital_year, eccen, obliq,
1086  mvelp, obliqr, lambm0, mvelpp);
1087 
1088  // Use the orbital parameters to calculate the solar declination and eccentricity factor
1089  double delta, eccf;
1090  // Want day + fraction; calday 1 == Jan 1 0Z
1091  static constexpr double dpy[] = {zero , Real(31.0), Real(59.0), Real(90.0), Real(120.0), Real(151.0),
1092  Real(181.0), Real(212.0), Real(243.0), Real(273.0), Real(304.0), Real(334.0)};
1093  bool leap = (m_orbital_year % 4 == 0 && (!(m_orbital_year % 100 == 0) || (m_orbital_year % 400 == 0))) ? true : false;
1094  double calday = one + dpy[m_orbital_mon-1] + (m_orbital_day-one) + m_orbital_sec/Real(86400.0);
1095  // add extra day if leap year and past February
1096  if (leap && m_orbital_mon>2) { calday += one; }
1097  orbital_decl(calday, eccen, mvelpp, lambm0, obliqr, delta, eccf);
1098 
1099  // Overwrite eccf if using a fixed solar constant.
1100  auto fixed_total_solar_irradiance = m_fixed_total_solar_irradiance;
1101  if (fixed_total_solar_irradiance >= 0){
1102  eccf = fixed_total_solar_irradiance/Real(1360.9);
1103  }
1104 
1105  // Precompute volume mixing ratio (VMR) for all gases
1106  //
1107  // H2O is obtained from qv.
1108  // O3 may be a constant or a 1D vector
1109  // All other comps are set to constants for now
1110  Vector<real2d_k> vmr_full_vec(m_ngas);
1111  for (int igas(0); igas < m_ngas; ++igas) {
1112  auto name = m_gas_names[igas];
1113  vmr_full_vec[igas] = real2d_k("vmr_full_" + name, ncol, nlay);
1114  auto tmp2d = vmr_full_vec[igas];
1115  auto gas_mol_weight = m_mol_weight_gas[igas];
1116  if (name == "H2O") {
1117  auto qv_lay_d = qv_lay;
1118  Kokkos::parallel_for(Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {ncol, nlay}),
1119  KOKKOS_LAMBDA (int icol, int ilay)
1120  {
1121  tmp2d(icol,ilay) = qv_lay_d(icol,ilay) * mwdair/gas_mol_weight;
1122  });
1123  } else if (name == "CO2") {
1124  Kokkos::deep_copy(tmp2d, m_co2vmr);
1125  } else if (name == "O3") {
1126  if (m_o3_size==1) {
1127  Kokkos::deep_copy(tmp2d, m_o3vmr[0] );
1128  } else {
1129  auto o3_lay_d = o3_lay;
1130  Kokkos::parallel_for(Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {ncol, nlay}),
1131  KOKKOS_LAMBDA (int icol, int ilay)
1132  {
1133  tmp2d(icol,ilay) = o3_lay_d(ilay);
1134  });
1135  }
1136  } else if (name == "N2O") {
1137  Kokkos::deep_copy(tmp2d, m_n2ovmr);
1138  } else if (name == "CO") {
1139  Kokkos::deep_copy(tmp2d, m_covmr );
1140  } else if (name == "CH4") {
1141  Kokkos::deep_copy(tmp2d, m_ch4vmr);
1142  } else if (name == "O2") {
1143  Kokkos::deep_copy(tmp2d, m_o2vmr );
1144  } else if (name == "N2") {
1145  Kokkos::deep_copy(tmp2d, m_n2vmr );
1146  } else {
1147  Abort("Radiation: Unknown gas component.");
1148  }
1149 
1150  // Populate GasConcs object
1151  m_gas_concs.set_vmr(name, tmp2d);
1152  Kokkos::fence();
1153  }
1154 
1155  // Populate mu0 1D array
1156  // This must be done on HOST and copied to device.
1157  auto h_mu0 = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), mu0);
1158  if (m_fixed_solar_zenith_angle > 0) {
1159  Kokkos::deep_copy(h_mu0, m_fixed_solar_zenith_angle);
1160  } else {
1161  auto h_lat = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), lat);
1162  auto h_lon = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), lon);
1163  double dt = double(m_dt);
1164  auto rad_freq_in_steps = m_rad_freq_in_steps;
1165  Kokkos::parallel_for(Kokkos::RangePolicy<Kokkos::Serial>(0, ncol),
1166  [&,PI_d=PI] (int icol)
1167  {
1168  // Convert lat/lon to radians
1169  double lat_col = h_lat(icol)*PI_d/Real(180.0);
1170  double lon_col = h_lon(icol)*PI_d/Real(180.0);
1171  double lcalday = calday;
1172  double ldelta = delta;
1173  double dt_avg = static_cast<double>(rad_freq_in_steps) * dt;
1174  h_mu0(icol) = Real(orbital_cos_zenith(lcalday, lat_col, lon_col, ldelta, dt_avg));
1175  });
1176  }
1177  Kokkos::deep_copy(mu0, h_mu0);
1178 
1179  // Compute layer cloud mass per unit area (populates lwp/iwp)
1182 
1183  // Convert to g/m2 (needed by RRTMGP)
1184  Table2D<Real,Order::C> lwp_tab(lwp.data(), {0,0}, {static_cast<int>(lwp.extent(0)),static_cast<int>(lwp.extent(1))});
1185  Table2D<Real,Order::C> iwp_tab(iwp.data(), {0,0}, {static_cast<int>(iwp.extent(0)),static_cast<int>(iwp.extent(1))});
1186  Kokkos::parallel_for(Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {ncol, nlay}),
1187  KOKKOS_LAMBDA (int icol, int ilay)
1188  {
1189  lwp_tab(icol,ilay) *= Real(1.e3);
1190  iwp_tab(icol,ilay) *= Real(1.e3);
1191  });
1192 
1193  // -----------------------------------------------------------------------
1194  // Process radiation in column chunks to limit peak GPU memory.
1195  // Radiation columns are independent (no horizontal coupling), so
1196  // chunking produces bit-identical results.
1197  // -----------------------------------------------------------------------
1198  const int ncol_chunk = std::min(m_ncol_chunk, ncol);
1199  const int kbot = 0;
1200 
1201  for (int col_s = 0; col_s < ncol; col_s += ncol_chunk) {
1202  const int ncol_c = std::min(ncol_chunk, ncol - col_s);
1203  const int col_e = col_s + ncol_c;
1204  auto cr = std::make_pair(col_s, col_e);
1205 
1206  // --- Chunk subviews: 1D (ncol) ---
1207  real1d_k mu0_c (mu0.data() + col_s, ncol_c);
1208  real1d_k sfc_alb_dir_vis_c (sfc_alb_dir_vis.data() + col_s, ncol_c);
1209  real1d_k sfc_alb_dir_nir_c (sfc_alb_dir_nir.data() + col_s, ncol_c);
1210  real1d_k sfc_alb_dif_vis_c (sfc_alb_dif_vis.data() + col_s, ncol_c);
1211  real1d_k sfc_alb_dif_nir_c (sfc_alb_dif_nir.data() + col_s, ncol_c);
1212  real1d_k sfc_flux_dir_vis_c (sfc_flux_dir_vis.data() + col_s, ncol_c);
1213  real1d_k sfc_flux_dir_nir_c (sfc_flux_dir_nir.data() + col_s, ncol_c);
1214  real1d_k sfc_flux_dif_vis_c (sfc_flux_dif_vis.data() + col_s, ncol_c);
1215  real1d_k sfc_flux_dif_nir_c (sfc_flux_dif_nir.data() + col_s, ncol_c);
1216  real1d_k t_sfc_c (t_sfc.data() + col_s, ncol_c);
1217  real1d_k sfc_emis_c (sfc_emis.data() + col_s, ncol_c);
1218  real1d_k lw_src_c (lw_src.data() + col_s, ncol_c);
1219 
1220  // --- Chunk subviews: 2D (ncol, nlay) via LayoutRight pointer offset ---
1221  const int stride2_nlay = nlay;
1222  const int stride2_nlayp1 = nlay + 1;
1223  real2d_k p_lay_c (p_lay.data() + col_s*stride2_nlay, ncol_c, nlay);
1224  real2d_k t_lay_c (t_lay.data() + col_s*stride2_nlay, ncol_c, nlay);
1225  real2d_k r_lay_c (r_lay.data() + col_s*stride2_nlay, ncol_c, nlay);
1226  real2d_k z_del_c (z_del.data() + col_s*stride2_nlay, ncol_c, nlay);
1227  real2d_k lwp_c (lwp.data() + col_s*stride2_nlay, ncol_c, nlay);
1228  real2d_k iwp_c (iwp.data() + col_s*stride2_nlay, ncol_c, nlay);
1229  real2d_k eff_radius_qc_c(eff_radius_qc.data() + col_s*stride2_nlay, ncol_c, nlay);
1230  real2d_k eff_radius_qi_c(eff_radius_qi.data() + col_s*stride2_nlay, ncol_c, nlay);
1231  real2d_k cldfrac_tot_c (cldfrac_tot.data() + col_s*stride2_nlay, ncol_c, nlay);
1232  real2d_k sw_heating_c (sw_heating.data() + col_s*stride2_nlay, ncol_c, nlay);
1233  real2d_k lw_heating_c (lw_heating.data() + col_s*stride2_nlay, ncol_c, nlay);
1234 
1235  // --- Chunk subviews: 2D (ncol, nlay+1) ---
1236  real2d_k p_lev_c (p_lev.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1237  real2d_k t_lev_c (t_lev.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1238  real2d_k sw_flux_up_c (sw_flux_up.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1239  real2d_k sw_flux_dn_c (sw_flux_dn.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1240  real2d_k sw_flux_dn_dir_c (sw_flux_dn_dir.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1241  real2d_k lw_flux_up_c (lw_flux_up.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1242  real2d_k lw_flux_dn_c (lw_flux_dn.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1243  // Clear-sky flux subviews (always active)
1244  // NOTE: once on m_ncol_chunk if not writing a datalog
1245  real2d_k sw_clrsky_flux_up_c, sw_clrsky_flux_dn_c, sw_clrsky_flux_dn_dir_c;
1246  real2d_k lw_clrsky_flux_up_c, lw_clrsky_flux_dn_c;
1247  if (datalog_int > 0) {
1248  sw_clrsky_flux_up_c = real2d_k(sw_clrsky_flux_up.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1249  sw_clrsky_flux_dn_c = real2d_k(sw_clrsky_flux_dn.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1250  sw_clrsky_flux_dn_dir_c = real2d_k(sw_clrsky_flux_dn_dir.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1251  lw_clrsky_flux_up_c = real2d_k(lw_clrsky_flux_up.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1252  lw_clrsky_flux_dn_c = real2d_k(lw_clrsky_flux_dn.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1253  } else {
1254  sw_clrsky_flux_up_c = real2d_k(sw_clrsky_flux_up.data() , ncol_c, nlay+1);
1255  sw_clrsky_flux_dn_c = real2d_k(sw_clrsky_flux_dn.data() , ncol_c, nlay+1);
1256  sw_clrsky_flux_dn_dir_c = real2d_k(sw_clrsky_flux_dn_dir.data() , ncol_c, nlay+1);
1257  lw_clrsky_flux_up_c = real2d_k(lw_clrsky_flux_up.data() , ncol_c, nlay+1);
1258  lw_clrsky_flux_dn_c = real2d_k(lw_clrsky_flux_dn.data() , ncol_c, nlay+1);
1259  }
1260 
1261  // Diagnostic flux subviews (placeholder when disabled)
1262  real2d_k sw_clnclrsky_flux_up_c, sw_clnclrsky_flux_dn_c, sw_clnclrsky_flux_dn_dir_c;
1263  real2d_k lw_clnclrsky_flux_up_c, lw_clnclrsky_flux_dn_c;
1264  if (m_extra_clnclrsky_diag) {
1265  sw_clnclrsky_flux_up_c = real2d_k(sw_clnclrsky_flux_up.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1266  sw_clnclrsky_flux_dn_c = real2d_k(sw_clnclrsky_flux_dn.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1267  sw_clnclrsky_flux_dn_dir_c = real2d_k(sw_clnclrsky_flux_dn_dir.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1268  lw_clnclrsky_flux_up_c = real2d_k(lw_clnclrsky_flux_up.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1269  lw_clnclrsky_flux_dn_c = real2d_k(lw_clnclrsky_flux_dn.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1270  } else {
1271  sw_clnclrsky_flux_up_c = real2d_k("sw_clnclrsky_flux_up_c" , 1, 1);
1272  sw_clnclrsky_flux_dn_c = real2d_k("sw_clnclrsky_flux_dn_c" , 1, 1);
1273  sw_clnclrsky_flux_dn_dir_c = real2d_k("sw_clnclrsky_flux_dn_dir_c", 1, 1);
1274  lw_clnclrsky_flux_up_c = real2d_k("lw_clnclrsky_flux_up_c" , 1, 1);
1275  lw_clnclrsky_flux_dn_c = real2d_k("lw_clnclrsky_flux_dn_c" , 1, 1);
1276  }
1277 
1278  real2d_k sw_clnsky_flux_up_c, sw_clnsky_flux_dn_c, sw_clnsky_flux_dn_dir_c;
1279  real2d_k lw_clnsky_flux_up_c, lw_clnsky_flux_dn_c;
1280  if (m_extra_clnsky_diag) {
1281  sw_clnsky_flux_up_c = real2d_k(sw_clnsky_flux_up.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1282  sw_clnsky_flux_dn_c = real2d_k(sw_clnsky_flux_dn.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1283  sw_clnsky_flux_dn_dir_c = real2d_k(sw_clnsky_flux_dn_dir.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1284  lw_clnsky_flux_up_c = real2d_k(lw_clnsky_flux_up.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1285  lw_clnsky_flux_dn_c = real2d_k(lw_clnsky_flux_dn.data() + col_s*stride2_nlayp1, ncol_c, nlay+1);
1286  } else {
1287  sw_clnsky_flux_up_c = real2d_k("sw_clnsky_flux_up_c" , 1, 1);
1288  sw_clnsky_flux_dn_c = real2d_k("sw_clnsky_flux_dn_c" , 1, 1);
1289  sw_clnsky_flux_dn_dir_c = real2d_k("sw_clnsky_flux_dn_dir_c", 1, 1);
1290  lw_clnsky_flux_up_c = real2d_k("lw_clnsky_flux_up_c" , 1, 1);
1291  lw_clnsky_flux_dn_c = real2d_k("lw_clnsky_flux_dn_c" , 1, 1);
1292  }
1293 
1294  // --- Chunk subviews: 2D (ncol, nswbands) ---
1295  real2d_k sfc_alb_dir_c(sfc_alb_dir.data() + col_s*nswbands, ncol_c, nswbands);
1296  real2d_k sfc_alb_dif_c(sfc_alb_dif.data() + col_s*nswbands, ncol_c, nswbands);
1297 
1298  // --- Chunk subviews: 3D (ncol, nlay+1, nbands) ---
1299  // NOTE: Allocate these once on m_ncol_chunk and use what we need in the chunk loop
1300  real3d_k sw_bnd_flux_up_c (sw_bnd_flux_up.data() , ncol_c, nlay+1, nswbands);
1301  real3d_k sw_bnd_flux_dn_c (sw_bnd_flux_dn.data() , ncol_c, nlay+1, nswbands);
1302  real3d_k sw_bnd_flux_dir_c(sw_bnd_flux_dir.data(), ncol_c, nlay+1, nswbands);
1303  real3d_k sw_bnd_flux_dif_c(sw_bnd_flux_dif.data(), ncol_c, nlay+1, nswbands);
1304  real3d_k lw_bnd_flux_up_c (lw_bnd_flux_up.data() , ncol_c, nlay+1, m_nlwbands);
1305  real3d_k lw_bnd_flux_dn_c (lw_bnd_flux_dn.data() , ncol_c, nlay+1, m_nlwbands);
1306 
1307  // --- Create chunk gas concentrations by subsetting from pre-fetched VMR ---
1308  gas_concs_t gas_concs_c;
1309  gas_concs_c.init(gas_names_offset, ncol_c, nlay);
1310  for (int igas = 0; igas < m_ngas; ++igas) {
1311  real2d_k vmr_c("vmr_c", ncol_c, nlay);
1312  auto vmr_full = vmr_full_vec[igas];
1313  auto cs = col_s;
1314  Kokkos::parallel_for(Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {ncol_c, nlay}),
1315  KOKKOS_LAMBDA (int i, int j) {
1316  vmr_c(i, j) = vmr_full(cs + i, j);
1317  });
1318  gas_concs_c.set_vmr(m_gas_names[igas], vmr_c);
1319  }
1320 
1321  // Expand surface albedos along nswbands for this chunk
1323  sfc_alb_dir_vis_c, sfc_alb_dir_nir_c,
1324  sfc_alb_dif_vis_c, sfc_alb_dif_nir_c,
1325  sfc_alb_dir_c , sfc_alb_dif_c);
1326 
1327  // Run RRTMGP driver for this column chunk
1328  rrtmgp::rrtmgp_main(ncol_c, m_nlay,
1329  p_lay_c, t_lay_c,
1330  p_lev_c, t_lev_c,
1331  gas_concs_c,
1332  sfc_alb_dir_c, sfc_alb_dif_c, mu0_c,
1333  t_sfc_c, sfc_emis_c, lw_src_c,
1334  lwp_c, iwp_c, eff_radius_qc_c, eff_radius_qi_c, cldfrac_tot_c,
1335  sw_flux_up_c, sw_flux_dn_c, sw_flux_dn_dir_c,
1336  lw_flux_up_c, lw_flux_dn_c,
1337  sw_clnclrsky_flux_up_c, sw_clnclrsky_flux_dn_c, sw_clnclrsky_flux_dn_dir_c,
1338  sw_clrsky_flux_up_c, sw_clrsky_flux_dn_c, sw_clrsky_flux_dn_dir_c,
1339  sw_clnsky_flux_up_c, sw_clnsky_flux_dn_c, sw_clnsky_flux_dn_dir_c,
1340  lw_clnclrsky_flux_up_c, lw_clnclrsky_flux_dn_c,
1341  lw_clrsky_flux_up_c, lw_clrsky_flux_dn_c,
1342  lw_clnsky_flux_up_c, lw_clnsky_flux_dn_c,
1343  sw_bnd_flux_up_c, sw_bnd_flux_dn_c, sw_bnd_flux_dir_c,
1344  lw_bnd_flux_up_c, lw_bnd_flux_dn_c,
1346 
1347  // Compute heating rates for this chunk
1348  rrtmgp::compute_heating_rate(sw_flux_up_c, sw_flux_dn_c, r_lay_c, z_del_c, sw_heating_c);
1349  rrtmgp::compute_heating_rate(lw_flux_up_c, lw_flux_dn_c, r_lay_c, z_del_c, lw_heating_c);
1350 
1351  // Compute diffuse band fluxes and broadband surface fluxes for this chunk
1352  Kokkos::parallel_for(Kokkos::MDRangePolicy<Kokkos::Rank<3>>({0, 0, 0}, {ncol_c, nlay+1, nswbands}),
1353  KOKKOS_LAMBDA (int icol, int ilay, int ibnd)
1354  {
1355  sw_bnd_flux_dif_c(icol,ilay,ibnd) = sw_bnd_flux_dn_c(icol,ilay,ibnd) - sw_bnd_flux_dir_c(icol,ilay,ibnd);
1356  });
1357  rrtmgp::compute_broadband_surface_fluxes(ncol_c, kbot, nswbands,
1358  sw_bnd_flux_dir_c , sw_bnd_flux_dif_c ,
1359  sfc_flux_dir_vis_c, sfc_flux_dir_nir_c,
1360  sfc_flux_dif_vis_c, sfc_flux_dif_nir_c);
1361 
1362  gas_concs_c.reset();
1363  } // end column chunk loop
1364 }
static constexpr int ORB_UNDEF_INT
Definition: ERF_Constants.H:138
constexpr amrex::Real mwdair
Definition: ERF_Constants.H:107
constexpr amrex::Real PI
Definition: ERF_Constants.H:42
AMREX_GPU_HOST AMREX_FORCE_INLINE real orbital_cos_zenith(real &jday, real &lat, real &lon, real &declin, real dt_avg=-one, real uniform_angle=-one, real constant_zenith_angle_deg=-one)
Definition: ERF_OrbCosZenith.H:562
AMREX_GPU_HOST AMREX_FORCE_INLINE void orbital_decl(real &calday, real &eccen, real &mvelpp, real &lambm0, real &obliqr, real &delta, real &eccf)
Definition: ERF_OrbCosZenith.H:15
AMREX_GPU_HOST AMREX_FORCE_INLINE void orbital_params(int &iyear_AD, real &eccen, real &obliq, real &mvelp, real &obliqr, real &lambm0, real &mvelpp)
Definition: ERF_OrbCosZenith.H:81
std::string name
Definition: ERF_Plotfile2DCatalog.cpp:97
double m_dt
Definition: ERF_Radiation.H:229
real(c_double), private cs
Definition: ERF_module_mp_morr_two_moment.F90:203
void rrtmgp_main(const int ncol, const int nlay, real2d_k &p_lay, real2d_k &t_lay, real2d_k &p_lev, real2d_k &t_lev, gas_concs_t &gas_concs, real2d_k &sfc_alb_dir, real2d_k &sfc_alb_dif, real1d_k &mu0, real1d_k &t_sfc, real1d_k &sfc_emis, real1d_k &lw_src, real2d_k &lwp, real2d_k &iwp, real2d_k &rel, real2d_k &rei, real2d_k &cldfrac, real2d_k &sw_flux_up, real2d_k &sw_flux_dn, real2d_k &sw_flux_dn_dir, real2d_k &lw_flux_up, real2d_k &lw_flux_dn, real2d_k &sw_clnclrsky_flux_up, real2d_k &sw_clnclrsky_flux_dn, real2d_k &sw_clnclrsky_flux_dn_dir, real2d_k &sw_clrsky_flux_up, real2d_k &sw_clrsky_flux_dn, real2d_k &sw_clrsky_flux_dn_dir, real2d_k &sw_clnsky_flux_up, real2d_k &sw_clnsky_flux_dn, real2d_k &sw_clnsky_flux_dn_dir, real2d_k &lw_clnclrsky_flux_up, real2d_k &lw_clnclrsky_flux_dn, real2d_k &lw_clrsky_flux_up, real2d_k &lw_clrsky_flux_dn, real2d_k &lw_clnsky_flux_up, real2d_k &lw_clnsky_flux_dn, real3d_k &sw_bnd_flux_up, real3d_k &sw_bnd_flux_dn, real3d_k &sw_bnd_flux_dn_dir, real3d_k &lw_bnd_flux_up, real3d_k &lw_bnd_flux_dn, const RealT tsi_scaling, const bool extra_clnclrsky_diag, const bool extra_clnsky_diag)
Definition: ERF_RRTMGP_Interface.cpp:384
void compute_band_by_band_surface_albedos(const int ncol, const int nswbands, real1d_k &sfc_alb_dir_vis, real1d_k &sfc_alb_dir_nir, real1d_k &sfc_alb_dif_vis, real1d_k &sfc_alb_dif_nir, real2d_k &sfc_alb_dir, real2d_k &sfc_alb_dif)
Definition: ERF_RRTMGP_Interface.cpp:282
void compute_broadband_surface_fluxes(const int ncol, const int kbot, const int nswbands, real3d_k &sw_bnd_flux_dir, real3d_k &sw_bnd_flux_dif, real1d_k &sfc_flux_dir_vis, real1d_k &sfc_flux_dir_nir, real1d_k &sfc_flux_dif_vis, real1d_k &sfc_flux_dif_nir)
Definition: ERF_RRTMGP_Interface.cpp:326
void mixing_ratio_to_cloud_mass(View1 const &mixing_ratio, View2 const &cloud_fraction, View3 const &rho, View4 const &dz, View5 const &cloud_mass)
Definition: ERF_RRTMGP_Utils.H:12

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,
double &  time,
const double &  dt,
const amrex::BoxArray &  ba,
amrex::Geometry &  geom,
amrex::MultiFab *  cons_in,
amrex::iMultiFab *  lmask,
amrex::MultiFab *  t_surf,
amrex::Vector< amrex::MultiFab * > &  lsm_input_ptrs,
amrex::MultiFab *  qheating_rates,
amrex::MultiFab *  rad_fluxes,
amrex::MultiFab *  z_phys,
amrex::MultiFab *  lat,
amrex::MultiFab *  lon,
const bool  updated_lsm 
)
175 {
176  // Set data members that may change
177  m_lev = level;
178  m_step = step;
179  m_time = time;
180  m_dt = dt;
181  m_geom = geom;
182  m_cons_in = cons_in;
183  m_qheating_rates = qheating_rates;
184  m_rad_fluxes = rad_fluxes;
185  m_z_phys = z_phys;
186  m_lat = lat;
187  m_lon = lon;
188 
189  // Update the day and month
190  time_t timestamp = time_t(time);
191  struct tm *timeinfo = gmtime(&timestamp);
192  if (m_fixed_orbital_year) {
193  m_orbital_mon = timeinfo->tm_mon + 1;
194  m_orbital_day = timeinfo->tm_mday;
195  m_orbital_sec = timeinfo->tm_hour*3600 + timeinfo->tm_min*60 + timeinfo->tm_sec;
196  } else {
197  m_orbital_year = timeinfo->tm_year + 1900;
198  m_orbital_mon = timeinfo->tm_mon + 1;
199  m_orbital_day = timeinfo->tm_mday;
200  m_orbital_sec = timeinfo->tm_hour*3600 + timeinfo->tm_min*60 + timeinfo->tm_sec;
201  }
202 
203  // Only allocate and proceed if we are going to update radiation
204  m_update_rad = false;
205  if (m_rad_freq_in_steps > 0) { m_update_rad = ( (m_step == 0) || (m_step % m_rad_freq_in_steps == 0) || updated_lsm); }
206 
207  if (m_update_rad) {
208  // Call to Init() has set the dimensions: ncol & nlay
209 
210  // Allocate the buffer arrays
211  alloc_buffers();
212 
213  // Fill the KOKKOS Views from AMReX MFs
214  mf_to_kokkos_buffers(lmask, t_surf, lsm_input_ptrs);
215 
216  // Initialize datalog MF on first step
217  if (m_first_step) {
218  m_first_step = false;
219  if (datalog_int > 0) {
220  datalog_mf.define(cons_in->boxArray(), cons_in->DistributionMap(), 25, 0);
221  datalog_mf.setVal(0.0);
222  }
223  }
224  }
225 }
int m_step
Definition: ERF_Radiation.H:223
void mf_to_kokkos_buffers(amrex::iMultiFab *lmask, amrex::MultiFab *t_surf, amrex::Vector< amrex::MultiFab * > &lsm_input_ptrs)
Definition: ERF_Radiation.cpp:470
bool m_first_step
Definition: ERF_Radiation.H:243
void alloc_buffers()
Definition: ERF_Radiation.cpp:228
double m_time
Definition: ERF_Radiation.H:226

Referenced by Run().

Here is the caller graph for this function:

◆ write_rrtmgp_fluxes()

void Radiation::write_rrtmgp_fluxes ( )
764 {
765  Table2D<Real,Order::C> sw_flux_up_tab(sw_flux_up.data(), {0,0}, {static_cast<int>(sw_flux_up.extent(0)),static_cast<int>(sw_flux_up.extent(1))});
766  Table2D<Real,Order::C> sw_flux_dn_tab(sw_flux_dn.data(), {0,0}, {static_cast<int>(sw_flux_dn.extent(0)),static_cast<int>(sw_flux_dn.extent(1))});
767  Table2D<Real,Order::C> sw_flux_dn_dir_tab(sw_flux_dn_dir.data(), {0,0}, {static_cast<int>(sw_flux_dn_dir.extent(0)),static_cast<int>(sw_flux_dn_dir.extent(1))});
768  Table2D<Real,Order::C> lw_flux_up_tab(lw_flux_up.data(), {0,0}, {static_cast<int>(lw_flux_up.extent(0)),static_cast<int>(lw_flux_up.extent(1))});
769  Table2D<Real,Order::C> lw_flux_dn_tab(lw_flux_dn.data(), {0,0}, {static_cast<int>(lw_flux_dn.extent(0)),static_cast<int>(lw_flux_dn.extent(1))});
770 
771  int n_fluxes = 5;
772  MultiFab mf_flux(m_cons_in->boxArray(), m_cons_in->DistributionMap(), n_fluxes, 0);
773 
774  for (MFIter mfi(mf_flux); mfi.isValid(); ++mfi) {
775  const auto& vbx = mfi.validbox();
776  const int nx = vbx.length(0);
777  const int imin = vbx.smallEnd(0);
778  const int jmin = vbx.smallEnd(1);
779  const int offset = m_col_offsets[mfi.index()];
780  const Array4<Real>& dst_arr = mf_flux.array(mfi);
781  ParallelFor(vbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
782  {
783  // map [i,j,k] 0-based to [icol, ilay] 0-based
784  const int icol = (j-jmin)*nx + (i-imin) + offset;
785  const int ilay = k;
786 
787  // SW and LW fluxes
788  dst_arr(i,j,k,0) = sw_flux_up_tab(icol,ilay);
789  dst_arr(i,j,k,1) = sw_flux_dn_tab(icol,ilay);
790  dst_arr(i,j,k,2) = sw_flux_dn_dir_tab(icol,ilay);
791  dst_arr(i,j,k,3) = lw_flux_up_tab(icol,ilay);
792  dst_arr(i,j,k,4) = lw_flux_dn_tab(icol,ilay);
793  });
794  }
795 
796 
797  std::string plotfilename = amrex::Concatenate("plt_rad", m_step, 5);
798  Vector<std::string> flux_names = {"sw_flux_up", "sw_flux_dn", "sw_flux_dir",
799  "lw_flux_up", "lw_flux_dn"};
800  WriteSingleLevelPlotfile(plotfilename, mf_flux, flux_names, m_geom, static_cast<Real>(m_time), m_step);
801 }
Here is the call graph for this function:

◆ WriteDataLog()

void Radiation::WriteDataLog ( const double &  time)
overridevirtual

Implements IRadiation.

910 {
911  constexpr int datwidth = 14;
912  constexpr int datprecision = 9;
913  constexpr int timeprecision = 13;
914 
915  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;
916  // Clear sky
917  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;
918  // Clean sky
919  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;
920  // Clean clear sky
921  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;
922 
923 
924  auto domain = m_geom.Domain();
925  h_avg_radqrsw = sumToLine(datalog_mf, 0, 1, domain, 2);
926  h_avg_radqrlw = sumToLine(datalog_mf, 1, 1, domain, 2);
927  h_avg_sw_up = sumToLine(datalog_mf, 2, 1, domain, 2);
928  h_avg_sw_dn = sumToLine(datalog_mf, 3, 1, domain, 2);
929  h_avg_sw_dn_dir = sumToLine(datalog_mf, 4, 1, domain, 2);
930  h_avg_lw_up = sumToLine(datalog_mf, 5, 1, domain, 2);
931  h_avg_lw_dn = sumToLine(datalog_mf, 6, 1, domain, 2);
932  h_avg_zenith = sumToLine(datalog_mf, 7, 1, domain, 2);
933 
934  h_avg_radqrcsw = sumToLine(datalog_mf, 8, 1, domain, 2);
935  h_avg_radqrclw = sumToLine(datalog_mf, 9, 1, domain, 2);
936  h_avg_sw_clr_up = sumToLine(datalog_mf, 10, 1, domain, 2);
937  h_avg_sw_clr_dn = sumToLine(datalog_mf, 11, 1, domain, 2);
938  h_avg_sw_clr_dn_dir = sumToLine(datalog_mf, 12, 1, domain, 2);
939  h_avg_lw_clr_up = sumToLine(datalog_mf, 13, 1, domain, 2);
940  h_avg_lw_clr_dn = sumToLine(datalog_mf, 14, 1, domain, 2);
941 
942  if (m_extra_clnsky_diag) {
943  h_avg_sw_cln_up = sumToLine(datalog_mf, 15, 1, domain, 2);
944  h_avg_sw_cln_dn = sumToLine(datalog_mf, 16, 1, domain, 2);
945  h_avg_sw_cln_dn_dir = sumToLine(datalog_mf, 17, 1, domain, 2);
946  h_avg_lw_cln_up = sumToLine(datalog_mf, 18, 1, domain, 2);
947  h_avg_lw_cln_dn = sumToLine(datalog_mf, 19, 1, domain, 2);
948  }
949 
951  h_avg_sw_clnclr_up = sumToLine(datalog_mf, 20, 1, domain, 2);
952  h_avg_sw_clnclr_dn = sumToLine(datalog_mf, 21, 1, domain, 2);
953  h_avg_sw_clnclr_dn_dir = sumToLine(datalog_mf, 22, 1, domain, 2);
954  h_avg_lw_clnclr_up = sumToLine(datalog_mf, 23, 1, domain, 2);
955  h_avg_lw_clnclr_dn = sumToLine(datalog_mf, 24, 1, domain, 2);
956  }
957 
958  Real area_z = static_cast<Real>(domain.length(0)*domain.length(1));
959  int nz = domain.length(2);
960  for (int k = 0; k < nz; k++) {
961  h_avg_radqrsw[k] /= area_z;
962  h_avg_radqrlw[k] /= area_z;
963  h_avg_sw_up[k] /= area_z;
964  h_avg_sw_dn[k] /= area_z;
965  h_avg_sw_dn_dir[k] /= area_z;
966  h_avg_lw_up[k] /= area_z;
967  h_avg_lw_dn[k] /= area_z;
968  h_avg_zenith[k] /= area_z;
969 
970  h_avg_radqrcsw[k] /= area_z;
971  h_avg_radqrclw[k] /= area_z;
972  h_avg_sw_clr_up[k] /= area_z;
973  h_avg_sw_clr_dn[k] /= area_z;
974  h_avg_sw_clr_dn_dir[k] /= area_z;
975  h_avg_lw_clr_up[k] /= area_z;
976  h_avg_lw_clr_dn[k] /= area_z;
977  }
978 
979  if (m_extra_clnsky_diag) {
980  for (int k = 0; k < nz; k++) {
981  h_avg_sw_cln_up[k] /= area_z;
982  h_avg_sw_cln_dn[k] /= area_z;
983  h_avg_sw_cln_dn_dir[k] /= area_z;
984  h_avg_lw_cln_up[k] /= area_z;
985  h_avg_lw_cln_dn[k] /= area_z;
986  }
987  }
988 
990  for (int k = 0; k < nz; k++) {
991  h_avg_sw_clnclr_up[k] /= area_z;
992  h_avg_sw_clnclr_dn[k] /= area_z;
993  h_avg_sw_clnclr_dn_dir[k] /= area_z;
994  h_avg_lw_clnclr_up[k] /= area_z;
995  h_avg_lw_clnclr_dn[k] /= area_z;
996  }
997  }
998 
999  if (ParallelDescriptor::IOProcessor()) {
1000  std::ostream& log = *datalog;
1001  if (log.good()) {
1002 
1003  for (int k = 0; k < nz; k++)
1004  {
1005  Real z = k * m_geom.CellSize(2);
1006  log << std::setw(datwidth) << std::setprecision(timeprecision) << time << " "
1007  << std::setw(datwidth) << std::setprecision(datprecision) << z << " "
1008  << h_avg_radqrsw[k] << " " << h_avg_radqrlw[k] << " " << h_avg_sw_up[k] << " "
1009  << h_avg_sw_dn[k] << " " << h_avg_sw_dn_dir[k] << " " << h_avg_lw_up[k] << " "
1010  << h_avg_lw_dn[k] << " " << h_avg_zenith[k] << " "
1011  << h_avg_radqrcsw[k] << " " << h_avg_radqrclw[k] << " " << h_avg_sw_clr_up[k] << " "
1012  << h_avg_sw_clr_dn[k] << " " << h_avg_sw_clr_dn_dir[k] << " " << h_avg_lw_clr_up[k] << " "
1013  << h_avg_lw_clr_dn[k] << " ";
1014  if (m_extra_clnsky_diag) {
1015  log << h_avg_sw_cln_up[k] << " " << h_avg_sw_cln_dn[k] << " " << h_avg_sw_cln_dn_dir[k] << " "
1016  << h_avg_lw_cln_up[k] << " " << h_avg_lw_cln_dn[k] << " ";
1017  } else {
1018  log << zero << " " << zero << " " << zero << " " << zero << " " << zero << " ";
1019  }
1020 
1021  if (m_extra_clnclrsky_diag) {
1022  log << h_avg_sw_clnclr_up[k] << " " << h_avg_sw_clnclr_dn[k] << " " << h_avg_sw_clnclr_dn_dir[k] << " "
1023  << h_avg_lw_clnclr_up[k] << " " << h_avg_lw_clnclr_dn[k] << std::endl;
1024  } else {
1025  log << zero << " " << zero << " " << zero << " " << zero << " " << zero << std::endl;
1026  }
1027  }
1028  // Write top face values
1029  Real z = nz * m_geom.CellSize(2);
1030  log << std::setw(datwidth) << std::setprecision(timeprecision) << time << " "
1031  << std::setw(datwidth) << std::setprecision(datprecision) << z << " "
1032  << zero << " " << zero << " " << zero << " " << zero << " " << zero << " " << zero << " "
1033  << zero << " " << zero << " "
1034  << zero << " " << zero << " " << zero << " " << zero << " " << zero << " " << zero << " "
1035  << zero << " "
1036  << zero << " " << zero << " " << zero << " " << zero << " " << zero << " "
1037  << zero << " " << zero << " " << zero << " " << zero << " " << zero
1038  << std::endl;
1039  }
1040  }
1041 }
std::unique_ptr< std::fstream > datalog
Definition: ERF_RadiationInterface.H:86

Member Data Documentation

◆ aero_g_sw

real3d_k Radiation::aero_g_sw
private

◆ aero_ssa_sw

real3d_k Radiation::aero_ssa_sw
private

◆ aero_tau_lw

real3d_k Radiation::aero_tau_lw
private

◆ aero_tau_sw

real3d_k Radiation::aero_tau_sw
private

◆ cldfrac_tot

real2d_k Radiation::cldfrac_tot
private

◆ d_tint

real2d_k Radiation::d_tint
private

◆ datalog_mf

amrex::MultiFab Radiation::datalog_mf
private

◆ eff_radius_qc

real2d_k Radiation::eff_radius_qc
private

◆ eff_radius_qi

real2d_k Radiation::eff_radius_qi
private

◆ gas_names_offset

std::vector<std::string> Radiation::gas_names_offset
private

◆ iwp

real2d_k Radiation::iwp
private

◆ lat

real1d_k Radiation::lat
private

◆ lon

real1d_k Radiation::lon
private

◆ lw_bnd_flux_dn

real3d_k Radiation::lw_bnd_flux_dn
private

◆ lw_bnd_flux_up

real3d_k Radiation::lw_bnd_flux_up
private

◆ lw_clnclrsky_flux_dn

real2d_k Radiation::lw_clnclrsky_flux_dn
private

◆ lw_clnclrsky_flux_up

real2d_k Radiation::lw_clnclrsky_flux_up
private

◆ lw_clnsky_flux_dn

real2d_k Radiation::lw_clnsky_flux_dn
private

◆ lw_clnsky_flux_up

real2d_k Radiation::lw_clnsky_flux_up
private

◆ lw_clrsky_flux_dn

real2d_k Radiation::lw_clrsky_flux_dn
private

◆ lw_clrsky_flux_up

real2d_k Radiation::lw_clrsky_flux_up
private

◆ lw_clrsky_heating

real2d_k Radiation::lw_clrsky_heating
private

◆ lw_flux_dn

real2d_k Radiation::lw_flux_dn
private

◆ lw_flux_up

real2d_k Radiation::lw_flux_up
private

◆ lw_heating

real2d_k Radiation::lw_heating
private

◆ lw_src

real1d_k Radiation::lw_src
private

◆ lwp

real2d_k Radiation::lwp
private

◆ m_ba

amrex::BoxArray Radiation::m_ba
private

◆ m_ch4vmr

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

◆ m_co2vmr

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

◆ m_col_offsets

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

Referenced by Init().

◆ m_cons_in

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

◆ m_covmr

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

◆ m_do_aerosol_rad

bool Radiation::m_do_aerosol_rad = false
private

◆ m_do_subcol_sampling

bool Radiation::m_do_subcol_sampling = true
private

◆ m_dt

double 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 = -amrex::Real(9999.)
private

◆ m_fixed_total_solar_irradiance

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

◆ m_gas_concs

GasConcsK<amrex::Real, layout_t, KokkosDefaultDevice> Radiation::m_gas_concs
private

◆ m_gas_mol_weights

real1d_k 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 = amrex::Real(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 = -amrex::Real(98.555183)
private

◆ m_lsm

bool Radiation::m_lsm = false
private

◆ m_lsm_input_names

amrex::Vector<std::string> Radiation::m_lsm_input_names
private
Initial value:
= {"t_sfc" , "sfc_emis" ,
"sfc_alb_dir_vis", "sfc_alb_dir_nir",
"sfc_alb_dif_vis", "sfc_alb_dif_nir"}

Referenced by get_lsm_input_varnames().

◆ m_lsm_output_names

amrex::Vector<std::string> Radiation::m_lsm_output_names
private
Initial value:
= {"cos_zenith_angle" , "sw_flux_dn" ,
"sw_flux_dn_dir_vis", "sw_flux_dn_dir_nir",
"sw_flux_dn_dif_vis", "sw_flux_dn_dif_nir",
"lw_flux_dn"}

Referenced by get_lsm_output_varnames().

◆ 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:
= {amrex::Real(18.01528), amrex::Real(44.00950), amrex::Real(47.9982), amrex::Real(44.0128),
amrex::Real(28.01010), amrex::Real(16.04246), amrex::Real(31.9980), amrex::Real(28.0134)}

◆ m_n2ovmr

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

◆ m_n2vmr

amrex::Real Radiation::m_n2vmr = amrex::Real(0.7906)
private

◆ m_ncol

int Radiation::m_ncol
private

Referenced by Init().

◆ m_ncol_chunk

int Radiation::m_ncol_chunk = 1024
private

Referenced by Init().

◆ m_ngas

int Radiation::m_ngas = 8
private

◆ m_nlay

int Radiation::m_nlay
private

Referenced by Init().

◆ m_nlwbands

int Radiation::m_nlwbands
private

◆ m_nlwgpts

int Radiation::m_nlwgpts
private

◆ m_nswbands

int Radiation::m_nswbands
private

◆ m_nswgpts

int Radiation::m_nswgpts
private

◆ m_o2vmr

amrex::Real Radiation::m_o2vmr = amrex::Real(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

Referenced by rad_run_impl().

◆ m_orbital_eccen

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

◆ m_orbital_mon

int Radiation::m_orbital_mon = -9999
private

Referenced by rad_run_impl().

◆ m_orbital_mvelp

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

◆ m_orbital_obliq

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

◆ m_orbital_sec

int Radiation::m_orbital_sec = -9999
private

Referenced by rad_run_impl().

◆ m_orbital_year

int Radiation::m_orbital_year = -9999
private

Referenced by rad_run_impl().

◆ m_qheating_rates

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

◆ m_rad_fluxes

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

◆ m_rad_freq_in_steps

int Radiation::m_rad_freq_in_steps = 1
private

◆ m_rad_nvar

int Radiation::m_rad_nvar = 12
private

◆ m_rad_t_sfc

amrex::Real Radiation::m_rad_t_sfc = -1
private

◆ m_rad_write_fluxes

bool Radiation::m_rad_write_fluxes = false
private

◆ m_step

int Radiation::m_step
private

◆ m_time

double Radiation::m_time
private

◆ m_update_rad

bool Radiation::m_update_rad = false
private

Referenced by rad_run_impl().

◆ m_z_phys

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

◆ mu0

real1d_k Radiation::mu0
private

◆ o3_lay

real1d_k Radiation::o3_lay
private

◆ p_lay

real2d_k Radiation::p_lay
private

◆ p_lev

real2d_k Radiation::p_lev
private

◆ qc_lay

real2d_k Radiation::qc_lay
private

◆ qi_lay

real2d_k Radiation::qi_lay
private

◆ qv_lay

real2d_k Radiation::qv_lay
private

◆ r_lay

real2d_k 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-g256-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_k Radiation::sfc_alb_dif
private

◆ sfc_alb_dif_nir

real1d_k Radiation::sfc_alb_dif_nir
private

◆ sfc_alb_dif_vis

real1d_k Radiation::sfc_alb_dif_vis
private

◆ sfc_alb_dir

real2d_k Radiation::sfc_alb_dir
private

◆ sfc_alb_dir_nir

real1d_k Radiation::sfc_alb_dir_nir
private

◆ sfc_alb_dir_vis

real1d_k Radiation::sfc_alb_dir_vis
private

◆ sfc_emis

real1d_k Radiation::sfc_emis
private

◆ sfc_flux_dif_nir

real1d_k Radiation::sfc_flux_dif_nir
private

◆ sfc_flux_dif_vis

real1d_k Radiation::sfc_flux_dif_vis
private

◆ sfc_flux_dir_nir

real1d_k Radiation::sfc_flux_dir_nir
private

◆ sfc_flux_dir_vis

real1d_k Radiation::sfc_flux_dir_vis
private

◆ sw_bnd_flux_dif

real3d_k Radiation::sw_bnd_flux_dif
private

◆ sw_bnd_flux_dir

real3d_k Radiation::sw_bnd_flux_dir
private

◆ sw_bnd_flux_dn

real3d_k Radiation::sw_bnd_flux_dn
private

◆ sw_bnd_flux_up

real3d_k Radiation::sw_bnd_flux_up
private

◆ sw_clnclrsky_flux_dn

real2d_k Radiation::sw_clnclrsky_flux_dn
private

◆ sw_clnclrsky_flux_dn_dir

real2d_k Radiation::sw_clnclrsky_flux_dn_dir
private

◆ sw_clnclrsky_flux_up

real2d_k Radiation::sw_clnclrsky_flux_up
private

◆ sw_clnsky_flux_dn

real2d_k Radiation::sw_clnsky_flux_dn
private

◆ sw_clnsky_flux_dn_dir

real2d_k Radiation::sw_clnsky_flux_dn_dir
private

◆ sw_clnsky_flux_up

real2d_k Radiation::sw_clnsky_flux_up
private

◆ sw_clrsky_flux_dn

real2d_k Radiation::sw_clrsky_flux_dn
private

◆ sw_clrsky_flux_dn_dir

real2d_k Radiation::sw_clrsky_flux_dn_dir
private

◆ sw_clrsky_flux_up

real2d_k Radiation::sw_clrsky_flux_up
private

◆ sw_clrsky_heating

real2d_k Radiation::sw_clrsky_heating
private

◆ sw_flux_dn

real2d_k Radiation::sw_flux_dn
private

◆ sw_flux_dn_dir

real2d_k Radiation::sw_flux_dn_dir
private

◆ sw_flux_up

real2d_k Radiation::sw_flux_up
private

◆ sw_heating

real2d_k Radiation::sw_heating
private

◆ t_lay

real2d_k Radiation::t_lay
private

◆ t_lev

real2d_k Radiation::t_lev
private

◆ t_sfc

real1d_k Radiation::t_sfc
private

◆ z_del

real2d_k Radiation::z_del
private

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