Inputs

The REMORA executable reads run-time information from an “inputs” file which you put on the command line. This section describes the inputs which can be specified either in the inputs file or on the command line. If a value is specified on the command line, that value will override a value specified in the inputs file. Biology options are documented in Fennel Biology. That section covers the remora.fennel.* parameters, biology initial-condition selection (remora.biology_ic_type), and the options used to validate the port against ROMS (remora.use_biology_cpp_answer, remora.biology_debug).

Problem Geometry

The problem geometry can be specified either by a NetCDF grid file or in the inputs. Instructions for setting grid, initial, and Dirichelet boundary conditions from NetCDF file can be found here. If one of these quantities is specified from a NetCDF file, they all must be. Even if the grid is specified in the NetCDF file, the geometry and boundary parameters below must still be set. remora.prob_lo and remora.prob_hi do not need to agree with the file in this case.

The z-component of remora.prob_lo should be more negative than the deepest bathymetry, and the z-compoonent of remora.prob_hi should be 0.

List of Parameters

Parameter

Definition

Acceptable Values

Default

remora.prob_lo

physical location of low

corner of the domain

[Real Real -Real]

must be set

remora.prob_hi

physical location of

high corner of the domain

[Real Real 0]

must be set

remora.is_periodic

is the domain periodic in

this direction

0 if false, 1 if true.

Z-component must be zero

0 0 0

Examples of Usage

  • remora.prob_lo = 0 0 -200 defines the low corner of the domain at (0 m,0 m,-200 m) in physical space.

  • remora.prob_hi = 1.e8 2.e8 0 defines the high corner of the domain at (1.e8 m, 2.e8 m, 0 m) in physical space.

  • remora.is_periodic = 0 1 0 says the domain is periodic in the y-direction only.

Domain Boundary Conditions

Instructions for how to specify domain boundary conditions, with usage examples can be found in Domain Boundary Conditions.

Imposing Boundary and Initial Conditions from NetCDF File

Grid, initial, and time-dependent boundary data can be specified using NetCDF files, as in ROMS. REMORA expects files in the same format as ROMS, in NetCDF classic format (32- or 64-bit). NetCDF4-classic does not work. If the file format is incorrect, REMORA will exit with the error:

NetCDF: Attempt to use feature that was not turned on when netCDF was built.

Other versions of NetCDF files can be converted to 64-bit NetCDF classic by running the command:

ncks -5 old_file.nc converted_file.nc

The utility ncks is part of the NCO suite.

Currently, if initial or grid files are specified, they both must be. Boundary condition options with NetCDF boundary data are equivalent to ROMS clamped, Chapman-Flather, and Orlanski + Nudging boundary conditions. Options and examples can be found in the section on Domain Boundary Conditions.

By default, bathymetry is specified at level 0 and interpolated to the finer levels, like with any other variable. Bathymetry may also be specified at level remora.hires_grid_level > 0 in file remora.nc_grid_file_hires. Bathymetry on levels < remora.hires_grid_level is set by averaging down the given bathymetry. Bathymetry on higher levels is set by interpolating. High resolution bathymetry data must be given with a number of grow cells equal to the cumulative refinement ratio between level 0 and remora.hires_grid_level. That is, the refined grid must fully cover the level 0 grid plus one level 0 grow cell. For example, in a problem with hires_grid_level = 2, a refinement ratio of 2 between levels 0 and 1, and 3 between levels 1 and 2, nc_grid_file_hires must have 6 grow cells on each side of the domain.

Both levels must be greater than 0 (-1 means the data is specified at level 0 as usual); 0 is rejected, since the full-domain arrays it would need exist only for levels above 0. A high-resolution file smaller than the rule above is rejected by name rather than read partially, and note that on restart the bathymetry is restored from the checkpoint but pm/pn are re-read, so the high-resolution grid file must still be present.

Initial data may be specified on a high-resolution level the same way, at level remora.hires_init_level > 0 in file remora.nc_init_file_hires, and averaged down to the levels below. The grow cell rule is the same as for bathymetry, applied to this level: the file must have as many grow cells as the cumulative refinement ratio between level 0 and remora.hires_init_level. The fields it supplies are the ones a level 0 initial file supplies, on the same terms: temp, salt, u, v, and zeta, plus each dye the run carries (optional, as at level 0) and the biology tracers when remora.biology_ic_type selects NetCDF. High-resolution initialization requires remora.ic_type = netcdf; it is not implemented for analytic initial conditions.

List of Parameters

Parameter

Definition

Acceptable

Values

Default

remora.ic_type

read initial and grid

data from files

analytic

or netcdf

analytic

remora.nc_init_file_0

initial data NetCDF

file name

string

must be set

if remora.ic_type

is true

remora.nc_grid_file_0

grid data NetCDF

file name

string

must be set

if remora.ic_type

is true

remora.nc_grid_file_hires

high-resolution grid data NetCDF

file name

string

must be set if

remora.hires_grid_level

is valid (greater than -1)

remora.hires_grid_level

level where high-resolution

grid data is specified, either

in NetCDF file or analytically

integer

-1, meaning grid data will

be specified at level 0

remora.nc_init_file_hires

high-resolution initial data

NetCDF file name

string

must be set if

remora.hires_init_level

is valid (greater than -1)

remora.hires_init_level

level where high-resolution

initial data is specified

in a NetCDF file

integer

-1, meaning initial data

will be specified at level 0

remora.nc_bdry_file

boundary data NetCDF

file names(s)

string or list

of strings

must be set if

any boundary

condition requires it:

orlanski_rad_nudg,

clamped, chapman,

or flather.

remora.nc_frc_file

forcing data NetCDF

file name(s)

string or list

of strings

must be set

if remora.wind_type

or remora.smflux_type

equal netcdf

