REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_Coupling.cpp
Go to the documentation of this file.
1#include <REMORA.H>
2
3#include <AMReX_BCRec.H>
4#include <AMReX_Box.H>
5#include <AMReX_FillPatchUtil.H>
6#include <AMReX_Geometry.H>
7#include <AMReX_Interpolater.H>
8#include <AMReX_MFIter.H>
9#include <AMReX_MultiFabUtil.H>
10#include <AMReX_Print.H>
11
12using namespace amrex;
13
14/*
15 Coupling reference context (implementation-side):
16
17 1) Legacy state-passing contract:
18 Warner et al. (2010), COAWST, Fig. 5 / Block B.
19 REMORA receives atmospheric states and computes surface fluxes internally
20 (bulk-physics/COARE-style path).
21
22 2) Future direct flux-passing roadmap:
23 COAWST's ATM2OCN_FLUXES pathway (documented in COAWST manuals/workshops
24 and exercised in Zambon et al., 2014) motivates direct flux exchange
25 (tau_x, tau_y, heat/moisture) instead of state-only exchange.
26 COAWST code anchors:
27 - Master/mct_roms_wrf.h
28 - ROMS/Nonlinear/atm2ocn_flux.F
29 - ROMS/Nonlinear/bulk_flux.F
30*/
31
32namespace {
33constexpr int SSTIndex = 0;
34
35Geometry
36make_unit_slab_geometry (Box const& domain)
37{
38 static constexpr Real lo[AMREX_SPACEDIM] = {0.0_rt, 0.0_rt, 0.0_rt};
39 static constexpr Real hi[AMREX_SPACEDIM] = {1.0_rt, 1.0_rt, 1.0_rt};
40 static constexpr int periodicity[AMREX_SPACEDIM] = {0, 0, 0};
41 RealBox rb(lo, hi);
42 return Geometry(domain, &rb, CoordSys::cartesian, periodicity);
43}
44
45Vector<BCRec>
46make_internal_bcs (int ncomp)
47{
48 Vector<BCRec> bcs(ncomp);
49 for (auto& bc : bcs) {
50 for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
51 bc.setLo(dir, BCType::int_dir);
52 bc.setHi(dir, BCType::int_dir);
53 }
54 }
55 return bcs;
56}
57}
58
59amrex::Real
60REMORA::EvolveOneStep (amrex::Real /*time*/, amrex::Real /*dt_request*/)
61{
62 Real cur_time = t_new[0];
63 const int step = istep[0];
64
65 if (cur_time >= stop_time) {
66 return Real(0.0);
67 }
68
69 ComputeDt();
70
71 int lev = 0;
72 int iteration = 1;
73 if (max_level == 0) {
74 timeStep(lev, cur_time, iteration);
75 } else {
76 timeStepML(cur_time, iteration);
77 }
78
79 cur_time += dt[0];
80
81 WriteAtIntermediateTime(step, cur_time);
82
83 post_timestep(step, cur_time, dt[0]);
84
85 return dt[0];
86}
87
88/*
89 * \brief Extracts SST from the 3D conservative state for the atmospheric driver.
90 *
91 * Reads Temp_comp at the top water-column cell (k_sfc), converts from
92 * Celsius to Kelvin, and copies the result into state[SSTIndex].
93 *
94 * @param[in,out] state OCN2ATM slab buffer sized by the driver (one MultiFab
95 * per ocean-to-atmosphere export layer). state[SSTIndex]
96 * (index 0) is overwritten with sea-surface temperature
97 * (SST) sampled from the Temp_comp tracer at the uppermost
98 * sigma level (k = Nz) and converted from degrees Celsius
99 * to Kelvin for the atmospheric driver. An empty vector or
100 * null state[0] is treated as a no-op.
101 * @param[in ] time Current ocean model time (unused; retained for driver
102 * interface conformance).
103 */
104void
105REMORA::PackSurfaceState (Vector<MultiFab*>& state, Real /*time*/)
106{
107 if (state.empty() || state[SSTIndex] == nullptr) { return; }
108 const int lev = 0;
109
110 // REMORA stores temperature in Celsius. Surface is at k=N (top of water column).
111 const int k_sfc = cons_new[lev]->boxArray().minimalBox().bigEnd(2);
112
113 // Build a temp MultiFab on REMORA's ba2d (k=0) derived from cons_new's BoxArray.
114 // Same DistributionMap ensures each box is local; we fill at k=0 from cons at k=k_sfc.
115 BoxList bl2d = cons_new[lev]->boxArray().boxList();
116 for (auto& b : bl2d) { b.setRange(2, 0); }
117 BoxArray ba2d(std::move(bl2d));
118 MultiFab tmp(ba2d, cons_new[lev]->DistributionMap(), 1, 0);
119
120 for (MFIter mfi(*cons_new[lev]); mfi.isValid(); ++mfi) {
121 auto const& c = cons_new[lev]->const_array(mfi);
122 auto t = tmp.array(mfi);
123 Box bx = makeSlab(mfi.validbox(), 2, k_sfc);
124 ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int) {
125 // Write to k=0 in tmp (ba2d range); convert Celsius → Kelvin.
126 t(i, j, 0) = c(i, j, k_sfc, Temp_comp) + 273.15_rt;
127 });
128 }
129
130 MultiFab& dst = *state[SSTIndex];
131 const Box src_domain = tmp.boxArray().minimalBox();
132 const Box dst_domain = dst.boxArray().minimalBox();
133
134 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
135 src_domain.smallEnd(2) == src_domain.bigEnd(2) &&
136 dst_domain.smallEnd(2) == dst_domain.bigEnd(2),
137 "REMORA::PackSurfaceState expects 2D slab source and destination MultiFabs.");
138 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
139 src_domain.smallEnd(0) == dst_domain.smallEnd(0) &&
140 src_domain.smallEnd(1) == dst_domain.smallEnd(1),
141 "REMORA::PackSurfaceState requires aligned atmosphere/ocean slab origins.");
142
143 const IntVect src_len = src_domain.length();
144 const IntVect dst_len = dst_domain.length();
145 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
146 src_len[2] == 1 && dst_len[2] == 1,
147 "REMORA::PackSurfaceState expects unit-thickness source and destination slabs.");
148
149 const bool same_xy = (src_len[0] == dst_len[0] && src_len[1] == dst_len[1]);
150 const bool dst_finer =
151 (dst_len[0] >= src_len[0] && dst_len[1] >= src_len[1] &&
152 dst_len[0] % src_len[0] == 0 && dst_len[1] % src_len[1] == 0);
153 const bool dst_coarser =
154 (src_len[0] >= dst_len[0] && src_len[1] >= dst_len[1] &&
155 src_len[0] % dst_len[0] == 0 && src_len[1] % dst_len[1] == 0);
156
157 if (same_xy) {
158 dst.ParallelCopy(tmp, 0, 0, 1);
159 return;
160 }
161
162 if (dst_finer) {
163 const IntVect ratio(dst_len[0] / src_len[0], dst_len[1] / src_len[1], 1);
164 const auto src_geom = make_unit_slab_geometry(src_domain);
165 const auto dst_geom = make_unit_slab_geometry(dst_domain);
166 const auto bcs = make_internal_bcs(1);
167 amrex::InterpFromCoarseLevel(dst, IntVect(0), IntVect(0),
168 tmp, 0, 0, 1,
169 src_geom, dst_geom,
170 ratio, &pc_interp, bcs, 0);
171 return;
172 }
173
174 if (dst_coarser) {
175 const IntVect ratio(src_len[0] / dst_len[0], src_len[1] / dst_len[1], 1);
176 amrex::average_down(tmp, dst, 0, 1, ratio);
177 return;
178 }
179
180 amrex::Abort("REMORA::PackSurfaceState requires matching horizontal extents and integer-ratio atmosphere/ocean slab resolutions.");
181}
182
183/*
184 * \brief Receives atmospheric states from the driver and applies unit conversions.
185 *
186 * Fills REMORA's internal forcing MultiFabs from states and records which
187 * lanes were successfully updated in driver_atmos_state_from_driver.
188 * Unit conversions applied: Pair Pa to mb; Tair K to Celsius.
189 *
190 * @param[in] states ATM2OCN forcing slab buffer from the driver (Warner et al.
191 * 2010, Block B state-passing contract), indexed by AtmosState.
192 * Expected units per lane:
193 * Uwind/Vwind: 10-m winds [m/s];
194 * Pair: mean sea-level pressure [Pa, converted to mb];
195 * Qair: near-surface specific humidity [kg/kg];
196 * Tair: 2-m air temperature [K, converted to degC];
197 * Cloud: cloud fraction [0-1];
198 * Rain: precipitation rate [kg/m^2/s];
199 * SWrad/LWrad: downwelling shortwave/longwave radiation [W/m^2].
200 * Missing lanes (null pointer or index out of range) are skipped;
201 * driver_atmos_state_from_driver tracks populated lanes for the
202 * bulk-flux parameterization fallback logic.
203 * @param[in] time Current ocean model time (unused; retained for driver
204 * interface conformance).
205 */
206void
207REMORA::ApplyAtmosphericStates (const Vector<MultiFab*>& states, Real /*time*/)
208{
210 if (finest_level < 0) { return; }
211
212 // Wind (m/s) — no unit conversion
213 if (vec_uwind[0] != nullptr) {
214 if (states.size() > AtmosState::Uwind && states[AtmosState::Uwind] != nullptr) {
215 vec_uwind[0]->ParallelCopy(*states[AtmosState::Uwind], 0, 0, 1);
216 vec_uwind[0]->FillBoundary(geom[0].periodicity());
218 }
219 }
220 if (vec_vwind[0] != nullptr) {
221 if (states.size() > AtmosState::Vwind && states[AtmosState::Vwind] != nullptr) {
222 vec_vwind[0]->ParallelCopy(*states[AtmosState::Vwind], 0, 0, 1);
223 vec_vwind[0]->FillBoundary(geom[0].periodicity());
225 }
226 }
227
228 // Atmospheric pressure: Pa → mb (REMORA bulk flux expects mb)
229 if (vec_Pair[0] != nullptr) {
230 if (states.size() > AtmosState::Pair && states[AtmosState::Pair] != nullptr) {
231 vec_Pair[0]->ParallelCopy(*states[AtmosState::Pair], 0, 0, 1);
232 vec_Pair[0]->mult(0.01_rt, 0, 1);
233 vec_Pair[0]->FillBoundary(geom[0].periodicity());
235 }
236 }
237
238 // Specific humidity (kg/kg) — no conversion
239 if (vec_qair[0] != nullptr) {
240 if (states.size() > AtmosState::Qair && states[AtmosState::Qair] != nullptr) {
241 vec_qair[0]->ParallelCopy(*states[AtmosState::Qair], 0, 0, 1);
242 vec_qair[0]->FillBoundary(geom[0].periodicity());
244 }
245 }
246
247 // Air temperature: K → °C (REMORA stores/uses Celsius internally)
248 if (vec_Tair[0] != nullptr) {
249 if (states.size() > AtmosState::Tair && states[AtmosState::Tair] != nullptr) {
250 vec_Tair[0]->ParallelCopy(*states[AtmosState::Tair], 0, 0, 1);
251 vec_Tair[0]->plus(-273.15_rt, 0, 1);
252 vec_Tair[0]->FillBoundary(geom[0].periodicity());
254 }
255 }
256
257 // Cloud fraction [0-1], rain, SW/LW radiation — no unit conversion
258 if (vec_cloud[0] != nullptr) {
259 if (states.size() > AtmosState::Cloud && states[AtmosState::Cloud] != nullptr) {
260 vec_cloud[0]->ParallelCopy(*states[AtmosState::Cloud], 0, 0, 1);
261 vec_cloud[0]->FillBoundary(geom[0].periodicity());
263 }
264 }
265 if (vec_rain[0] != nullptr) {
266 if (states.size() > AtmosState::Rain && states[AtmosState::Rain] != nullptr) {
267 vec_rain[0]->ParallelCopy(*states[AtmosState::Rain], 0, 0, 1);
268 vec_rain[0]->FillBoundary(geom[0].periodicity());
270 }
271 }
272 if (vec_srflx[0] != nullptr) {
273 if (states.size() > AtmosState::SWrad && states[AtmosState::SWrad] != nullptr) {
274 vec_srflx[0]->ParallelCopy(*states[AtmosState::SWrad], 0, 0, 1);
275 vec_srflx[0]->FillBoundary(geom[0].periodicity());
277 }
278 }
279 if (vec_longwave_down[0] != nullptr) {
280 if (states.size() > AtmosState::LWrad && states[AtmosState::LWrad] != nullptr) {
281 vec_longwave_down[0]->ParallelCopy(*states[AtmosState::LWrad], 0, 0, 1);
282 vec_longwave_down[0]->FillBoundary(geom[0].periodicity());
284 }
285 }
286
287}
288
289void
290REMORA::ApplyAtmosphericFluxes (const Vector<MultiFab*>& states, Real /*time*/)
291{
293 if (finest_level < 0) { return; }
294
295 if (states.size() <= AtmosFluxes::Evap ||
296 states[AtmosFluxes::TauX] == nullptr ||
297 states[AtmosFluxes::TauY] == nullptr ||
298 states[AtmosFluxes::SHflux] == nullptr ||
299 states[AtmosFluxes::LHflux] == nullptr ||
300 states[AtmosFluxes::SWrad] == nullptr ||
301 states[AtmosFluxes::LWrad] == nullptr ||
302 states[AtmosFluxes::Rain] == nullptr ||
303 states[AtmosFluxes::Evap] == nullptr ||
304 vec_sustr[0] == nullptr || vec_svstr[0] == nullptr ||
305 vec_stflux[0] == nullptr || vec_mskr[0] == nullptr ||
306 vec_msku[0] == nullptr || vec_mskv[0] == nullptr ||
307 vec_srflx[0] == nullptr || vec_lrflx[0] == nullptr ||
308 vec_lhflx[0] == nullptr || vec_shflx[0] == nullptr ||
309 vec_rain[0] == nullptr || vec_evap[0] == nullptr) {
310 return;
311 }
312
313 const Real Hscale2 = 1.0_rt / (solverChoice.rho0 * Cp);
314
315 vec_srflx[0]->ParallelCopy(*states[AtmosFluxes::SWrad], 0, 0, 1);
316 vec_rain[0]->ParallelCopy(*states[AtmosFluxes::Rain], 0, 0, 1);
317 vec_evap[0]->ParallelCopy(*states[AtmosFluxes::Evap], 0, 0, 1);
318
319 for (MFIter mfi(*vec_stflux[0], TilingIfNotGPU()); mfi.isValid(); ++mfi) {
320 Array4<Real> const& stflux = vec_stflux[0]->array(mfi);
321 Array4<Real> const& sustr = vec_sustr[0]->array(mfi);
322 Array4<Real> const& svstr = vec_svstr[0]->array(mfi);
323 Array4<Real> const& lrflx = vec_lrflx[0]->array(mfi);
324 Array4<Real> const& lhflx = vec_lhflx[0]->array(mfi);
325 Array4<Real> const& shflx = vec_shflx[0]->array(mfi);
326 Array4<const Real> const& mskr = vec_mskr[0]->const_array(mfi);
327 Array4<const Real> const& msku = vec_msku[0]->const_array(mfi);
328 Array4<const Real> const& mskv = vec_mskv[0]->const_array(mfi);
329 Array4<const Real> const& srflx = vec_srflx[0]->const_array(mfi);
330 Array4<const Real> const& rain = vec_rain[0]->const_array(mfi);
331 Array4<const Real> const& evap = vec_evap[0]->const_array(mfi);
332 Array4<const Real> const& tau_x = states[AtmosFluxes::TauX]->const_array(mfi);
333 Array4<const Real> const& tau_y = states[AtmosFluxes::TauY]->const_array(mfi);
334 Array4<const Real> const& shflux = states[AtmosFluxes::SHflux]->const_array(mfi);
335 Array4<const Real> const& lhflux = states[AtmosFluxes::LHflux]->const_array(mfi);
336 Array4<const Real> const& lwflux = states[AtmosFluxes::LWrad]->const_array(mfi);
337
338 Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
339 Box gbx2D = gbx2;
340 gbx2D.makeSlab(2,0);
341 Box ubx = mfi.grownnodaltilebox(0, IntVect(NGROW,NGROW,0));
342 Box ubxD = ubx;
343 ubxD.makeSlab(2,0);
344 Box vbx = mfi.grownnodaltilebox(1, IntVect(NGROW,NGROW,0));
345 Box vbxD = vbx;
346 vbxD.makeSlab(2,0);
347
348 ParallelFor(ubxD, [=] AMREX_GPU_DEVICE (int i, int j, int ) {
349 sustr(i,j,0) = Real(0.5) / solverChoice.rho0
350 * (tau_x(i-1,j,0) + tau_x(i,j,0))
351 * msku(i,j,0);
352 });
353
354 ParallelFor(vbxD, [=] AMREX_GPU_DEVICE (int i, int j, int ) {
355 svstr(i,j,0) = Real(0.5) / solverChoice.rho0
356 * (tau_y(i,j-1,0) + tau_y(i,j,0))
357 * mskv(i,j,0);
358 });
359
360 ParallelFor(gbx2D, [=] AMREX_GPU_DEVICE (int i, int j, int ) {
361 // ERF exports flux lanes in native surface-flux units; convert once at ingest.
362 lrflx(i,j,0) = lwflux(i,j,0) * Hscale2;
363 lhflx(i,j,0) = -lhflux(i,j,0) * Hscale2;
364 shflx(i,j,0) = -shflux(i,j,0) * Hscale2;
365 stflux(i,j,0,Temp_comp) =
366 (srflx(i,j,0) * Hscale2 + lrflx(i,j,0) + lhflx(i,j,0) + shflx(i,j,0))
367 * mskr(i,j,0);
368 stflux(i,j,0,Salt_comp) =
369 mskr(i,j,0) * (evap(i,j,0) - rain(i,j,0)) / rhow;
370 });
371 }
372
373 vec_sustr[0]->FillBoundary(geom[0].periodicity());
374 vec_svstr[0]->FillBoundary(geom[0].periodicity());
375 vec_srflx[0]->FillBoundary(geom[0].periodicity());
376 vec_lrflx[0]->FillBoundary(geom[0].periodicity());
377 vec_lhflx[0]->FillBoundary(geom[0].periodicity());
378 vec_shflx[0]->FillBoundary(geom[0].periodicity());
379 vec_stflux[0]->FillBoundary(geom[0].periodicity());
380 vec_rain[0]->FillBoundary(geom[0].periodicity());
381 vec_evap[0]->FillBoundary(geom[0].periodicity());
382 vec_stflux[0]->FillBoundary(geom[0].periodicity());
383
384 if (amrex::ParallelDescriptor::IOProcessor()) {
385 amrex::Print() << "REMORA ApplyAtmosphericFluxes validation:\n"
386 << " sustr: min=" << vec_sustr[0]->min(0) << " max=" << vec_sustr[0]->max(0) << "\n"
387 << " svstr: min=" << vec_svstr[0]->min(0) << " max=" << vec_svstr[0]->max(0) << "\n"
388 << " stflux(Temp): min=" << vec_stflux[0]->min(Temp_comp) << " max=" << vec_stflux[0]->max(Temp_comp) << "\n"
389 << " stflux(Salt): min=" << vec_stflux[0]->min(Salt_comp) << " max=" << vec_stflux[0]->max(Salt_comp) << "\n"
390 << " srflx: min=" << vec_srflx[0]->min(0) << " max=" << vec_srflx[0]->max(0) << "\n"
391 << " lrflx: min=" << vec_lrflx[0]->min(0) << " max=" << vec_lrflx[0]->max(0) << "\n"
392 << " lhflx: min=" << vec_lhflx[0]->min(0) << " max=" << vec_lhflx[0]->max(0) << "\n"
393 << " shflx: min=" << vec_shflx[0]->min(0) << " max=" << vec_shflx[0]->max(0) << "\n";
394 }
395}
constexpr amrex::Real rhow
constexpr amrex::Real Cp
#define NGROW
#define Temp_comp
#define Salt_comp
void PackSurfaceState(amrex::Vector< amrex::MultiFab * > &state, amrex::Real time)
Extracts SST from the 3D conservative state for the atmospheric driver.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_evap
evaporation rate [kg/m^2/s]
Definition REMORA.H:434
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_lrflx
longwave radiation
Definition REMORA.H:414
amrex::Vector< amrex::MultiFab * > cons_new
multilevel data container for current step's scalar data: temperature, salinity, passive tracer
Definition REMORA.H:315
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_vwind
Wind in the v direction, defined at rho-points.
Definition REMORA.H:403
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskr
land/sea mask at cell centers (2D)
Definition REMORA.H:480
amrex::Real stop_time
Time to stop.
Definition REMORA.H:1469
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rain
precipitation rate [kg/m^2/s]
Definition REMORA.H:432
void ApplyAtmosphericFluxes(const amrex::Vector< amrex::MultiFab * > &states, amrex::Real time)
Receives atmospheric flux lanes from the driver and assembles REMORA flux inputs.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_sustr
Surface stress in the u direction.
Definition REMORA.H:396
void WriteAtIntermediateTime(int step, amrex::Real cur_time)
Write checkpoint and plotfiles at intermediate point of simulation, if needed.
Definition REMORA.cpp:319
amrex::Real EvolveOneStep(amrex::Real time, amrex::Real dt_request)
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_msku
land/sea mask at x-faces (2D)
Definition REMORA.H:482
std::array< bool, AtmosState::NumTypes > driver_atmos_state_from_driver
provenance flags for driver-supplied atmospheric forcing lanes
Definition REMORA.H:441
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_uwind
Wind in the u direction, defined at rho-points.
Definition REMORA.H:401
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_shflx
sensible heat flux
Definition REMORA.H:420
void post_timestep(int nstep, amrex::Real time, amrex::Real dt_lev)
Called after every level 0 timestep.
Definition REMORA.cpp:344
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_lhflx
latent heat flux
Definition REMORA.H:418
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskv
land/sea mask at y-faces (2D)
Definition REMORA.H:484
void ComputeDt()
a wrapper for estTimeStep()
amrex::Vector< int > istep
which step?
Definition REMORA.H:1403
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_svstr
Surface stress in the v direction.
Definition REMORA.H:398
amrex::Vector< amrex::Real > t_new
new time at each level
Definition REMORA.H:1407
static SolverChoice solverChoice
Container for algorithmic choices.
Definition REMORA.H:1537
void ApplyAtmosphericStates(const amrex::Vector< amrex::MultiFab * > &states, amrex::Real time)
Receives atmospheric states from the driver and applies unit conversions.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_longwave_down
Downward longwave radiation.
Definition REMORA.H:416
void timeStep(int lev, amrex::Real time, int iteration)
advance a level by dt, includes a recursive call for finer levels
void timeStepML(amrex::Real time, int iteration)
advance all levels by dt, loops over finer levels
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_stflux
Surface tracer flux; input arrays.
Definition REMORA.H:425
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_cloud
cloud cover fraction [0-1], defined at rho-points
Definition REMORA.H:436
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_srflx
Shortwave radiation flux [W/m²], defined at rho-points.
Definition REMORA.H:412
amrex::Vector< amrex::Real > dt
time step at each level
Definition REMORA.H:1411
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Pair
Air pressure [mb], defined at rho-points.
Definition REMORA.H:409
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_qair
Specific humidity [kg/kg], defined at rho-points.
Definition REMORA.H:407
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Tair
Air temperature [°C], defined at rho-points.
Definition REMORA.H:405
@ LWrad
longwave flux lane
@ LHflux
latent heat flux lane
@ Rain
precipitation rate lane
@ Evap
evaporation rate lane
@ SHflux
sensible heat flux lane
@ TauX
surface zonal stress lane
@ TauY
surface meridional stress lane
@ SWrad
shortwave radiation lane
@ Pair
atmospheric pressure [Pa from driver, mb in REMORA]
@ Vwind
10-m meridional wind [m/s]
@ Qair
specific humidity [kg/kg]
@ SWrad
downward shortwave radiation [W/m^2]
@ LWrad
downward longwave radiation [W/m^2]
@ Uwind
10-m zonal wind [m/s]
@ Rain
precipitation rate [kg/m^2/s]
@ Cloud
cloud fraction [0-1]
@ Tair
air temperature [K from driver, degC in REMORA]