Output land-surface variables

Submitted by siwei.he on Thu, 09/09/2021 - 09:27

May I know how to output additional variables, such as land-surface related variables? So far, it seems the default output only includes latent and sensible heat flux, surface temperature. Can I output more variables, like soil moisture and temperature of different levels, ground heat flux, runoff, evaportranspiration, snow depth/SWE, et al.

Thank you,

Siwei

Siwei,

The answer depends on what version of the code that you're using. If your code base is older than January of 2021, please find the instructions in the FAQ on this forum. If your code base is more recent than January of 2021, the instructions are slightly different. Please see below:

The following procedure for adding a variable to the output file should be followed. For instructional purposes, we will be looking to add the SWE snow depth over land.

  • First, identify the variable that you want to output by scanning/searching scm/src/GFS_typedefs.meta. In this case, keywords like "snow depth" and "equivalent" probably the most relevant. Two standard names that I see are "lwe_surface_snow", "surface_snow_thickness_water_equivalent_over_land". Both are in the "sfcprop" derived data type in GFS_typedefs.F90, which you can tell by scanning upward from where you found the variable until you find something like:

    [ccpp-arg-table]   
    name = GFS_sfcprop_type   
    type = ddt

    at the beginning of the section of variables containing your variable of choice. This information will come in handy in the next step. Let's choose the first variable. It's local name in GFS_typedefs is snowd and we know that it is in the GFS_sfcprop_type.

  • All SCM output is controlled via code in the scm_output.F90 file. The subroutines within can be classified as those that initialize the variables within the output file (run once at the beginning of the time integration) and those that actually write (append) data to the same file (run at a defined periodicity during the time integration). We will need to modify both to output a new variable. Let's initialize the variable in the output file first. Since there are so many variables that one may need to output, the subroutines are organized by the derived data types found in GFS_typedefs.F90. In this case, we're interested in the sfcprop_type, so we will look for the two subroutines dealing with variables in this data type. There are the output_init_sfcprop() and output_append_sfcprop() subroutines. Within output_init_sfcprop(), we will need to add a new call to the NetCDF_def_var method which takes the following arguments: ncid, var_name, var_type, desc, unit, varid, dims

    • ncid: (integer) the netCDF file id number
    • var_name: (character*) what we want to call this variable in the output file
    • var_type: (integer) netCDF var type (typically NF90_FLOAT)
    • desc: (character*) the description that will be printed in the output file
    • unit: (character*) the units that will be printed in the output file
    • varid: (integer, optional) the netCDF variable id number
    • dims: (integer array, optional) the size of the variable that we will be writing out in the netCDF file, using the previously defined dimensions
  • We can use entries that are already in the subroutine to construct the new statement to add to the subroutine:
    • call NetCDF_def_var(ncid, 'snowd', NF90_FLOAT, "water equivalent snow depth", "mm", dummy_id, (/ hor_dim_id, time_inst_id /))
    • Note that the variable we are writing out only has a horizontal extent (typically 1 for the SCM) and a time dimension, since we want to write out its value at some interval throughout the simulation. In this case, we want to write out the instantaneous value every timestep, so we'll use the "time_inst_id". Other options are "time_diag_id" for variables time-averaged over some diagnostic time interval, and "time_swrad_id/time_lwrad_id" for variables that only have values on the shortwave and longwave radiation timesteps, respectively.
  • Finally, let's modify the output_append_sfcprop subroutine in scm_output.F90. This subroutine has access to any variables within the scm_state or physics derived datatypes. The variable that we want to output is in the physics derived datatype (where all variables defined in GFS_typedefs.F90 are). We will want to add a new call to the NetCDF_put_var method which takes the following arguments: ncid, var_name, var, itt, mult_const
    • ncid: (integer) the netCDF file id number
    • var_name: (character*) what we want called this variable in the output file; should correspond exactly with the NetCDF_def_var call above
    • var: (real array) where the variable is stored in memory
    • itt: (integer) the time array slice in the NetCDF output where to write the data
    • mult_const: (real, optional) an optional number to multiply all values in var
  • We can use entries that are already in the subroutine to construct the new statement to add to the subroutine:
    • call NetCDF_put_var(ncid, 'snowd', physics%Sfcprop%snowd(:), scm_state%itt_out)
    • Note that scm_state%itt_out is an integer counter that is incremented every time instantaneous data is appended to the output file. Other options are scm_state%itt_diag, scm_state%itt_swrad, scm_state%itt_lwrad corresponding to the frequency of writing of this particular variable. Note also that we used information in GFS_typedefs.F90/meta to know where this particular variable is stored in memory so that we can write it out. The output routine has access to all variables in the physics type defined in scm_type_defs.F90. In the physics type, the GFS_Sfcprop_type variable is called Sfcprop. So now we can string together the right names to find it within the nested derived types: physics%Sfcprop%snowd. This is what we will write out.

After compilation and running the model, you can double-check that the variable is indeed written out using 

ncdump -v name_of_your_new_output_variable path/to/your/output.nc

Siwei,

There is a pull request that updates the SCM to use the latest ccpp-physics main, but it is not merged yet. You can see the latest code here:

https://github.com/NCAR/ccpp-scm/pull/272

You can checkout the pull request code using something like the following if you need it before everything is merged to main and working again:

git fetch origin pull/272/head:PR272

git checkout PR272

Then, you'll need to update the ccpp-physics and ccpp-framework repositories:

cd ccpp/framework

git checkout main

git pull origin main

cd ../physics

git fetch origin pull/731/head:PR731

git checkout PR731