remora.bdy_time_varname

default name of time

variable in

boundary file

string

ocean_time

remora.bdy_{var}_time_varname

name of time variable

for variable {var} (one

of u, v, ubar,

vbar, zeta, or any

tracer name)

string

None

remora.frc_time_varname

name of time variable

in forcing file

string

wind_time for wind,

sms_time for surface

momentum stress

Notes

  • nc_bdry_file must either be a string or a space-separated list of strings of boundary data files. They must be in time series order.

  • nc_frc_file may be either a string or a space-separated list of strings of forcing data files. They must be in time series order.

  • The time variables in the boundary files may be different for each boundary variable. Any that are not individually specified with remora.bdy_{var}_time_varname will default to the variable name given by bdy_time_varname.

  • Every cell-centered tracer has its own boundary variable, named for the tracer itself: temp, salt, and then either the active biology tracer names or tracer, tracer_1, … So a run carrying nitrate reads NO3_west and friends from the boundary file and accepts remora.bdy_NO3_time_varname. See Boundary conditions for individual tracers.

Resolution and Tiling

The REMORA gridding and load balancing strategy is based on that in AMReX. See the Gridding section of the AMReX documentation for details.

List of Parameters

Parameter

Definition

Acceptable Values

Default

remora.n_cell

number of cells in each

direction at the coarsest

level

Triplet of integers > 0

{x,y,z}

must be set

remora.omp_tile_size

target tile size

Triplet of integers > 0

{x,y,z}

CPU: 8 8 1024

GPU: 1024 1024 1024

Notes

  • remora.omp_tile_size is an alias for fabarray.mfiter_tile_size, which controls the distribution of work by OpenMP.

  • The domain may not be tiled in the z direction. That is, the last component of remora.omp_tile_size must be greater than or equal to the number of vertical levels.

Examples of Usage

  • remora.n_cell = 32 64 64

    would define the domain to have 32 cells in the x-direction, 64 cells in the y-direction, and 64 cells in the z-direction at the coarsest level.

Mesh Refinement and (Re)gridding

Overview

The user defines how to tag individual cells at a given level for refinement. This list of tagged cells is sent to a grid generation routine, which uses the Berger–Rigoutsos algorithm to create rectangular grids that contain the tagged cells.

See Mesh Refinement for more details on how to specify regions for refinement.

Note that because these arguments are primarily used by AMReX and pertain to adaptive mesh refinement, they use the prefix amr.

List of Parameters

Parameter

Definition

Acceptable Values

Default

amr.max_level

number of levels of

refinement above the

coarsest level

Integer >= 0

must be set

amr.ref_ratio_vect

ratio of coarse

to fine grid

spacing between

subsequent levels

3 integers

(one per dir)

per refinement

level. Refinement

in z must be 1

2 for all

directions

amr.regrid_int

how often to regrid

Integer

-1 (don’t regrid)

amr.regrid_on_restart

should we regrid

immediately

after restarting

0 or 1

0

amr.regrid_file

name of file

from which to

read the grids

text

no file

amr.grid_eff

grid efficiency at

coarse level

at which grids

are created

Real > 0, < 1

0.7

amr.n_error_buf

radius of additional

tagging around

already tagged cells

Integer >= 0

1

amr.n_error_buf_{x,y}

radius of additional

tagging around

already tagged

cells in x or y

Integer >= 0;

Can specify up

to one per ref. level

1

amr.blocking_factor

grid size must

be a multiple

of this

Integer > 0

2

amr.blocking_factor_{x,y}

grid size in

{x,y} must be

multiple of this

Integer > 0;

Can specify up to

one per ref. level

1

amr.refine_grid_layout

refine grids more if

# of processors

\(>\) # of grids

0 if false, 1 if true

1

amr.do_substep

whether to sub-step finer

levels in time

0 if false, 1 if true

NOTE: true will

trigger Assert

failure

0

Notes

  • if amr.max_level = 0 then you do not need to set amr.ref_ratio_vect or amr.regrid_int.

  • amr.n_error_buf, remora.max_grid_size and amr.blocking_factor can be read in as a single value which is assigned to every level, or as multiple values, one for each level

  • amr.max_grid_size at every level must be even

  • amr.blocking_factor at every level must be a power of 2

  • The blocking factor in the z-direction will be forced to a large value automatically to guarantee the domain will not be decomposed in the z-direction

  • the domain size remora.n_cell must be a multiple of amr.blocking_factor at level 0

  • amr.max_grid_size must be a multiple of amr.blocking_factor at every level

  • the substepping turned on by amr.do_substep is NOT implemented yet so will trigger an Assert.

Examples of Usage

  • amr.max_level = 2
    would allow a maximum of 2 refined levels in addition to the coarse level. Note that these additional levels will only be created only if the tagging criteria are such that cells are flagged as needing refinement. The number of refined levels in a calculation must be \(\leq\) amr.max_level, but can change in time and need not always be equal to amr.max_level.
  • amr.ref_ratio = 2 6
    would set factor 2 refinement between levels 0 and 1, and factor 3 refinement between levels 1 and 2 (6 between levels 0 and 2). Note that you must have at least amr.max_level values of amr.ref_ratio (Additional values may appear in that line and they will be ignored).
  • amr.ref_ratio_vect = 2 4 1
    would set factor {2 in x-dir, 4 in y-dir, 1 in z-dir} refinement between all adjacent levels. Note that you must specify 3 values, one for each coordinate direction.
  • amr.regrid_int = 2 2
    tells the code to regrid every 2 steps. Thus in this example, new level-1 grids will be created every 2 level-0 time steps, and new level-2 grids will be created every 2 level-1 time steps.
  • amr.regrid_file = fixed_grids
    In this case the list of grids at each fine level are contained in the file fixed_grids, which will be read during the gridding procedure. These grids must not violate the amr.max_grid_size criterion. The rest of the gridding procedure described below will not occur if amr.regrid_file is set.
  • amr.grid_eff = 0.9
    During the grid creation process, at least 90% of the cells in each grid at the level at which the grid creation occurs must be tagged cells. Note that this is applied at the coarsened level at which the grids are actually made, and before amr.max_grid_size is imposed.
  • amr.max_grid_size = 64
    The final grids will be no longer than 64 cells on a side at every level.
  • amr.max_grid_size = 64 32 16
    The final grids will be no longer than 64 cells on a side at level 0, 32 cells on a side at level 1, and 16 cells on a side at level 2.
  • amr.blocking_factor = 32
    The dimensions of all the final grids will be multiples of 32 at all levels.
  • amr.blocking_factor = 32 16 8
    The dimensions of all the final grids will be multiples of 32 at level 0, multiples of 16 at level 1, and multiples of 8 at level 2.

