1) How exactly do changes in zeta affect biogeochemical tracer concentrations?
2) How are other ROMS modelers implementing biogeochemical tracer fluxes associated with freshwater runoff from land? Point sources? Precipitation-like runoff? Altering the surface flux boundary conditions? Something else?
Much longer query:
For background, I'm working with a descendent of the Hedstrom sea-ice-and-extra-bio variant of ROMS. My domains include a few different Alaska-centric locations, including a variant of the NEP (northeast Pacific 10k) domain and smaller and/or higher-resolution grids within that (Bering Sea 10k and Bering Shelf 3k grids). I'm also attempting to implement some new biological code (BIO_COBALT) in the Bering10K grid and port our Bering biogeochemical model (BESTNPZ) to the larger NEP grid by merging it with the GOANPZ model. One key way BESTNPZ, GOANPZ, and BIO_COBALT differ is in the way they handle runoff-based biogeochemical fluxes.
This region requires a fair amount of freshwater input from land, not only from large rivers but also along much of the coast to represent sub-grid-scale estuaries. The biogeochemical models also require at minimum runoff-associated iron and carbonate system fluxes to appropriate capture our desired dynamics. All of the above applications currently apply freshwater runoff via the RUNOFF flag (a custom option in the Hedstrom variant that adds runoff as an extra surface salinity flux loss, near-identically to EMINUSP). My understanding is that this option was developed because earlier tests with point sources led to unrealistically high stratification, with a lense of surface freshwater extending well away from the coasts (see Dobbins et al., 2009: 10.1016/j.dsr2.2009.02.004).
With this option, GOANPZ later added corresponding tracer fluxes, applied alongside the RUNOFF-related salinity flux in bulk_fluxes.f/ccsm_flux.F:
Code: Select all
cff=1.0_r8/rhow
! Salinity flux due to runoff
stflx(i,j,isalt) = stflx(i,j,isalt) - &
& cff*runoff(i,j)
! example tracer flux due to runoff
stflx(i,j,iTAlk) = stflx(i,j,iTAlk) + cff*TAFlux(i,j)
My understanding is that this method does *not* actually influence the total mass of water in the grid cell. Because no change in mass occurs, the tracer flux as coded here always leads to an increase in total tracer, even if the the runoff-derived value is lower than the amount in the domain.
Likewise, BIO_COBALT applies a river-derived flux within the biology_tile routine. It also does not appear to consider any dilution effect that would come with the accompanying freshwater input.
Code: Select all
cff_rivr = 1.0d0 / ( rho0 * Hz(i,j,UBk) )
cobalt%jno3(i,j,UBk)= cobalt%jno3(i,j,UBk) + river_no3(i,j)*cff_rivr
Code: Select all
stflx(i,j,iTAlk) = (stflx(i,j,iTAlk) + cff*TAFlux(i,j) &
& + (1._r8 - (cff*runoff(i,j)))*t(i,j,N(ng),nrhs,iTAlk)) &
& - t(i,j,N(ng),nrhs,iTAlk)
Going forward, I have a few options:
1) Keep the BGC code as in GOANPZ and/or BIO_COBALT, but turn on the RUNOFF_SSH flag. This flag alters zeta to account for the added mass from runoff. But does this then affect tracer concentration? I would assume so, and I've been trying to track where various routines switch between referencing the nrhs/nstp/nnew time steps and where those convert between Tunits and m*Tunits in order to answer this question... but I haven't convinced myself one way or the other yet. If it does properly dilute tracers, then that fixes *most* my issues. (It would also dilute tracers without any runoff-associated flux... but I think that's an okay assumption for our applications).
2) If RUNOFF_SSH *doesn't* dilute tracers, I'd need to do something similar to the BESTNPZ logic for all the bio models I'm spinning up. Doable, but a pain, and currently difficult to maintain (would need to be coded into each bio model).
3) Alternatively, I could experiment with using point sources. I understand that the LwSrc option was recently updated so that mass point sources (and their accompanying tracer concentrations) can be added in any grid cell, not just those adjacent to land. Perhaps distributing point sources in the same diffuse manner as we had been doing with runoff would mitigate the runaway stratification issue from years ago while also adding both mass and tracer fluxes in a numerically robust manner?
I'd really love some input from anyone else who has dug into this part of the ROMS code!