134 static std::string tracer_hadv_string =
"upstream3";
135 pp.queryAdd(
"tracer_horizontal_advection_scheme",tracer_hadv_string);
136 if (tracer_hadv_string ==
"centered4")
138 else if (tracer_hadv_string ==
"upstream3")
141 amrex::Error(
"Advection scheme unknown.");
144 static std::string uv_hadv_string =
"upstream3";
145 pp.queryAdd(
"uv_horizontal_advection_scheme",uv_hadv_string);
146 if (uv_hadv_string ==
"upstream3")
148 else if (uv_hadv_string ==
"centered2")
151 amrex::Error(
"UV advection scheme unknown.");
153 pp.queryAdd(
"rdrag",
rdrag);
154 pp.queryAdd(
"rdrag2",
rdrag2);
155 pp.queryAdd(
"Zos",
Zos);
156 pp.queryAdd(
"Zob",
Zob);
157 pp.queryAdd(
"Cdb_max",
Cdb_max);
158 pp.queryAdd(
"Cdb_min",
Cdb_min);
189 for (
int icomp =
Tracer_comp; icomp < ncons; ++icomp) {
199 static std::string eos_type_string =
"linear";
200 pp.queryAdd(
"eos_type",eos_type_string);
201 if (eos_type_string ==
"linear" || eos_type_string ==
"Linear" ||
202 eos_type_string ==
"lin" || eos_type_string ==
"Lin") {
204 pp.queryAdd(
"Tcoef",
Tcoef);
205 pp.queryAdd(
"Scoef",
Scoef);
206 }
else if (eos_type_string ==
"nonlinear" || eos_type_string ==
"Nonlinear" ||
207 eos_type_string ==
"non-linear" || eos_type_string ==
"Non-linear" ||
208 eos_type_string ==
"nonlin" || eos_type_string ==
"Nonlin") {
211 amrex::Abort(
"Dont know this eos_type");
213 pp.queryAdd(
"R0",
R0);
214 pp.queryAdd(
"S0",
S0);
215 pp.queryAdd(
"T0",
T0);
216 pp.queryAdd(
"rho0",
rho0);
221 amrex::ParmParse pp_driver(
"driver");
222 std::string driver_atm2ocn_mode =
"state";
223 pp_driver.query(
"atm2ocn_mode", driver_atm2ocn_mode);
224 if (amrex::toLower(driver_atm2ocn_mode) ==
"flux") {
234 pp.queryAdd(
"air_pressure",
Pair);
235 pp.queryAdd(
"air_temperature",
Tair);
236 pp.queryAdd(
"air_humidity",
Hair);
237 pp.queryAdd(
"surface_radiation_flux",
srflux);
238 pp.queryAdd(
"uwind",
Uwind);
239 pp.queryAdd(
"vwind",
Vwind);
245 pp.queryAdd(
"cloud",
cloud);
246 pp.queryAdd(
"rain",
rain);
247 pp.queryAdd(
"EminusP",
EminusP);
248 pp.query(
"eminusp_value",
EminusP);
249 pp.queryAdd(
"blk_ZQ",
blk_ZQ);
250 pp.queryAdd(
"blk_ZT",
blk_ZT);
251 pp.queryAdd(
"blk_ZW",
blk_ZW);
252 pp.queryAdd(
"eminusp",
eminusp);
256 struct BulkTypeInput {
259 const char* default_type;
263 const BulkTypeInput bulk_type_inputs[] = {
276 bool uwind_type_specified =
false;
277 bool vwind_type_specified =
false;
278 for (
const BulkTypeInput& input : bulk_type_inputs) {
279 std::string type_string = input.default_type;
280 const bool type_specified = pp.queryAdd(input.name, type_string);
281 if (type_specified) {
283 "remora." + std::string(input.name),
284 input.allow_computed);
286 uwind_type_specified =
true;
288 vwind_type_specified =
true;
293 struct BulkTypeAlias {
299 const BulkTypeAlias bulk_type_aliases[] = {
305 for (
const BulkTypeAlias& input : bulk_type_aliases) {
306 std::string type_string;
307 if (pp.query(input.name, type_string)) {
309 "remora." + std::string(input.name),
310 input.allow_computed);
314 const BulkTypeAlias legacy_netcdf_flags[] = {
325 for (
const BulkTypeAlias& input : legacy_netcdf_flags) {
326 bool from_netcdf =
false;
327 if (pp.query(input.name, from_netcdf) && from_netcdf) {
332 bool legacy_longwave_netcdf_is_net =
false;
333 if (pp.query(
"longwave_netcdf_is_net", legacy_longwave_netcdf_is_net) && legacy_longwave_netcdf_is_net) {
345 amrex::Warning(
"remora.longwave_netcdf_varname is set but remora.lwrad_type is not netcdf; the value will be ignored.");
349 amrex::Abort(
"If evaporation minus precipitation (E-P) sea surface height correction is on, bulk fluxes must be on as well (remora.bulk_fluxes=true)");
352 amrex::Abort(
"Evaporation minus precipitation (E-P) requires bulk flux parametrizations (remora.bulk_fluxes=true)");
355 const bool use_external_lwrad =
359 amrex::Abort(
"remora.longwave_is_net=true requires remora.lwrad_type to be constant, analytic, or netcdf");
363 amrex::Abort(
"remora.longwave_down=true requires remora.lwrad_type to be constant, analytic, or netcdf");
367 static bool printed_ep_source =
false;
368 if (!printed_ep_source) {
369 printed_ep_source =
true;
371 amrex::Print() <<
"[REMORA] Active E-P source: NetCDF EminusP (remora.eminusp_type=netcdf).\n";
373 amrex::Print() <<
"[REMORA] Active E-P source: analytic EminusP (remora.eminusp_type=analytic).\n";
375 amrex::Print() <<
"[REMORA] Active E-P source: constant EminusP (remora.eminusp_type=constant).\n";
377 amrex::Print() <<
"[REMORA] Active E-P source: bulk evap-rain diagnostic.\n";
383 pp.queryAdd(
"theta_s",
theta_s);
384 pp.queryAdd(
"theta_b",
theta_b);
385 pp.queryAdd(
"tcline",
tcline);
391 pp.queryAdd(
"Akv_bak",
Akv_bak);
392 pp.queryAdd(
"Akt_bak",
Akt_bak);
395 static std::string grid_scale_type_string =
"constant";
396 pp.queryAdd(
"grid_scale_type",grid_scale_type_string);
398 if (amrex::toLower(grid_scale_type_string) ==
"constant") {
400 }
else if (amrex::toLower(grid_scale_type_string) ==
"custom") {
401 amrex::Warning(
"Initialization of grid scale from prob.cpp is now called 'analytic'. 'custom' will be deprecated");
403 }
else if (amrex::toLower(grid_scale_type_string) ==
"analytic") {
406 amrex::Error(
"Don't know this grid_scale_type");
409 static std::string ic_type_string =
"analytic";
410 bool found_ic_bc = pp.queryAdd(
"ic_bc_type", ic_type_string);
411 pp.queryAdd(
"ic_type", ic_type_string);
414 amrex::Warning(
"remora.ic_bc_type is now called remora.ic_type, and will eventually be deprecated");
417 if ( amrex::toLower(ic_type_string) ==
"custom") {
418 amrex::Warning(
"Problem initialization from prob.cpp is now called 'analytic'. 'custom' will be deprecated");
420 }
else if ( amrex::toLower(ic_type_string) ==
"analytic") {
422 }
else if ( amrex::toLower(ic_type_string) ==
"netcdf") {
424 }
else if ( amrex::toLower(ic_type_string) ==
"real") {
425 amrex::Warning(
"Problem initialization from NetCDF (remora.ic_type) is now called 'netcdf'. 'real' will be deprecated");
428 amrex::Error(
"Don't know this ic_type");
432 static std::string coupling_type_string =
"TwoWay";
433 pp.queryAdd(
"coupling_type",coupling_type_string);
434 if (amrex::toLower(coupling_type_string) ==
"twoway" ||
435 amrex::toLower(coupling_type_string) ==
"two_way") {
437 }
else if (amrex::toLower(coupling_type_string) ==
"oneway" ||
438 amrex::toLower(coupling_type_string) ==
"one_way") {
441 amrex::Abort(
"Dont know this coupling_type");
446 static std::string coriolis_type_string =
"beta_plane";
447 pp.queryAdd(
"coriolis_type",coriolis_type_string);
448 if ( amrex::toLower(coriolis_type_string) ==
"custom") {
449 amrex::Warning(
"Coriolis initialization from prob.cpp is now called 'analytic'. 'custom' will be deprecated");
451 }
else if ( amrex::toLower(coriolis_type_string) ==
"analytic") {
453 }
else if ((amrex::toLower(coriolis_type_string) ==
"beta_plane") ||
454 (amrex::toLower(coriolis_type_string) ==
"betaplane")) {
456 }
else if ( (amrex::toLower(coriolis_type_string) ==
"netcdf")) {
458 }
else if ( (amrex::toLower(coriolis_type_string) ==
"real")) {
459 amrex::Warning(
"Coriolis initialization from NetCDF is now called 'netcdf'. 'real' will be deprecated");
462 amrex::Abort(
"Don't know this coriolis_type");
466 static std::string smflux_type_string =
"analytic";
467 int smflux_specified = pp.queryAdd(
"smflux_type",smflux_type_string);
468 if ( amrex::toLower(smflux_type_string) ==
"custom") {
469 amrex::Warning(
"Surface momentum flux initialization from prob.cpp is now called 'analytic'. 'custom' will be deprecated");
471 }
else if ( amrex::toLower(smflux_type_string) ==
"analytic") {
473 }
else if ( amrex::toLower(smflux_type_string) ==
"netcdf") {
476 amrex::Abort(
"Don't know this smflux_type");
479 static std::string wind_type_string =
"analytic";
480 int wind_specified = pp.queryAdd(
"wind_type",wind_type_string);
481 if ( amrex::toLower(wind_type_string) ==
"custom") {
482 amrex::Warning(
"Surface wind initialization from prob.cpp is now called 'analytic'. 'custom' will be deprecated");
484 }
else if ( amrex::toLower(wind_type_string) ==
"analytic") {
486 }
else if ( amrex::toLower(wind_type_string) ==
"netcdf") {
489 amrex::Abort(
"Don't know this smflux_type");
492 if (wind_specified) {
495 if (!uwind_type_specified) {
498 if (!vwind_type_specified) {
503 if (wind_specified && smflux_specified) {
504 amrex::Abort(
"Cannot specify both wind and surface momentum flux");
507 static std::string mask_type_string =
"none";
510 mask_type_string =
"netcdf";
512 pp.queryAdd(
"mask_type", mask_type_string);
513 if (amrex::toLower(mask_type_string) ==
"none") {
515 }
else if (amrex::toLower(mask_type_string) ==
"analytic") {
517 }
else if (amrex::toLower(mask_type_string) ==
"netcdf") {
520 amrex::Abort(
"Don't know this mask_type");
523 static std::string bottom_stress_type_string =
"linear";
524 pp.queryAdd(
"bottom_stress_type", bottom_stress_type_string);
525 if (amrex::toLower(bottom_stress_type_string) ==
"linear") {
527 }
else if (amrex::toLower(bottom_stress_type_string) ==
"quadratic") {
529 }
else if (amrex::toLower(bottom_stress_type_string) ==
"logarithmic") {
532 amrex::Abort(
"Don't know this bottom_stress_type");
535 amrex::Real tnu2_salt =
zero;
536 amrex::Real tnu2_temp =
zero;
537 amrex::Real tnu2_scalar =
zero;
538 static std::string horiz_mixing_type_string =
"analytic";
539 pp.queryAdd(
"horizontal_mixing_type", horiz_mixing_type_string);
540 if (amrex::toLower(horiz_mixing_type_string) ==
"analytical" ||
541 amrex::toLower(horiz_mixing_type_string) ==
"analytic") {
543 }
else if (amrex::toLower(horiz_mixing_type_string) ==
"constant") {
545 }
else if (amrex::toLower(horiz_mixing_type_string) ==
"scaled_to_grid") {
548 amrex::Abort(
"Don't know this horizontal mixing type");
550 pp.queryAdd(
"visc2",
visc2);
551 pp.queryAdd(
"tnu2_salt",tnu2_salt);
552 pp.queryAdd(
"tnu2_temp",tnu2_temp);
553 pp.queryAdd(
"tnu2_scalar",tnu2_scalar);
557 static std::string scaled_to_grid_amr_scaling_string =
"none";
558 pp.queryAdd(
"scaled_to_grid_amr_scaling", scaled_to_grid_amr_scaling_string);
559 if (amrex::toLower(scaled_to_grid_amr_scaling_string) ==
"none") {
561 }
else if (amrex::toLower(scaled_to_grid_amr_scaling_string) ==
"linear") {
564 amrex::Abort(
"Don't know this scaled_to_grid_amr_scaling option");
567 tnu2.assign(ncons, tnu2_scalar);
575 static std::string harmonic_mixing_type_string =
"s";
576 pp.queryAdd(
"harmonic_mixing_type", harmonic_mixing_type_string);
577 if (amrex::toLower(harmonic_mixing_type_string) ==
"s") {
579 }
else if (amrex::toLower(harmonic_mixing_type_string) ==
"geopotential" ||
580 amrex::toLower(harmonic_mixing_type_string) ==
"geo") {
583 amrex::Abort(
"Don't know this harmonic_mixing_type");
586 pp.queryAdd(
"Akk_bak",
Akk_bak);
587 pp.queryAdd(
"Akp_bak",
Akp_bak);
588 static std::string vert_mixing_type_string =
"analytic";
589 static std::string gls_stability_type_string =
"Canuto_A";
590 pp.queryAdd(
"vertical_mixing_type", vert_mixing_type_string);
591 pp.queryAdd(
"gls_stability_type", gls_stability_type_string);
592 if (amrex::toLower(vert_mixing_type_string) ==
"analytical" ||
593 amrex::toLower(vert_mixing_type_string) ==
"analytic") {
595 }
else if (amrex::toLower(vert_mixing_type_string) ==
"gls") {
597 if (amrex::toLower(gls_stability_type_string) ==
"canuto_a") {
600 else if (amrex::toLower(gls_stability_type_string) ==
"canuto_b") {
603 else if (amrex::toLower(gls_stability_type_string) ==
"galperin") {
607 amrex::Abort(
"Don't know this GLS stability type");
610 amrex::Abort(
"Don't know this vertical mixing type");
614 pp.queryAdd(
"gls_P",
gls_p);
615 pp.queryAdd(
"gls_M",
gls_m);
616 pp.queryAdd(
"gls_N",
gls_n);
621 pp.queryAdd(
"gls_c1",
gls_c1);
622 pp.queryAdd(
"gls_c2",
gls_c2);
623 pp.queryAdd(
"gls_c3m",
gls_c3m);
624 pp.queryAdd(
"gls_c3p",
gls_c3p);
630 gls_L1 = amrex::Real(0.107);
631 gls_L2 = amrex::Real(0.0032);
632 gls_L3 = amrex::Real(0.0864);
633 gls_L4 = amrex::Real(0.12);
634 gls_L5 = amrex::Real(11.9);
635 gls_L6 = amrex::Real(0.4);
637 gls_L8 = amrex::Real(0.48);
641 gls_L1 = amrex::Real(0.127);
642 gls_L2 = amrex::Real(0.00336);
643 gls_L3 = amrex::Real(0.0906);
644 gls_L4 = amrex::Real(0.101);
645 gls_L5 = amrex::Real(11.2);
646 gls_L6 = amrex::Real(0.4);
648 gls_L8 = amrex::Real(0.318);
657 amrex::Real tnudg =
zero;
658 amrex::Real znudg =
zero;
659 amrex::Real m2nudg =
zero;
660 amrex::Real m3nudg =
zero;
661 pp.queryAdd(
"tnudg",tnudg);
662 pp.queryAdd(
"znudg",znudg);
663 pp.queryAdd(
"m2nudg",m2nudg);
664 pp.queryAdd(
"m3nudg",m3nudg);
665 pp.queryAdd(
"obcfac",
obcfac);
684#ifndef REMORA_USE_NETCDF
686 amrex::Abort(
"Climatology nudging requires building with NetCDF");