Simulation Time

List of Parameters

Parameter

Definition

Acceptable Values

Default

remora.max_step

maximum number of level 0 time steps

Integer >= 0

-1

remora.stop_time

final simulation time

Real >= 0

-1.0

remora.start_time

initial simulation time

Real >= 0

0.0

remora.time_ref

reference date of the

model clock, and with it

the calendar. See below.

yyyymmdd

.dd, or

0, -1, -2

0.0

Reference date and calendar

remora.time_ref is the reference date the model clock is measured from, and it also selects the calendar, exactly as ROMS TIME_REF does:

time_ref

calendar

epoch

year length

yyyymmdd.dd

proleptic Gregorian

the date given

365.2425 d

0

proleptic Gregorian

0001-01-01 00:00:00

365.2425 d

-1

360_day: twelve 30-day months, no leap years

0000-12-30 00:00:00

360 d

-2

Gregorian, as a truncated Julian day

1968-05-23 00:00:00

365.25 d

The fractional part of a positive value is a time of day, so remora.time_ref = 20020115.5 is 15 January 2002 at 12:00. A value below -2 names no calendar and is an error.

Model time is elapsed time since that epoch, so remora.start_time offsets the run within the calendar the way ROMS DSTART does. With the default time_ref = 0, a run starting on 1 January 2020 sets remora.start_time = 63713433600.

Only features that need a date consult this: at present the time-dependent atmospheric CO2 options of the Fennel biology model, see Fennel Biology. The conversion is remora_caldate in Source/Utils/REMORA_DateClock.H, a port of ROMS caldate.

Notes

To control the number of time steps, you can limit by the maximum number of level-0 time steps (remora.max_step), or the final simulation time (remora.stop_time), or both. The code will stop at whichever criterion comes first. Note that if the code reaches remora.stop_time then the final time step will be shortened so as to end exactly at remora.stop_time, not pass it.

Examples of Usage

  • remora.max_step = 1000

  • remora.stop_time = 1.0

will end the calculation when either the simulation time reaches 1.0 or the number of level-0 steps taken equals 1000, whichever comes first.

Time Step

List of Parameters for Single-Rate

Parameter

Definition

Acceptable

Values

Default

remora.cfl

Courant number applied to the advective and external gravity wave limits. Only used if fixed_dt is unset

Real > 0

and <= 1

0.8

remora.fixed_dt

set level 0 dt

as this value

value regardless of cfl

or other settings

Real > 0

unused if

not set

remora.ndtfast

number of barotropic steps taken per baroclinic step. The fast dt is slow dt / this ratio. Deprecated alias: fixed_ndtfast_ratio

int > 0

must be set

remora.change_max

factor by which dt can grow

in subsequent steps

Real >= 1

1.1

Examples of Usage

  • remora.cfl = 0.9
    scales the estimated timestep, and is only relevant if fixed_dt is not set. The estimate is the smaller of an advective limit and an external gravity wave limit, each a maximum over the wet cells (mskr > 0.5) of the level:
    dt_adv  = cfl / max( |u|*pm, |v|*pn, |w|/Hz )
    dt_grav = cfl * ndtfast / max( sqrt(g*h) * sqrt(pm**2 + pn**2) )
    dt      = min(dt_adv, dt_grav)
    pm and pn are the per-cell 1/dx and 1/dy metrics, so stretched and curvilinear grids are handled; Hz is the layer thickness and h the bathymetry. ndtfast is remora.ndtfast: the baroclinic step only has to resolve the external gravity wave to within the number of barotropic substeps taken per baroclinic step.
    The gravity wave term is what keeps the estimate finite for a run started from rest, where every velocity is zero. The estimate does not include the internal gravity wave speed, so a large remora.ndtfast can yield a baroclinic step that does not resolve the internal modes; lower remora.cfl or set remora.fixed_dt in that case.
  • remora.change_max = 1.1
    allows the time step to increase by no more than 10% in this case. Note that the time step can shrink by any factor; this only controls the extent to which it can grow.
  • remora.fixed_dt = 1.e-4
    sets the level-0 time step to be 1.e-4 for the entire simulation, ignoring the other timestep controls.

Restart Capability

See Checkpoint / Restart for how to control the checkpoint/restart capability.

PlotFiles

See Plotfiles for how to control the types and frequency of plotfile generation.

Screen Output

List of Parameters

Parameter

Definition

Acceptable Values

Default

amr.v

verbosity of Amr.cpp

0 or 1

remora.v

remora.v

verbosity of REMORA

functions

  • 0: none

  • 1: integrated/max quantities

  • 2: print boxes

0

remora.sum_interval

how often (in level-0

time steps) to to compute

integral quantities

Integer

-1

