NOAA-GFDL/MOM6

Generic tracer runoff fluxes are incorrect if DT_THERM < dt_cpld

Closed this issue · 3 comments

For generic tracers that have a non-zero runoff concentration, the contribution of the runoff to the tracer surface flux is computed separately in MOM_generic_tracer_column_physics:

call g_tracer_get_pointer(g_tracer,g_tracer_name,'stf', stf_array)
call g_tracer_get_pointer(g_tracer,g_tracer_name,'trunoff',trunoff_array)
call g_tracer_get_pointer(g_tracer,g_tracer_name,'runoff_tracer_flux',runoff_tracer_flux_array)
!nnz: Why is fluxes%river = 0?
runoff_tracer_flux_array(:,:) = trunoff_array(:,:) * &
US%RZ_T_to_kg_m2s*fluxes%lrunoff(:,:)
stf_array = stf_array + runoff_tracer_flux_array

The problem is that this routine is called every thermodynamics timestep, but stf is refreshed from the coupler every coupling time step. This means that if DT_THERM < dt_cpld, the tracer runoff is added to stf multiple times. So, on the first thermo timestep after a coupler step, the runoff input is correct, on the second thermo timestep it is twice what it should be, etc.

This is not an issue for GFDL's previous global earth system model runs, which have used a DT_THERM much greater than dt_cpld. This bug has only been encountered now that we've started running regional models with short timesteps.

One way to fix it that I found works is to not add the runoff tracer flux to stf and instead pass it as the optional in_flux_optional argument to applyTracerBoundaryFluxesInOut later in this subroutine.

Is this the best way to fix the issue (I will send a PR if yes)? It seems to me it would be better to have g_tracer_coupler_get do the addition of the runoff tracer flux to the surface flux, but that routine is unaware of the liquid runoff flux and has a note that

!runoff contributes to %stf in GOLD but not in MOM, 
!so it will be added later in the model-dependent driver code (GOLD_generic_tracer.F90)

It does seem that adding the flux via the optional in_flux_optional argument to applyTracerBoundaryFluxesInOut() would work in ALE mode, but this routine is not called in layered mode (as was the case in ESM2G). Instead, the fluxes in the MOM6-specific packages mostly use the sfc_flux arguments to tracer_vertdiff(). We need to be careful to avoid fixing the problems in one configuration, but breaking other configurations.

I think a workable alternative is to add a logical flag to the g_tracer_type type that indicates whether runoff has been added to stf, so that the addition only gets done once after stf has been updated by g_tracer_coupler_get or any other routines. This would minimize disruption to existing logic and code. Going to test this out.

This issue can be closed now that PR #246 has been merged into dev/gfdl.