ESCOMP / CTSM

Community Terrestrial Systems Model (includes the Community Land Model of CESM)
http://www.cesm.ucar.edu/models/cesm2.0/land/
Other
301 stars 306 forks source link

Implement water tracers for HandleNewSnow and FracH2oSfc #718

Closed billsacks closed 5 years ago

billsacks commented 5 years ago

The next step in the tracerization of CTSM will be HandleNewSnow and FracH2oSfc. These are both things that had been part of CanopyHydrology until ctsm1.0.dev041.

billsacks commented 5 years ago

@swensosc @martynpclark - Do you have any opinions on how I should handle the state update in the else block here (i.e., the last few lines of this code snippet)?:

https://github.com/ESCOMP/ctsm/blob/57adf1ed1f3f5d4b4881277734c6d4b67a392c64/src/biogeophys/SurfaceWaterMod.F90#L97-L117

In order to accommodate water tracers/isotopes, I need to extract the state update into a separate routine that operates on tracers as well as the bulk (and doing the state update in a separate routine is something we want anyway). But I see two options for how to handle it:

(1) Turn this into an explicit flux. So the else block would look like:

          else
             frac_h2osfc(c) = 0._r8
             qflx_too_small_h2osfc_to_soil(c) = h2osfc(c) / dtime
          end if

Then we would do a standard tracer flux calculation based on this bulk flux, followed by a standard state update (where I would also call a routine to truncate small values of h2osfc to 0, to deal with roundoff errors). (For now, to preserve behavior, I'd keep the state update immediately following the flux calculation. Eventually we could move this state update to sometime later for more sophisticated numerics.)

(2) Keep this formulated as it is, with the rationale that an explicit flux is overkill for a situation like this where we're adding the entirety of some state variable to another state variable. In this case, the else block would look like:

          else
             frac_h2osfc(c) = 0._r8
             transfer_too_small_h2osfc_to_soil(c) = .true.
          end if

and then we'd have a separate routine that operates on bulk and all water tracers which looks like:

          do ...
             if (transfer_too_small_h2osfc_to_soil(c)) then
                h2osoi_liq(c,1) = h2osoi_liq(c,1) + h2osfc(c)
                h2osfc(c)=0._r8
             end if
          end do

I am pretty equal on those two options. (2) would be less code and would avoid roundoff-level answer changes (so would save me a bit of time in my testing), but (1) is more in line with the standard pattern of doing things.

Do you have a preference? (Or would you suggest a third option that I'm not seeing?) I suspect I'll run into other situations like this, so I'd like to get some general guidance on what to do in cases like this.

billsacks commented 5 years ago

From discussion with @swensosc - probably go with (1) (using explicit fluxes). I'll plan on that unless @martynpclark chimes in soon with a different opinion.