Examples of Usage

  • remora.sum_interval = 2
    if remora.sum_interval \(> 0\) then the code computes and prints certain integral quantities, such as total mass, momentum and energy in the domain every remora.sum_interval level-0 steps. In this example the code will print these quantities every two coarse time steps. The print statements have the form
    TIME= 1.91717746 MASS= 1.792410279e+34
    for example. If this line is commented out or if remora.v \(<= 0\) then it will not compute and print these quantities.

Included terms

List of Parameters

Parameter

Definition

Acceptable Values

Default

remora.use_coriolis

Include Coriolis terms.

true / false

false

remora.use_curvilinear_grid

Add curvilinear grid terms

for advection

true / false

false

remora.use_prestep

Do prestep terms. Only for

debugging purposes.

true / false

true

remora.use_uv3dmix

Include harmonic viscosity.

Only for debugging purposes.

true / false

true

Physics Parameters

List of Parameters

Parameter

Definition

Acceptable

Values

Default

remora.ggrav

Gravitational field strength

[kg m/s^2]

Real number

9.81

remora.eos_type

Which equation of state to use.

Nonlinear is UNESCO

Linear or

Nonlinear

Linear

remora.R0

Background density [kg/m^3]

used in Linear Equation of

State. May be used in setup

of some problems.

Real number

1028

remora.S0

Background salinity

(nondimensional) used in

Linear Equation of State

State. May be used in setup

of some problems.

Real number

35

remora.T0

Background temperature

(Celsius) used in

Linear Equation of State

State. May be used in setup

of some problems.

Real number

5

remora.Tcoef

Linear EOS parameter

(1/Celsius)

Real number

1.7e-4

remora.Scoef

Linear EOS parameter

(nondimensional)

Real number

0.0

remora.rho0

Mean density (kg/m^3) used

when Boussinesq approx is

inferred

Real number

1025

remora.coriolis_type

Type of Coriolis forcing.

beta_plane uses a linear

approximation. analytic is

calculated from a function in

prob.cpp, and netcdf is

read from the netcdf grid file

beta_plane /

analytic /

netcdf

beta_plane

remora.coriolis_f0

f-plane constant for

Coriolis param

\(f = f_0 + \beta (y - y_c)\)

when using beta plane Coriolis

type. \(y\) is measured from

the southern domain boundary,

\(y_c\) is the domain center

Real number

0.0

remora.coriolis_beta

beta-plane constant for

Coriolis param

\(f = f_0 + \beta (y - y_c)\)

when using beta plane Coriolis

type. \(y\) is measured from

the southern domain boundary,

\(y_c\) is the domain center

Real number

0.0

remora.horizontal_mixing_type

Horizontal mixing type.

analytic means function is

specified in prob.cpp.

scaled_to_grid scales harmonic

viscosity/diffusivity by the grid

cell area. Equivalent to DIFF_GRID

and VISC_GRID in ROMS.

analytic /

constant

/ scaled_to_grid

analytic

remora.scaled_to_grid_amr_scaling

AMR scaling behavior for

scaled_to_grid and constant

coefficients on refined levels.

linear decreases coefficients in

proportion to the horizontal

refinement ratio.

none /

linear

none

remora.visc2

Constant horizontal viscosity,

everywhere. Needed when

horizontal_mixing_type is

constant or scaled_to_grid

(in this case, it is the maximum

viscosity over the domain).

Real number

0.0

remora.tnu2_salt

Constant horizontal diffusivity,

everywhere for salt.

Needed when

horizontal_mixing_type is

constant or scaled_to_grid

(in this case, it is the maximum

salt diffusivity over the domain).

Real number

0.0

remora.tnu2_temp

Constant horizontal diffusivity,

everywhere for temperature.

Needed when

horizontal_mixing_type

is constant or scaled_to_grid

(in this case, it is the maximum

temperature diffusivity over the

domain).

Real number

0.0

remora.nscalar

Number of passive (dye) scalars

in addition to temperature and

salinity. Does not count biology

tracers.

Integer >= 0

0

remora.tnu2_scalar

Constant horizontal diffusivity,

everywhere for passive scalar.

Needed when

horizontal_mixing_type

is constant or scaled_to_grid

(in this case, it is the maximum

scalar diffusivity over the domain).

Real number

0.0

remora.tnu2_{var}

Constant horizontal diffusivity for

one named tracer, overriding

tnu2_scalar. {var} is a tracer

name: tracer, tracer_1,

NO3, and so on. tnu2_temp and

tnu2_salt above are this same form

for the first two components.

Real number

value of

tnu2_scalar

remora.harmonic_mixing_type

Whether harmonic mixing (tracers)

is calculated along s- or geopotential

surfaces.

s /

geopotential

s

remora.vertical_mixing_type

Vertical mixing type. analytic

function is specified in

prob.cpp.

analytic /

GLS

analytic

remora.gls_stability_type

Stability function to use for GLS

Canuto_A /

Canuto_B /

Galperin

Canuto_A

remora.Akv_bak

Minimum/initial value of Akv

Real number

5.0e-6

remora.Akt_bak

Minimum/initial value of Akt, applied

to temperature and salinity.

Real number

1.0e-6

remora.Akt_bak_temp

Minimum/initial value of Akt for

temperature, overriding Akt_bak.

Real number

value of

Akt_bak

remora.Akt_bak_salt

Minimum/initial value of Akt for

salinity, overriding Akt_bak.

Passive tracers mix with this value.

Real number

value of

Akt_bak

remora.bulk_fluxes

Whether to use bulk fluxes

parametrization

true / false

false

Passive scalars

REMORA always includes temperature and salinity as the first two conserved state variables. Passive scalars begin at component Tracer_comp = 2, and the biology tracers, if any, follow them:

temp  salt  | tracer  tracer_1  ...  | NO3  NH4  ...
0     1     | Tracer_comp = 2        | Bio_comp = 2 + nscalar

