REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_Biology.H
Go to the documentation of this file.
1#ifndef REMORA_BIOLOGY_H_
2#define REMORA_BIOLOGY_H_
3
4#include <string>
5
6#include <AMReX_REAL.H>
7#include <AMReX_Vector.H>
8
10
11namespace REMORABiology {
12
13
14enum class BiologyModel {
15 none,
16 fennel
17};
18
19/**
20 * Source of the biology tracer initial condition, selected independently of
21 * remora.ic_type.
22 *
23 * The two are decoupled because a NetCDF initial file supplies whichever
24 * tracers it happens to contain, and validating an option set the file does
25 * not cover (PO4, ODU) would otherwise require regenerating binary input.
26 * With `analytic`, physical fields still come from NetCDF while biology comes
27 * from the problem's analytic profile, which is reproducible from source.
28 */
29enum class BiologyICType {
30 follow_ic_type, //!< default: NetCDF when ic_type is netcdf, else analytic
32 netcdf
33};
34
35/**
36 * Source of the atmospheric pCO2 used by the surface CO2 gas exchange.
37 *
38 * ROMS picks one of these with PCO2AIR_DATA / PCO2AIR_SECULAR or neither. The
39 * two time-dependent forms date the model clock with remora_caldate.
40 */
41enum class PCO2AirType {
42 constant, //!< remora.fennel.pCO2air, unchanging
43 data, //!< annual climatology of Laurent et al. (2017)
44 secular //!< secular trend plus harmonics, referenced to 1951
45};
46
47/**
48 * Schmidt-number formulation for the air-sea gas transfer velocity.
49 *
50 * CO2 offers the Wanninkhof (1992) and (2014) coefficient sets; O2 adds the
51 * Keeling et al. (1998) OCMIP set. The choice also selects the leading rate
52 * coefficient, 0.31 for 1992 and 0.251 for 2014, so the two must move
53 * together and are not independently settable.
54 */
59
60enum class O2SchmidtType {
63 ocmip
64};
65
67 // Maximum number of iterations to achieve convergence of the nonlinear solution.
68 int BioIter = 1;
69
70 // Light attenuation due to seawater [1/m].
71 amrex::Real AttSW = amrex::Real(0.04);
72
73 // Light attenuation by chlorophyll [1/(mg_Chl m2)].
74 amrex::Real AttChl = amrex::Real(0.02486);
75
76 // Fraction of shortwave radiation that is photosynthetically active.
77 amrex::Real PARfrac = amrex::Real(0.43);
78
79 // Eppley temperature-limited and light-limited growth tuning parameter.
80 amrex::Real Vp0 = amrex::Real(1.0);
81
82 // Radiation threshold for nitrification inhibition [Watts/m2].
83 amrex::Real I_thNH4 = amrex::Real(0.0095);
84
85 // Half-saturation radiation for nitrification inhibition [Watts/m2].
86 amrex::Real D_p5NH4 = amrex::Real(0.1);
87
88 // Nitrification rate: oxidation of NH4 to NO3 [day-1].
89 amrex::Real NitriR = amrex::Real(0.05);
90
91 // Inverse half-saturation for phytoplankton NO3 uptake [1/(millimole_N m-3)].
92 amrex::Real K_NO3 = amrex::Real(2.0);
93
94 // Inverse half-saturation for phytoplankton NH4 uptake [1/(millimole_N m-3)].
95 amrex::Real K_NH4 = amrex::Real(2.0);
96
97 // Inverse half-saturation for phytoplankton PO4 uptake [1/(millimole_P m-3)].
98 amrex::Real K_PO4 = amrex::Real(32.0);
99
100 // Zooplankton half-saturation squared constant for ingestion [millimole_N m-3]^2.
101 amrex::Real K_Phy = amrex::Real(1.0);
102
103 // Maximum chlorophyll to carbon ratio [mg_Chl/mg_C].
104 amrex::Real Chl2C_m = amrex::Real(0.0535);
105
106 // Chlorophyll minimum threshold value [mg_Chl/m3].
107 amrex::Real ChlMin = amrex::Real(0.01);
108
109 // Phytoplankton Carbon:Nitrogen ratio [mole_C/mole_N].
110 amrex::Real PhyCN = amrex::Real(6.625);
111
112 // Phytoplankton Phosphate:Nitrogen ratio [mole_P/mole_N].
113 amrex::Real R_P2N = amrex::Real(0.0625);
114
115 // Phytoplankton NH4 inhibition parameter [1/(millimole_N)].
116 amrex::Real PhyIP = amrex::Real(1.5);
117
118 // Phytoplankton initial slope of P-I curve [1/(Watts m-2 day)].
119 amrex::Real PhyIS = amrex::Real(0.025);
120
121 // Phytoplankton minimum threshold value [millimole_N/m3].
122 amrex::Real PhyMin = amrex::Real(0.01);
123
124 // Phytoplankton mortality rate [1/day].
125 amrex::Real PhyMR = amrex::Real(0.15);
126
127 // Zooplankton Nitrogen assimilation efficiency.
128 amrex::Real ZooAE_N = amrex::Real(0.75);
129
130 // Zooplankton Carbon:Nitrogen ratio [mole_C/mole_N].
131 amrex::Real ZooCN = amrex::Real(6.625);
132
133 // Basal metabolism of zooplankton [1/day].
134 amrex::Real ZooBM = amrex::Real(0.1);
135
136 // Zooplankton specific excretion rate [1/day].
137 amrex::Real ZooER = amrex::Real(0.1);
138
139 // Zooplankton maximum growth rate [1/day].
140 amrex::Real ZooGR = amrex::Real(0.6);
141
142 // Zooplankton minimum threshold value [millimole_N/m3].
143 amrex::Real ZooMin = amrex::Real(0.01);
144
145 // Zooplankton mortality rate [1/day].
146 amrex::Real ZooMR = amrex::Real(0.025);
147
148 // Large nitrogen detritus remineralization rate [day-1].
149 amrex::Real LDeRRN = amrex::Real(0.01);
150
151 // Large detritus remineralization rate C-fraction [day-1].
152 amrex::Real LDeRRC = amrex::Real(0.01);
153
154 // Coagulation rate: aggregation rate of SDeN + Phyt ==> LDeN [day-1].
155 amrex::Real CoagR = amrex::Real(0.005);
156
157 // Small nitrogen detritus remineralization rate [day-1].
158 amrex::Real SDeRRN = amrex::Real(0.1);
159
160 // Small detritus remineralization rate C-fraction [day-1].
161 amrex::Real SDeRRC = amrex::Real(0.03);
162
163 // Vertical sinking velocity for phytoplankton [m/day].
164 amrex::Real wPhy = amrex::Real(0.1);
165
166 // Vertical sinking velocity for large detritus [m/day].
167 amrex::Real wLDet = amrex::Real(1.0);
168
169 // Vertical sinking velocity for small detritus [m/day].
170 amrex::Real wSDet = amrex::Real(0.1);
171
172 // River nitrogen detritus remineralization rate [1/day].
173 amrex::Real RDeRRN = amrex::Real(0.03);
174
175 // River carbon detritus remineralization rate [1/day].
176 amrex::Real RDeRRC = amrex::Real(0.03);
177
178 // CO2 partial pressure in the air (parts per million by volume). Used when
179 // pco2air_type is constant; otherwise the value is computed from the date.
180 amrex::Real pCO2air = amrex::Real(370.0);
181
182 // Enable ROMS PO4 option, adding phosphate as an active biological tracer.
183 bool po4 = false;
184
185 // Enable ROMS CARBON option, adding large and small carbon detritus,
186 // total inorganic carbon, and alkalinity tracers.
187 bool carbon = false;
188
189 // Enable one additional biological tracer for dissolved oxygen. OXYGEN can
190 // be activated independently of the CARBON option in ROMS.
191 bool oxygen = false;
192
193 // Enable ROMS ODU option, adding dissolved oxygen demand units.
194 bool odu = false;
195
196 // Runtime analogue of ROMS DENITRIFICATION bottom remineralization option.
197 bool denitrification = false;
198
199 // Runtime analogue of ROMS BIO_SEDIMENT bottom remineralization option.
200 bool bio_sediment = true;
201
202 // Enable ROMS RIVER_DON option, adding a river dissolved organic nitrogen
203 // pool that remineralizes to NH4, plus its carbon counterpart when carbon
204 // is on. Neither pool sinks, matching ROMS.
205 bool river_don = false;
206
207 // Enable ROMS TALK_NONCONSERV option. Alkalinity is otherwise diagnostic,
208 // a function of salinity alone; with this on it responds to nitrate
209 // uptake, nitrification, zooplankton metabolism and remineralization.
210 // Requires carbon, since alkalinity is a carbon-block tracer.
211 bool talk_nonconserv = false;
212
213 // remora.fennel.pco2air_type: constant / data / secular. The two
214 // time-dependent forms date the model clock through REMORA_DateClock.H,
215 // which is ROMS caldate with time_ref = 0: model time zero is 0001-01-01,
216 // and a run is placed at a real date through remora.start_time.
218
219 // remora.fennel.co2_schmidt / remora.fennel.oxygen_schmidt.
222
223 void init_params (const std::string& remora_prefix);
224};
225
226namespace Fennel {
227static constexpr int NumBaseTracers = 7;
228static constexpr int NumCarbonTracers = 4;
229
231 int no3 = -1;
232 int nh4 = -1;
233 int chlo = -1;
234 int phyt = -1;
235 int zoop = -1;
236 int lden = -1;
237 int sden = -1;
238 int rden = -1;
239 int po4 = -1;
240 int ldec = -1;
241 int sdec = -1;
242 int tic = -1;
243 int talk = -1;
244 int rdec = -1;
245 int oxyg = -1;
246 int odu = -1;
247};
248
249/** \brief Map the Fennel tracers onto cons components starting at \p base.
250 *
251 * \p base is REMORA::bio_comp_start(), which is Tracer_comp plus the number of passive
252 * (dye) scalars. Passing it explicitly keeps biology working when a run carries dye as
253 * well, since the biology block then no longer starts at Tracer_comp.
254 */
256{
257 int comp = base;
259 c.no3 = comp++;
260 c.nh4 = comp++;
261 c.chlo = comp++;
262 c.phyt = comp++;
263 c.zoop = comp++;
264 c.lden = comp++;
265 c.sden = comp++;
266 c.rden = parameters.river_don ? comp++ : -1;
267 c.po4 = parameters.po4 ? comp++ : -1;
268 c.ldec = parameters.carbon ? comp++ : -1;
269 c.sdec = parameters.carbon ? comp++ : -1;
270 c.tic = parameters.carbon ? comp++ : -1;
271 c.talk = parameters.carbon ? comp++ : -1;
272 c.rdec = (parameters.carbon && parameters.river_don) ? comp++ : -1;
273 c.oxyg = parameters.oxygen ? comp++ : -1;
274 c.odu = parameters.odu ? comp++ : -1;
275 return c;
276}
277
278inline int num_tracers (FennelParameters const& parameters) noexcept
279{
280 return NumBaseTracers + (parameters.po4 ? 1 : 0) +
281 (parameters.carbon ? NumCarbonTracers : 0) +
282 (parameters.river_don ? 1 : 0) +
283 ((parameters.river_don && parameters.carbon) ? 1 : 0) +
284 (parameters.oxygen ? 1 : 0) + (parameters.odu ? 1 : 0);
285}
286}
287
288BiologyModel parse_biology_model (const std::string& name);
290BiologyICType parse_biology_ic_type (const std::string& name);
292bool has_biology (BiologyModel model) noexcept;
293amrex::Vector<std::string> tracer_names (BiologyModel model,
294 FennelParameters const& fennel_parameters);
295
296}
297
298#endif
mf_h setVal(geomdata.ProbHi(2))
static constexpr int NumCarbonTracers
Components components(FennelParameters const &parameters, int base) noexcept
Map the Fennel tracers onto cons components starting at base.
int num_tracers(FennelParameters const &parameters) noexcept
static constexpr int NumBaseTracers
Vector< std::string > tracer_names(BiologyModel model, FennelParameters const &fennel_parameters)
std::string biology_ic_type_name(BiologyICType type)
bool has_biology(BiologyModel model) noexcept
BiologyICType parse_biology_ic_type(const std::string &name)
@ secular
secular trend plus harmonics, referenced to 1951
@ constant
remora.fennel.pCO2air, unchanging
@ data
annual climatology of Laurent et al. (2017)
@ follow_ic_type
default: NetCDF when ic_type is netcdf, else analytic
BiologyModel parse_biology_model(const std::string &name)
std::string biology_model_name(BiologyModel model)
void init_params(const std::string &remora_prefix)