17#include <AMReX_MultiFab.H>
32int fidx (
int i,
int j,
int k,
int n,
33 int ilo,
int jlo,
int ni,
int nj,
int nk)
noexcept
35 return ((n * nk + k) * nj + (j - jlo)) * ni + (i - ilo);
41REMORA::advance_biology_fortran (
int lev, MultiFab
const& mf_cons_old,
42 MultiFab& mf_cons_new,
46 amrex::ignore_unused(lev, mf_cons_old, mf_cons_new, N, dt_lev);
47 amrex::Abort(
"Fennel Fortran bridge is host-only. Serial-first acceptance "
48 "is the default validation scope; GPU parity is a separate "
49 "lane and is not opened by this campaign.");
54 const bool need_gas = parms.
oxygen || parms.carbon;
60 (need_gas && do_bulk_flux &&
62 (need_gas && !do_bulk_flux &&
64 amrex::Abort(
"Fennel Fortran bridge requires Hz, z_r, z_w, rmask, "
65 "srflx, and, when carbon or oxygen is active, either "
66 "uwind/vwind (bulk_fluxes) or sustr/svstr");
77 const int ntrc =
nbt + 2;
80 auto cons_comp_for_slot = [l_bio_comp] (
int slot)
noexcept {
89 const Real srflx_to_roms_kinematic =
92 for (MFIter mfi(mf_cons_new,
false); mfi.isValid(); ++mfi) {
93 const Box bx = mfi.validbox();
95 const int ilo = bx.smallEnd(0);
96 const int ihi = bx.bigEnd(0);
97 const int jlo = bx.smallEnd(1);
98 const int jhi = bx.bigEnd(1);
100 const int ni = ihi - ilo + 1;
101 const int nj = jhi - jlo + 1;
105 const int nis = ni + 1;
106 const int njs = nj + 1;
108 Array4<Real const>
const& state_old = mf_cons_old.const_array(mfi);
109 Array4<Real const>
const& state_new = mf_cons_new.const_array(mfi);
110 Array4<Real>
const& state_out = mf_cons_new.array(mfi);
111 Array4<Real const>
const& Hz_a =
vec_Hz[lev]->const_array(mfi);
112 Array4<Real const>
const& z_r_a =
vec_z_r[lev]->const_array(mfi);
113 Array4<Real const>
const& z_w_a =
vec_z_w[lev]->const_array(mfi);
114 Array4<Real const>
const& srflx_a =
vec_srflx[lev]->const_array(mfi);
115 Array4<Real const>
const& mskr_a =
vec_mskr[lev]->const_array(mfi);
117 Array4<Real const> sustr_a;
118 Array4<Real const> svstr_a;
119 Array4<Real const> uwind_a;
120 Array4<Real const> vwind_a;
123 uwind_a =
vec_uwind[lev]->const_array(mfi);
124 vwind_a =
vec_vwind[lev]->const_array(mfi);
126 sustr_a =
vec_sustr[lev]->const_array(mfi);
127 svstr_a =
vec_svstr[lev]->const_array(mfi);
131 Vector<double> b_rmask(std::size_t(ni) * nj, 0.0);
132 Vector<double> b_srflx(std::size_t(ni) * nj, 0.0);
133 Vector<double> b_pH (std::size_t(ni) * nj, 0.0);
134 Vector<double> b_Hz (std::size_t(ni) * nj * nz, 0.0);
135 Vector<double> b_z_r (std::size_t(ni) * nj * nz, 0.0);
136 Vector<double> b_z_w (std::size_t(ni) * nj * (nz + 1), 0.0);
137 Vector<double> b_sustr(std::size_t(nis) * njs, 0.0);
138 Vector<double> b_svstr(std::size_t(nis) * njs, 0.0);
139 Vector<double> b_uwind(std::size_t(ni) * nj, 0.0);
140 Vector<double> b_vwind(std::size_t(ni) * nj, 0.0);
141 Vector<double> b_told (std::size_t(ni) * nj * nz * ntrc, 0.0);
142 Vector<double> b_tnew (std::size_t(ni) * nj * nz * ntrc, 0.0);
145 for (
int j = jlo; j <= jhi; ++j) {
146 for (
int i = ilo; i <= ihi; ++i) {
147 const int s = fidx(i, j, 0, 0, ilo, jlo, ni, nj, 1);
148 b_rmask[
s] = mskr_a(i, j, 0);
149 b_srflx[
s] = srflx_a(i, j, 0) * srflx_to_roms_kinematic;
155 for (
int k = 0; k < nz; ++k) {
156 for (
int j = jlo; j <= jhi; ++j) {
157 for (
int i = ilo; i <= ihi; ++i) {
158 const int s = fidx(i, j, k, 0, ilo, jlo, ni, nj, nz);
159 b_Hz [
s] = Hz_a (i, j, k);
160 b_z_r[
s] = z_r_a(i, j, k);
167 for (
int k = 0; k <= nz; ++k) {
168 for (
int j = jlo; j <= jhi; ++j) {
169 for (
int i = ilo; i <= ihi; ++i) {
170 b_z_w[fidx(i, j, k, 0, ilo, jlo, ni, nj, nz + 1)] =
176 if (need_gas && !do_bulk_flux) {
177 for (
int j = jlo; j <= jhi + 1; ++j) {
178 for (
int i = ilo; i <= ihi + 1; ++i) {
179 const int s = fidx(i, j, 0, 0, ilo, jlo, nis, njs, 1);
180 b_sustr[
s] = sustr_a(i, j, 0);
181 b_svstr[
s] = svstr_a(i, j, 0);
186 if (need_gas && do_bulk_flux) {
187 for (
int j = jlo; j <= jhi; ++j) {
188 for (
int i = ilo; i <= ihi; ++i) {
189 const int s = fidx(i, j, 0, 0, ilo, jlo, ni, nj, 1);
190 b_uwind[
s] = uwind_a(i, j, 0);
191 b_vwind[
s] = vwind_a(i, j, 0);
197 for (
int n = 0;
n < ntrc; ++
n) {
198 const int comp = cons_comp_for_slot(n);
199 for (
int k = 0; k < nz; ++k) {
200 for (
int j = jlo; j <= jhi; ++j) {
201 for (
int i = ilo; i <= ihi; ++i) {
203 fidx(i, j, k, n, ilo, jlo, ni, nj, nz);
204 b_told[
s] = state_old(i, j, k, comp);
205 b_tnew[
s] = state_new(i, j, k, comp);
213 ilo, ihi, jlo, jhi, nz, nbt,
216 parms.carbon ? 1 : 0,
217 parms.oxygen ? 1 : 0,
219 parms.denitrification ? 1 : 0,
220 parms.bio_sediment ? 1 : 0,
221 do_bulk_flux ? 1 : 0,
222 parms.river_don ? 1 : 0,
223 parms.talk_nonconserv ? 1 : 0,
227 static_cast<int>(parms.pco2air_type),
228 static_cast<int>(parms.co2_schmidt),
229 static_cast<int>(parms.o2_schmidt),
232 double(parms.AttSW), double(parms.AttChl), double(parms.PARfrac),
233 double(parms.Vp0), double(parms.I_thNH4), double(parms.D_p5NH4),
234 double(parms.NitriR), double(parms.K_NO3), double(parms.K_NH4),
235 double(parms.K_PO4), double(parms.K_Phy), double(parms.Chl2C_m),
236 double(parms.ChlMin), double(parms.PhyCN), double(parms.R_P2N),
237 double(parms.PhyIP), double(parms.PhyIS), double(parms.PhyMin),
238 double(parms.PhyMR), double(parms.ZooAE_N), double(parms.ZooCN),
239 double(parms.ZooBM), double(parms.ZooER), double(parms.ZooGR),
240 double(parms.ZooMin), double(parms.ZooMR), double(parms.LDeRRN),
241 double(parms.LDeRRC), double(parms.CoagR), double(parms.SDeRRN),
242 double(parms.SDeRRC), double(parms.RDeRRN), double(parms.RDeRRC),
243 double(parms.wPhy), double(parms.wLDet),
244 double(parms.wSDet), double(parms.pCO2air),
255 const int comp = cons_comp_for_slot(n);
256 for (
int k = 0; k < nz; ++k) {
257 for (
int j = jlo; j <= jhi; ++j) {
258 for (
int i = ilo; i <= ihi; ++i) {
259 state_out(i, j, k, comp) =
260 Real(b_tnew[fidx(i, j, k, n, ilo, jlo,
void fennel_bridge_advance_c(int ilo, int ihi, int jlo, int jhi, int nz, int nbt, int istr, int iend, int jstr, int jend, int use_po4, int use_carbon, int use_oxygen, int use_odu, int use_denit, int use_biosed, int use_bulk, int use_rivdon, int use_talknc, int pco2air_kind, int co2_sc_kind, int o2_sc_kind, int bioiter, double dt_sec, double rho0, double cp_heat, double p_AttSW, double p_AttChl, double p_PARfrac, double p_Vp0, double p_I_thNH4, double p_D_p5NH4, double p_NitriR, double p_K_NO3, double p_K_NH4, double p_K_PO4, double p_K_Phy, double p_Chl2C_m, double p_ChlMin, double p_PhyCN, double p_R_P2N, double p_PhyIP, double p_PhyIS, double p_PhyMin, double p_PhyMR, double p_ZooAE_N, double p_ZooCN, double p_ZooBM, double p_ZooER, double p_ZooGR, double p_ZooMin, double p_ZooMR, double p_LDeRRN, double p_LDeRRC, double p_CoagR, double p_SDeRRN, double p_SDeRRC, double p_RDeRRN, double p_RDeRRC, double p_wPhy, double p_wLDet, double p_wSDet, double p_pCO2air, const double *rmask, const double *Hz, const double *z_r, const double *z_w, const double *srflx, const double *sustr, const double *svstr, const double *uwind, const double *vwind, double *pH, const double *t_nstp, double *t_nnew, int dbg_level, int dbg_i, int dbg_j)
int biology_debug_i
Target column i index for biology_debug = 1.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_vwind
Wind in the v direction, defined at rho-points.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskr
land/sea mask at cell centers (2D)
int biology_debug
Biology diagnostic verbosity: 0 off, 1 target column, 2 all columns. See Source/Biology/Fortran/tag_m...
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_sustr
Surface stress in the u direction.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Hz
Width of cells in the vertical (z-) direction (3D, Hz in ROMS)
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_uwind
Wind in the u direction, defined at rho-points.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_z_r
z coordinates at rho points (cell centers)
int Bio_comp
First cons component of the biology block, i.e. Tracer_comp + nscalar. The state is laid out as temp,...
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_svstr
Surface stress in the v direction.
static SolverChoice solverChoice
Container for algorithmic choices.
int biology_debug_j
Target column j index for biology_debug = 1.
REMORABiology::FennelParameters fennel_params
Runtime parameters for the Fennel biology package.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_srflx
Shortwave radiation flux [W/m²], defined at rho-points.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_z_w
z coordinates at w points (faces between z-cells)
int num_tracers(FennelParameters const ¶meters) noexcept
@ data
annual climatology of Laurent et al. (2017)
integer, dimension(ngrids) n