The total number of conserved components is

\[ncons = 2 + \texttt{remora.nscalar} + n_{bio}\]

so remora.nscalar counts only the passive scalars — not temperature, salinity, or biology tracers.

For example:

  • remora.nscalar = 1 gives temp, salt, and tracer.

  • remora.nscalar = 2 gives temp, salt, tracer, and tracer_1.

Additional passive scalars continue with the names tracer_2, tracer_3, and so on.

remora.nscalar defaults to 0, so dye is opt-in: a run carries temperature and salinity only until an input asks for more. A tracer nothing asked for is still advected and diffused every step, and still has to be accounted for in plotfiles and in boundary and climatology files, so carrying one by default made runs that never mentioned dye behave as though they had.

Dye and biology coexist freely, so remora.nscalar = 2 with a Fennel model carrying 11 tracers gives 15 components in the order shown above. See Fennel Biology.

With remora.ic_type = netcdf each dye’s initial field is read from the initial file under its own name – tracer, tracer_1, and so on – stored with the same (ocean_time, s_rho, eta_rho, xi_rho) layout ROMS uses for temp and salt. The read is the last thing init_data_from_netcdf does: dye follows remora.ic_type along with the physical fields rather than having an initialization-source flag of its own the way biology does.

Unlike temp and salt, these fields are optional. A dye whose variable the initial file does not carry starts at zero, and the run prints the names it did not find, so an initial file written before the run carried dye still works unchanged and an idealized file need only carry the dyes it actually wants to specify. The same read runs on remora.nc_init_file_hires when initial data is given on a high-resolution level.

A dye’s other file-driven inputs follow the same naming convention – tracer_west and friends for boundary data, tracer for a climatology field, and tracer_NudgeCoef for a spatially varying nudging coefficient – but unlike the initial field they are not optional. A boundary condition or nudging flag that calls for data the file does not have stops the run and names what is missing; only tracer_NudgeCoef falls back, to the constant derived from remora.tnudg. See Boundary conditions for individual tracers and Climatology nudging for individual tracers.

Horizontal and vertical mixing coefficients follow different rules, as they do in ROMS.

Horizontal diffusivity is per tracer. remora.tnu2_scalar sets the value every tracer takes by default – biology tracers included – and remora.tnu2_{var} overrides a single tracer by name:

remora.tnu2_scalar  = 5.0      # every dye and biology tracer
remora.tnu2_NO3     = 50.0     # except NO3

remora.tnu2_temp and remora.tnu2_salt are the pre-existing spelling of the same per-name form for the first two components, and they still default to zero rather than to tnu2_scalar.

Vertical diffusivity is not. ROMS computes and stores Akt for the active tracers alone, and every passive tracer – dye and biology alike – mixes with the salinity coefficient (ltrc=MIN(itrc,NAT) in pre_step3d and step3d_t). REMORA does the same: vec_Akt has two components, and akt_comp() in REMORA_IndexDefines.H performs the mapping.

remora.Akt_bak      = 1.0e-6   # temperature and salinity
remora.Akt_bak_temp = 1.0e-5   # except temperature
remora.Akt_bak_salt = 1.0e-6   # salinity, and every passive tracer with it

There is deliberately no remora.Akt_bak_{var} for a passive tracer; supplying one is an error rather than a silent no-op, since it would name a coefficient that no part of the vertical diffusion reads.

Note that tnu2 is only consulted when remora.horizontal_mixing_type is constant or scaled_to_grid; under the default analytic the problem’s init_analytic_hmix hook sets the coefficients itself. The same is true of Akt and init_analytic_vmix; the hooks in Source/Prob/ set the two active-tracer components directly and ignore Akt_bak, but this can be changed in other problems.

The current analytic initial condition hooks seed the first dye tracer only, so with more than one dye the rest start at zero. Again, this can be changed by the user in other problems as needed.

The remora.sum_interval diagnostic reports a volume-weighted sum for every tracer, labelled by name. Both plotfile writers check every tracer they are about to write for NaN and inf, and name the offending tracer if one is found; a tracer absent from remora.plot_vars_3d is not checked. Both writers also accept stflux_{var} in remora.plot_vars_2d for any tracer, so the surface flux array can be inspected per tracer. Only the temperature and salinity entries are ever filled, by the bulk-flux or coupling paths; the rest read zero, because Fennel’s air-sea gas exchange acts on the tracer directly rather than through that array.

Refinement accepts any tracer name as its field_name, so a biology tracer can drive AMR:

remora.refinement_indicators = hi_no3
remora.hi_no3.max_level      = 1
remora.hi_no3.field_name     = NO3
remora.hi_no3.value_greater  = 15.0

River sources also work per tracer; see River input for individual tracers.

Scaled-to-grid horizontal mixing

If remora.horizontal_mixing_type = "scaled_to_grid", REMORA follows the ROMS-style approach of scaling horizontal harmonic mixing coefficients by the grid cell area.

\[G(i,j) = \sqrt{\frac{1}{pm(i,j)\,pn(i,j)}}\]
\[\nu(i,j) = \nu_0 \frac{G(i,j)}{\max(G)}, \qquad \kappa_n(i,j) = \kappa_{0,n} \frac{G(i,j)}{\max(G)}\]

where \(\nu_0\) is remora.visc2 and \(\kappa_{0,n}\) are the tracer diffusivities (remora.tnu2_temp, remora.tnu2_salt, remora.tnu2_scalar). This ensures the maximum coefficient over the normalization region equals the user-specified value, while varying spatially with grid size. Note that if the largest cell area occurs over land, then the maximum over wet cells (and thus what you see after applying mask_rho in post-processing) may be smaller than the user-specified value.

  • The normalization max(G) is computed as a global maximum over the level-0 grid (rho points at the surface, i.e. k=0) and does not use land/sea masks. Equivalently, it uses the maximum grid-cell area \(A(i,j) = 1/(pm\,pn)\) via \(\max(G)=\sqrt{\max(A)}\).

  • AMR refinement scaling: if remora.scaled_to_grid_amr_scaling = "linear", then on AMR level \(\ell\) the coefficients are additionally scaled by the cumulative horizontal refinement ratio.

    \[\frac{1}{\prod_{m=0}^{\ell-1} \sqrt{r_x(m)\,r_y(m)}}\]

    For example, with a refinement ratio of 5 5 1, level 1 coefficients are reduced by a factor of 5 relative to level 0.

  • Ghost cells for the coefficient fields are filled using the same periodic/foextrap boundary fill used elsewhere in REMORA. This is done so stencil-based operations (e.g., the psi-point averaging for visc2_p) have valid neighbor values near domain boundaries and coarse/fine interfaces. Output (plotfiles / NetCDF) writes only the valid region.

When this option is active, the spatially varying coefficients are automatically included in plot output as 2D (vertically homogeneous) fields:

  • visc2 (horizontal viscosity at rho points)

  • diff2_temp, diff2_salt, diff2_tracer (horizontal diffusivities at rho points)

  • additional passive scalars appear as diff2_tracer_1, diff2_tracer_2, and so on

Geopotential rotated harmonic tracer diffusion

Harmonic tracer diffusion can be rotated along geopotential (constant-\(z\)) surfaces when remora.harmonic_mixing_type = "geopotential". This formulation reduces spurious diapycnal mixing over steeply sloping bathymetry, where terrain-following \(s\)-levels intersect isopycnal surfaces. This approach corresponds to the ROMS MIX_GEO_TS option (Nonlinear/t3dmix2_geo.h), although full algorithmic details are not documented in the ROMS implementation.

Let \(z_r(i,j,k)\) denote the geopotential (rho-point) vertical coordinate. Local surface slopes are defined using metric-weighted discrete differences:

\[\begin{split}\begin{aligned} S_x &\equiv dZdx \approx c_x(i,j)\,(z_r(i,j,k)-z_r(i-1,j,k)) \\ S_y &\equiv dZde \approx c_y(i,j)\,(z_r(i,j,k)-z_r(i,j-1,k)) \end{aligned}\end{split}\]

where \(c_x\) and \(c_y\) are C-grid metric factors that include inverse grid spacing and land–sea masking. These are constructed as face-centered averages:

\[ \begin{align}\begin{aligned}c_x(i,j) = \tfrac{1}{2}\left(pm(i,j) + pm(i-1,j)\right)\, msku(i,j),\\c_y(i,j) = \tfrac{1}{2}\left(pn(i,j) + pn(i,j-1)\right)\, mskv(i,j).\end{aligned}\end{align} \]

The rotated diffusion operator can be interpreted in flux-form as:

\[F_x = -K_h\,H\left(\partial_x T - S_x\,\partial_z T\right), \qquad F_y = -K_h\,H\left(\partial_y T - S_y\,\partial_z T\right),\]

where \(K_h\) is the harmonic diffusivity and \(H\) is the face-averaged vertical cell thickness (Hz).

In practice, all gradients are computed using finite differences:

  • dTdx, dTde: centered horizontal differences on cell faces

  • dTdz: vertical differences along rho columns

  • dZdx, dZde: metric-weighted slope fields

Diffusivity is interpolated to cell faces and combined with face-averaged vertical thicknesses prior to flux construction.

The x-face flux (FX) is computed as a face-centered diffusivity–thickness product multiplied by a slope-corrected horizontal tracer gradient:

\[FX_{i+1/2,j,k} = K_{i+1/2,j,k}\,H_{i+1/2,j,k} \left[ dTdx_{i+1/2,j,k} - \mathcal{R}_x(S_x, \partial_z T) \right],\]

where \(\mathcal{R}_x\) denotes a slope-dependent estimate of how much vertical stratification contaminates the horizontal gradient. This term uses a sign-aware (min/max) stencil that selects locally appropriate vertical neighbor averages of \(\partial_z T\) based on the sign of the slope.

Specifically, the reconstruction is given by:

\[\mathcal{R}_x = \tfrac{1}{2}\Big( \min(S_x,0)\,(dTdz_{\text{down}}+dTdz_{\text{up}+1}) + \max(S_x,0)\,(dTdz_{\text{down}+1}+dTdz_{\text{up}}) \Big).\]

The y-face flux (FE) is constructed analogously using \(S_y\) and the corresponding y-direction stencil.

A separate vertical coupling term (FS) accounts for cross-directional slope–gradient interactions between horizontal and vertical derivatives. It is constructed using similar sign-dependent decompositions (min/max splitting) that select locally consistent horizontal and vertical neighbor contributions.

List of GLS-specific parameters

Parameter

Definition

Acceptable Values

Default

remora.gls_P

Real number

3.0

remora.gls_M

Real number

1.5

remora.gls_N

Real number

-1.0

remora.gls_Kmin

Real number

7.6e-6

remora.gls_Pmin

Real number

1.0e-12

remora.gls_cmu0

Real number

0.5477

remora.gls_c1

Real number

1.44

remora.gls_c2

Real number

1.92

remora.gls_c3m

Real number

-0.4

remora.gls_c3p

Real number

1.0

remora.gls_sigk

Real number

1.0

remora.gls_sigp

Real number

1.3

remora.Akk_bak

Initial/minimum value of Akk

Real number

5.0e-6

remora.Akp_bak

Initial/minimum value of Akp

Real number

5.0e-6

List of surface forcing parameters

Parameter

Definition

Acceptable Values

Default

remora.smflux_type

Input format for surface momentum

flux if using. analytic specified

in prob.cpp; netcdf from file.

analytic or

netcdf

analytic

remora.wind_type

Input format for surface wind speed,

if using. analytic specified in

prob.cpp; netcdf from file.

analytic or

netcdf

analytic

List of Bulk Fluxes parameters

Bulk-flux atmospheric inputs use per-variable source selectors when not received from the driver in a coupled simulation. The source selectors accept constant, analytic, or netcdf. lwrad_type and eminusp_type also accept computed, which uses REMORA’s internal longwave or evaporation-minus-rain diagnostic path.

The source selector parameters are:

Parameter

Definition

Acceptable values

Default

remora.uwind_type

Source for u-direction wind

constant, analytic, netcdf

analytic

remora.vwind_type

Source for v-direction wind

constant, analytic, netcdf

analytic

remora.tair_type

Source for air temperature Tair

constant, analytic, netcdf

constant

remora.qair_type

Source for air humidity qair

constant, analytic, netcdf

constant

remora.pair_type

Source for air pressure Pair

constant, analytic, netcdf

constant

remora.swrad_type

Source for shortwave radiation swrad

constant, analytic, netcdf

constant

remora.lwrad_type

Source for external longwave radiation

computed, constant, analytic, netcdf

computed

remora.cloud_type

Source for cloud fraction

constant, analytic, netcdf

constant

remora.rain_type

Source for precipitation rate

constant, analytic, netcdf

constant

remora.eminusp_type

Source for prescribed EminusP

computed, constant, analytic, netcdf

computed

The legacy paired wind selector remora.wind_type is still accepted, with accepted values analytic or netcdf. When remora.uwind_type or remora.vwind_type is not set, remora.wind_type sets the corresponding wind component source.

Constant-valued bulk inputs are set with:

Parameter

Definition

Acceptable values

Default

remora.uwind

Constant u-direction wind [m/s

Real number

0.0

remora.vwind

Constant v-direction wind [m/s]

Real number

0.0

remora.air_temperature

Constant air temperature [C]

Real number

23.567

remora.air_humidity

Constant humidity [fraction or kg/kg]

Real number

0.776

remora.air_pressure

Constant air pressure [hPa]

Real number

1013.48

remora.surface_radiation_flux

Constant shortwave radiation [W/m^2]

Real number

0.0

remora.longwave_radiation_flux

Constant external longwave [W/m^2]

Real number

0.0

remora.cloud

Constant cloud cover fraction

0 to 1

0.0

remora.rain

Constant precipitation rate [kg/m^2/s]

Real number

0.0

remora.EminusP

Constant prescribed E-P [kg/m^2/s]

Real number

0.0

Additional bulk-flux controls:

Parameter

Definition

Acceptable values

Default

remora.longwave_down

Treat external longwave as downward radiation and compute net longwave

true / false

false

remora.longwave_is_net

Interpret external longwave as net

longwave and use it as-is

true / false

false

remora.longwave_netcdf_varname

Name of the NetCDF longwave variable

String

lwrad

remora.qair_is_percent

Convert NetCDF qair from 0-100 percent to 0-1 fraction

true / false

false

remora.eminusp_correct_ssh

Adjust sea surface height for active E-P source

true / false

false

remora.blk_ZQ

Height [m] of humidity measurements

Real number

10.0

remora.blk_ZT

Height [m] of temperature measurements

Real number

10.0

remora.blk_ZW

Height [m] of wind measurements

Real number

10.0

When a source selector is constant, spatially uniform values are set from values specified in the inputs file.

When a source selector is analytic, REMORA calls the problem-defined init_analytic_bulk_flux hook and passes pointers only for the fields that were selected as analytic.

When a source selector is netcdf, the field is read from remora.nc_frc_file using variable names Uwind, Vwind, Tair, qair, Pair, swrad, rain, cloud, EminusP, and the configured longwave variable name. Multiple files may be specified, in which case in which case REMORA concatenates their time axes in the order listed in the inputs file. Forcing variables must have the same dimensions as the level 0 (coarsest) model grid. Time interpolation is performed automatically based on the simulation time at level 0, and fields are interpoalted to finer AMR levels as needed.

The legacy boolean inputs Tair_from_netcdf, qair_from_netcdf, Pair_from_netcdf, srflx_from_netcdf, longwave_down_from_netcdf, rain_from_netcdf, cloud_from_netcdf, and EminusP_from_netcdf are still accepted for compatibility; setting one to true maps the corresponding *_type selector to netcdf. The legacy longwave_netcdf_is_net input is also accepted as an alias for longwave_is_net; when true and no lwrad_type is provided, it selects netcdf to preserve existing inputs.

The qair_is_percent flag should be set to true if the relative humidity in the NetCDF file is stored as a percentage (0-100) rather than as a fraction (0-1).

Numerical Algorithms

List of Parameters

Parameter

Definition

Acceptable

Values

Default

remora.tracer_horizontal_advection_scheme

Scheme for

horizontal advection

of tracers

upstream3,

centered4

upstream3

remora.uv_horizontal_advection_scheme

Scheme for

horizontal advection

of momenta

upstream3,

centered2

upstream3

Vertical Stretch parameters

List of Parameters

Parameter

Definition

Acceptable Values

Default

remora.theta_s

Stretching parameter for

surface refinement of

vertical S-grid

\(0 \leq \theta_S \leq 10\)

3.0

remora.theta_b

Stretching parameter for

bottom refinement of

vertical S-grid

\(0 \leq \theta_B \leq 4\)

0.0

remora.tcline

Surface/bottom layer width

[m] in vertical S-grid

Positive number

150

These parameters are used to calculate the vertical S-grid stretch/transform functions detailed in Vertical S-Coordinate.

Climatology parameters

List of Parameters

Parameter

Definition

Acceptable

Values

Default

remora.do_m3_clim_nudg

Whether to nudge 3D

momentum variables

to climatology

true / false

false

remora.do_m2_clim_nudg

Whether to nudge 2D

momentum variables

to climatology

true / false

false

remora.do_{var}_clim_nudg

Whether to nudge tracer

{var} to climatology.

{var} is any tracer

name: temp, salt,

NO3, …

true / false

false

remora.nc_clim_his_file

NetCDF file name(s) for

climatology data

string or

list

of strings

must be set if one of

do_*_clim_nudg

flags is true

remora.nc_clim_coeff_file

NetCDF file name for

climatology nudging

coefficients

string

must be set if one of

do_*_clim_nudg

flags is true

remora.clim_ubar_time_varname

name of time variable

for ubar climatology

string

ocean_time

remora.clim_vbar_time_varname

name of time variable

for vbar climatology

string

ocean_time

remora.clim_u_time_varname

name of time variable

for u climatology

string

ocean_time

remora.clim_v_time_varname

name of time variable

for v climatology

string

ocean_time

remora.clim_{var}_time_varname

name of time variable

for the climatology of

tracer {var}

string

ocean_time

Note

For AMR runs, climatology fields are read on level 0 and temporally interpolated there. REMORA then interpolates those fields to finer AMR levels for nudging updates. remora.nc_clim_his_file may be a single file or a space-separated list of files. When multiple files are provided, they must be listed in time series order.

Climatology nudging for individual tracers

Every cell-centered tracer can be nudged toward its own climatology, not just temperature and salinity. The flag is keyed by the tracer’s own name, so a run carrying nitrate uses

remora.do_NO3_clim_nudg = true

exactly as temperature uses remora.do_temp_clim_nudg. Each tracer turned on this way needs two things in the input files:

  • A 3D field named for the tracer in remora.nc_clim_his_file: temp, salt, NO3, and so on. This is the ROMS convention, and it is the same name the variable carries elsewhere. If the field is missing, REMORA aborts and names it rather than failing deep inside the NetCDF reader.

  • Optionally, a spatially varying nudging coefficient named {var}_NudgeCoef in remora.nc_clim_coeff_file (in inverse days), again following ROMS: temp_NudgeCoef, salt_NudgeCoef, NO3_NudgeCoef.

The coefficient is optional in a way the climatology field is not. A tracer with no {var}_NudgeCoef in the file falls back to the constant coefficient derived from remora.tnudg, and REMORA prints which tracers fell back. This means a nudging coefficient file written for temperature and salinity alone still works when biology tracers are nudged: those tracers simply use the uniform timescale.

Each tracer may also take its own climatology time axis via remora.clim_{var}_time_varname, which defaults to ocean_time.

Rivers (point sources)

These parameters are used to configure NetCDF-specified river-like point sources and sinks.

Parameter

Definition

Acceptable

Values

Default

remora.do_rivers

Whether to do rivers.

Equiavlent to LuvSrc in

ROMS. Sources always

apply momentum

true / false

false

remora.nc_river_file

NetCDF file(s) for river

sources

string or

list

must be set if

do_rivers

remora.riv_time_varname

Name of time variable

string

river_time

remora.do_rivers_temp

Whether rivers are

temperature sources

true / false

true; only used

if do_rivers

remora.do_rivers_salt

Whether rivers are

salinity sources

true / false

true; only used

if do_rivers

remora.do_rivers_scalar

Whether rivers are passive

scalar sources. Default for

every dye tracer.

true / false

false; only used

if do_rivers

remora.do_rivers_{var}

Whether rivers are a source of

tracer {var}. Overrides the

defaults above.

true / false

see below

Note

remora.nc_river_file may be either a single file or a space-separated list of files. If multiple river files are provided, they must be listed in time series order.

River input for individual tracers

Any cell-centered tracer can take river input, keyed by the tracer’s own name, so temperature and salinity keep remora.do_rivers_temp and remora.do_rivers_salt and a biology tracer uses

remora.do_rivers_NO3 = true

The defaults are: temperature and salinity on, every passive (dye) scalar following remora.do_rivers_scalar, and biology tracers off. Biology defaults off because a river concentration for a biogeochemical tracer has to be a deliberate choice, not something inherited from a dye setting. All of these are ignored unless remora.do_rivers is true.

Each enabled tracer needs a field named for it in remora.nc_river_file, with dimensions (river_time, s_rho, river), following the ROMS convention: river_temp, river_salt, river_tracer, river_NO3, and so on. If the field is missing REMORA aborts and names it, rather than failing inside the NetCDF reader.

Tracer fields are concentrations, so a tracer given without an s_rho dimension, as (river_time, river), is used unchanged at every vertical level, and REMORA prints a warning naming the field. river_Vshape applies only to river_transport, where it distributes the total transport over the vertical as ROMS does with Qsrc = Qbar * Qshape; it is not applied to tracers.

Runtime Error Checking

Through AMReX functionality, REMORA supports options to raise errors when NaNs, division by zero, and overflow errors are detected. These checks are activated at runtime using the input parameters below.

Note

When running on Macs using the Apple-Clang compilers with optimization (DEBUG = FALSE in the GNUmakefile), these checks may lead to false positives due to optimizations performed by the compiler and the flags should be turned off. It is still possible to run with these error checks with Apple-Clang debug builds.

List of Parameters

Parameter

Definition

Acceptable Values

Default

amrex.fpe_trap_invalid

Raise errors for NaNs

0 / 1

0

amrex.fpe_trap_zero

Raise errors for divide by zero

0 / 1

0

amrex.fpe_trap_overflow

Raise errors for overflow

0 / 1

0