MODULE model_mod (NOAH)

DART project logo

Jump to DART Documentation Main Index
version information for this file:
$Id: model_mod.html 11626 2017-05-11 17:27:50Z $



The NOAH Land Surface Model and Data Assimilation Research Testbed (DART) may now be used for assimilation experiments. This should be considered an 'alpha' release -- the code has only been tested for a single column configuration of NOAH. The offline 2D driver code: High-Resolution Land Data Assimilation System (HRLDAS) v3.3 (April 2011) is the version used to develop the interface. This must be downloaded and compiled outside the framework of DART.

The simple_driver-v3.3 was deemed suboptimal because of poor restart characteristics. Since the offline 2D driver code can be run at a single gridpoint and has excellent restart characteristics, there are no plans to support the simple-driver-v3.3 version of NOAH.

Any of the variables in the NOAH restart file are available to be adjusted by the assimilation. The list of variables is set though a simple namelist interface. Since we are testing in a column configuration, there is no practical reason not to include all the variables necessary for a bit-for-bit restart: SOIL_T, SOIL_M, SOIL_W, SKINTEMP, SNODEP, WEASD, CANWAT, and QFX. These variables are then adjusted to be consistent with real observations and stuffed back into the same netCDF restart files. Since DART is an ensemble algorithm there are multiple restart files for a single restart time; one for each ensemble member. Creating the initial ensemble of land surface states is an area of active research. At present, it may be sufficient to use a climatological ensemble; e.g., using the restarts for '1 January 00Z' from 50 consecutive years.

The offline hrldas-v3.3 driver is designed to use atmospheric forcing files that cover a VERY short period - about every hour. Consequently, the directories that contain the forcing files get very cluttered for experiments that may cover years, for example. There is reason to believe that the ensemble system will benefit from having unique atmospheric forcing for each ensemble member. A reasonable ensemble size is 50 or 80 or so. You do the math.

DART reads the NOAH namelist &NOAHLSM_OFFLINE from a file called namelist.hrldas for several pieces of information. DART is responsible for starting/stopping NOAH; the restart information is conveyed through the NOAH namelist. Unpleasant Reality #1 : managing the tremendous number of hourly forcing files for every ensemble member is tedious. To facilitate matters, the DART/NOAH system uses a single netCDF file for each ensemble member that contains ALL of the forcing for that ensemble member. The DART advance_model.csh script for NOAH uses the ncks program to extract the required forcing timesteps into the unique forcing files required by NOAH. The simplest way we could think of to provide the location of the 'master' forcing files was by adding a comment in the namelist.hrldas file of the form : FORCING_FILE_DIRECTORY = "/path/to/your/forcing/files" We felt it important to specify this information in the namelist.hrldas file since it is a strong analogue of the traditional NOAH INDIR variable.

For the impatient - skip the fundamentals and get frustrated.

There are several scripts in the DART/models/noah/shell_scripts directory that assist in configuring and running experiments: setup_pmo.csh, run_pmo.csh, setup_filter.csh, and run_filter.csh . The scripts are not intended to be black boxes. You are expected to read them and modify them to your own purpose.

The offline 2D HRLDAS-V3.3

The offline 2D HRLDAS-V3.3 and the development branch of DART was tested and run on a MacBook Pro laptop running OS X 10.7.4 (Lion) with gfortran v 4.5.0. The Noah_hrldas_beta source code was downloaded from the Unified NOAH/LSM website and built - outside the DART framework - to produce a standalone executable.

Trivial modifications to the distributed hrldas makefiles were necessary to compile the Noah_hrldas_beta on a case-insensitive filesystem. All of the original 14 Makefile files have to be changed:

$(CPP) $(CPPFLAGS) $(CPPHRLDAS) $(*).F > $(*).f
$(CPP) $(CPPFLAGS) $(CPPHRLDAS) $(*).F > $(*).f90

i.e. all instances of ".f" must be changed to ".f90". If you do not have a case-insensitive filesystem, the original Makefiles will not need these modifications.

The DART components were built for debugging with the following settings:
   FC = gfortran
   LD = gfortran
   INCS = -I${NETCDF}/include
   LIBS = -L${NETCDF}/lib -lnetcdff -lnetcdf -lcurl -lhdf5_hl -lhdf5 -lz  -lm
   FFLAGS = -g -O0 -ffree-line-length-none -fbounds-check -frecord-marker=4 -ffpe-trap=invalid $(INCS)

A word about NOAH times and dates

HRLDAS-V3.3 has some unusual conventions as pertains the contents of 'restart' files. You should confirm the following to prove it to yourself - outside of the DART framework. Your actual numbers will change, but the point should be obvious.

  1. Assume there is a NOAH restart file:
    RESTART.2009010118_DOMAIN1 containing
           Times = "2009-01-01_18:00:00" ;
           SOIL_M = 0.100843, 0.1324335, 0.1104331, 0.16349 ;
           QFX = 12.03423 ;
  2. Now, run/advance NOAH for a single (1 hour) timestep (i.e. from 18Z to 19Z). The following files are created:
    2009010118.LDASOUT_DOMAIN1 containing
           Times = "2009-01-01_18:00:00" ;
    SOIL_M = 0.1007659, 0.132411, 0.1104217, 0.1634897 ; QFX = 14.90484 ;
    RESTART.2009010119_DOMAIN1 containing
           Times = "2009-01-01_19:00:00" ;
    SOIL_M = 0.1007659, 0.132411, 0.1104217, 0.1634897 ; QFX = 14.90484 ;
    2009010119.LDASOUT_DOMAIN1 containing
           Times = "2009-01-01_19:00:00" ;
           SOIL_M = 0.1006793, 0.1323851, 0.1104083, 0.1634894 ;
           QFX = 17.13207 ;

The contents of the 2009010118.LDASOUT_DOMAIN1 contain the same values as the RESTART.2009010119_DOMAIN1 -- although the names and Times imply they are from different times. The Times in the LDASOUT files are fundamentally "now"casts and reflect the valid time of the model state. This is the time that DART requires.

IMPORTANT: DART reads and modifies the RESTART files. DART internally adjusts the times in the restart files to correspond to the time of the companion LDASOUT file. The Times array is unchanged. NOTE: The DART/NOAH interface uses the Gregorian calendar.

Converting between DART files and NOAH restart files

The information about how the NOAH variables are stored in the DART state vector comes from the order in which the variables are specified in input.nml &model_nml:noah_state_variables , as is the the name of the NOAH restart file. DART also needs to read the namelist.hrldas &NOAHLSM_OFFLINE namelist.

There are two programs - both use the model_mod module, and both have their own documentation :

noah_to_dart.f90 converts a NOAH restart file into a DART-compatible file normally called dart_ics . We usually wind up linking the NOAH restart files to a static name ( [models/noah/noah_to_dart.html]
dart_to_noah.f90 updates some or all of a NOAH restart file with the posterior DART state vector. There is the ability to selectively avoid updating the NOAH variables. This allows one to include NOAH variables in the DART state vector to aid in the application of observation operators, etc., without having to modify those variables in the NOAH restart file. [models/noah/dart_to_noah.html]

Running a "Perfect Model" experiment ... OSSE

The example requires a basic knowledge of running NOAH for a single column. Since the single-column version requires such small netCDF input files, it is possible to simply use ncdump to convert these files to text files, edit them, and generate new netCDF files using ncgen. An appropriate wrfinput file may be generated by editing the templates/wrfinput.template.ascii file and using ncgen, for example.

Four scripts are provided to demonstrate how to set up and run a perfect model experiment for a single site - with one caveat. You must provide your own initial ensemble for the experiment. The scripts are not intended to be black boxes. You are expected to read them and modify them to your own purpose.

The scripts assume the directory containing the DART executables is ${DARTDIR}/work. and the directory containing the NOAH executables is ${NOAHDIR}/Run.

1) setup_pmo.csh This script stages the run of perfect_model_obs. The directory where you run the script is called CENTRALDIR and will be the working directory for the experiment. The required input observation sequence file must be created in the normal DART way (one way: synthetic) and must exist before running this script. All the necessary data files and exectuables for a perfect model experiment get copied to CENTRALDIR so that you may run multiple experiments at the same time - in separate CENTRALDIRs.
2) run_pmo.csh very simply - it advances NOAH and applies the observation operator to put the "perfect" observations in an observation sequence file that can then be used for an assimilation.
3) setup_filter.csh builds upon the work of setup_pmo.csh and stages a PRE-EXISTING initial ensemble.
4) run_filter.csh Actually runs the filtering (assimilation) experiment.

Generating the initial ensemble

Creating the initial ensemble of soil moisture states is an area of active research. The ensemble must come from 'somewhere else'. At present, it may be sufficient to use a climatological ensemble; e.g., using the NOAH restarts for '1 January 00Z' from 50 consecutive years from a hindcast experiment. It may also be sufficient to take a single model state, replicate it N times and force each of the N instances with different atmospheric conditions for 'a long time'.

BTW - Experience has shown that having a paired (unique) atmospheric forcing maintains the ensemble spread during an assimilation better than simply forcing all the ensemble members with one single atmospheric state.

DART has routines to perturb a single NOAH state and generate its own ensemble (typically done with pert_model_state), but this produces model states that are incompatible with NOAH. We are interested in adopting/adapting strategies to create sensible initial conditions for NOAH. If you have an algorithm you believe will be useful, please contact us!


Some novel observations come from the Cosmic-ray Soil Moisture Observing System: COSMOS and are processed by DART routines in the DART/observations/COSMOS directory.

DART has a very object-oriented approach to observation support. All observations that are intended to be supported must be preprocessed into a single obs_def_mod.f90 and obs_kind_mod.f90 in the standard DART way.

Exploring the Output

There are Matlab® scripts for exploring the performance of the assimilation in observation-space (after running obs_diag to explore the file) - use the scripts starting with 'plot_', i.e. DART/diagnostics/matlab/plot_*.m. As always, there are some model-specific items Matlab® will need to know about in DART/models/NOAH/matlab.

The and (and possibly ) netCDF files have the model prognostic variables before and after the assimilation. The DART/matlab scripts for NOAH are under development.

It is also worthwhile to convert your file to a netCDF format obs_sequence file with obs_seq_to_netcdf and use any of the standard plots. Be aware that the COSMOS site-specific metadata will not get conveyed to the netCDF file.


model_nml NAMELIST

We adhere to the F90 standard of starting a namelist with an ampersand '&' and terminating with a slash '/' for all our namelist input. Consider yourself forewarned that character strings that contain a '/' must be enclosed in quotes to prevent them from prematurely terminating the namelist.

namelist /model_nml/  noah_netcdf_filename, &
          assimilation_period_days, assimilation_period_seconds, &
          model_perturbation_amplitude, output_state_vector, &
          debug, noah_state_variables

This namelist is read from a file called input.nml. This namelist provides control over the assimilation period for the model. All observations within (+/-) half of the assimilation period are assimilated. The assimilation period is the minimum amount of time the model can be advanced, and checks are performed to ensure that the assimilation window is a multiple of the NOAH model dynamical timestep.

Contents Type Description
noah_netcdf_filename character(len=128) The name of the NOAH RESTART file to use to create the DART state vector. For convenience, the advance_model.csh script usually links the most recent restart file to a static name. [default: '']
assimilation_period_days integer The number of days to advance the model for each assimilation. [default: 1]
assimilation_period_seconds integer In addition to assimilation_period_days, the number of seconds to advance the model for each assimilation. [default: 0]
model_perturbation_amplitude real(r8) The amount of noise to add when trying to perturb a single state vector to create an ensemble. Only used when input.nml &filter_nml:start_from_restart = .false. See also Generating the initial ensemble at the start of this document. units: standard deviation of a Gaussian distribution with the mean at the value of the state vector element. [default: 0.2]
output_state_vector logical The switch to determine the form of the state vector in the output netCDF files. If .true. the state vector will be output exactly as DART uses it ... one long array. If .false., the state vector is parsed into prognostic variables and output that way -- much easier to use with 'ncview', for example. [default: .false.]
debug integer The switch to specify the run-time verbosity. 0 is as quiet as it gets. > 1 provides more run-time messages. > 5 provides ALL run-time messages. All values above 0 will also write a netCDF file of the grid information and perform a grid interpolation test. [default: 0]
noah_state_variables character(len=32)::
The list of variable names in the NOAH restart file to use to create the DART state vector and their corresponding DART kind. [default: see example below]


   noah_netcdf_file             = '',
   assimilation_period_days     = 0,
   assimilation_period_seconds  = 3600,
   model_perturbation_amplitude = 0.0,
   output_state_vector          = .false.,
   debug                        = 0,
   noah_state_variables         = 'SOIL_T',   'QTY_SOIL_TEMPERATURE',
                                  'SOIL_M',   'QTY_SOIL_MOISTURE',
                                  'SOIL_W',   'QTY_SOIL_LIQUID_WATER',
                                  'SKINTEMP', 'QTY_SKIN_TEMPERATURE',
                                  'SNODEP',   'QTY_SNOW_THICKNESS',
                                  'WEASD',    'QTY_SNOW_WATER',
                                  'CANWAT',   'QTY_CANOPY_WATER',
                                  'QFX',      'QTY_LATENT_HEAT_FLUX',
                                  'HFX',      'QTY_SENSIBLE_HEAT_FLUX',
                                  'GRDFLX',   'QTY_GROUND_HEAT_FLUX'

The second column of noah_state_variables needs some explanation. The DART 'KIND's match what the model_mod knows how to interpolate, so you can't just add a new kind and expect it to work. There is a complex interplay between obs_def_mod, preprocess, and model_mod that defines what KINDs are supported. There is only a single KIND that works with each variable and the example shows the current KINDs. Support for these KINDs was provided by running preprocess with the following namelist settings:

    input_obs_kind_mod_file = '../../../assimilation_code/modules/observations/DEFAULT_obs_kind_mod.F90',
   output_obs_kind_mod_file = '../../../assimilation_code/modules/observations/obs_kind_mod.f90',
     input_obs_def_mod_file = '../../../observations/forward_operators/DEFAULT_obs_def_mod.F90',
    output_obs_def_mod_file = '../../../observations/forward_operators/obs_def_mod.f90',
   input_files              = '../../../observations/forward_operators/obs_def_tower_mod.f90'


namelist /NOAHLSM_OFFLINE/   hrldas_constants_file, &
     indir, outdir,  &
     restart_filename_requested, &
     khour,  kday, &
     forcing_timestep, &
     noah_timestep,  &
     output_timestep, &
     restart_frequency_hours, &
     split_output_count, &
     nsoil, &

The remaining variables are not used by DART - but are used by NOAH. Since DART verifies namelist accuracy, any namelist entry in NOAHLSM_OFFLINE that is not in the following list will cause a FATAL DART ERROR.
zlvl, zlvl_wind, iz0tlnd, sfcdif_option, update_snow_from_forcing, start_year, start_month, start_day, start_hour, start_min, external_fpar_filename_template, external_lai_filename_template, subwindow_xstart, subwindow_xend, subwindow_ystart, subwindow_yend

This namelist is read from a file called namelist.hrldas . This namelist is the same one that is used by NOAH. The values are explained in full in the NOAH documentation. Only the namelist variables of interest to DART are discussed. All other namelist variables are ignored by DART - but mean something to NOAH.

Contents Type Description
hrldas_constants_file character(len=256) The name of the netCDF file containing the grid information. [default: 'wrfinput']
indir character(len=256) The DART/NOAH environment requires all the input files to be in the current working directory. [default: '.']
outdir character(len=256) The DART/NOAH environment requires all output files are in the current working directory. [default: '.']
restart_filename_requested character(len=256) The name of the file containing the grid information. The default value is implicitly used by the scripting examples. Change at your own risk. [default: '']
khour integer The duration (in hours) of the model integration. [default: 1]
kday integer The duration (in days) of the model integration. [default: 0]
forcing_timestep integer The timestep (in seconds) of the atmospheric forcing. [default: 3600]
noah_timestep integer The internal (dynamical) timestep (in seconds). [default: 3600]
output_timestep integer The output interval (in seconds). [default: 3600]
restart_frequency_hours integer How often the NOAH restart files get written. [default: 1]
split_output_count integer should be 1 or bad things happen. [default: 1]
nsoil integer The number of soil interfaces. As I understand it, NOAH requires this to be 4. [default: 4]
zsoil integer(NSOLDX) The depth (in meters) of the soil interfaces. [default: -0.1, -0.4, -1.0, -2.04]


Note: the FORCING_FILE_DIRECTORY line is not required by NOAH but IS required by DART - specifically in the advance_model.csh script.

### THIS IS FOR DART ### FORCING_FILE_DIRECTORY = "/path/to/your/forcing/files"





Only the public interfaces used are discussed here.

Required Interface Routines

use model_mod, only : get_model_size

Additional Interface Routines

use model_mod, only : noah_to_dart_vector

A note about documentation style. Optional arguments are enclosed in brackets [like this].

Required Interface Routines

model_size = get_model_size( )
integer :: get_model_size

Returns the length of the model state vector. Required.

model_size The length of the model state vector.

call adv_1step(x, time)
real(r8), dimension(:), intent(inout) :: x
type(time_type),        intent(in)    :: time

adv_1step is not used for the NOAH model. Advancing the model is done through the advance_model script. This is a NULL_INTERFACE, provided only for compatibility with the DART requirements.

x State vector of length model_size.
time Specifies time of the initial model state.

call get_state_meta_data (index_in, location [, var_type] )
integer,             intent(in)  :: index_in
type(location_type), intent(out) :: location
integer, optional,   intent(out) ::  var_type 

get_state_meta_data returns metadata about a given element of the DART representation of the model state vector. Since the DART model state vector is a 1D array and the native model grid is multidimensional, get_state_meta_data returns information about the native model state vector representation. Things like the location, or the type of the variable (for instance: salinity, temperature, u current component, ...). The integer values used to indicate different variable types in var_type are themselves defined as public interfaces to model_mod if required.

index_in Index of state vector element about which information is requested.
location Returns the 3D location of the indexed state variable. The location_ type comes from DART/location/threed_sphere/location_mod.f90. Note that the lat/lon are specified in degrees by the user but are converted to radians internally.
var_type Returns the KIND of the indexed state variable as an optional argument. The kind is one of the list of supported observation kinds, found in the block of code starting ! Integer definitions for DART TYPES in DART/assimilation_code/modules/observations/obs_kind_mod.f90. To clarify between DART 'KIND's and 'TYPE's ... a KIND is a more generic reference (i.e. QTY_TEMPERATURE) as opposed to the more specific TYPE (i.e. RADIOSONDE_TEMPERATURE).

The list of supported variables in DART/assimilation_code/modules/observations/obs_kind_mod.f90 is created by preprocess using the entries in input.nml[&preprocess_nml, &obs_kind_nml], DEFAULT_obs_kind_mod.F90, obs_def_tower_mod.f90, and perhaps obs_def_COSMOS_mod.f90.

call model_interpolate(x, location, itype, obs_val, istatus)
real(r8), dimension(:), intent(in)  :: x
type(location_type),    intent(in)  :: location
integer,                intent(in)  :: itype
real(r8),               intent(out) :: obs_val
integer,                intent(out) :: istatus

Given the DART vector, model_interpolate returns the value of the desired KIND (i.e. QTY_TEMPERATURE) at the desired location. Put another way, model_interpolate applies the observation operator H to the model state to create an 'expected' observation at the desired location. Some observation operators are more complicated and are defined in their own modules - obs_def_COSMOS_mod.f90, for example. If the interpolation is valid, istatus = 0. Negative values are reserved for the system, any positive value indicates an error.

x A model state vector.
location Location to which to interpolate.
itype Integer indexing which DART KIND is desired.
obs_val The interpolated value from the model.
istatus Integer flag indicating the success of the interpolation.
success == 0, failure == anything else

var = get_model_time_step()
type(time_type) :: get_model_time_step

get_model_time_step returns the forecast length to be used as the "model base time step" in the filter. This is the minimum amount of time the model can be advanced by filter. This is also the assimilation window. All observations within (+/-) one half of the forecast length are used for the assimilation. In the NOAH case, this is set from the namelist values for input.nml &model_nml:assimilation_period_days, assimilation_period_seconds.

var Smallest time step of model.

call static_init_model()

static_init_model is called for runtime initialization of the model. The namelists are read to determine runtime configuration of the model, the grid coordinates, etc. There are no input arguments and no return values. The routine sets module-local private attributes that can then be queried by the public interface routines. In order to initialize the model, DART needs to allocate arrays in proportion to the model size. To calculate the model size, DART queries a NOAH restart file for the variables listed in input.nml &model_nml:noah_state_variables. The model time is also computed from information in this file. The grid locations, etc. come from a file specified in the namelist.hrldas &NOAHLSM_OFFLINE namelist in the HRLDAS_CONSTANTS_FILE variable.

Important: this routine requires:

  1. input.nml &model_mod_nml (and more),
  2. namelist.hrldas &NOAHLSM_OFFLINE,
  3. a NOAH restart file (normally, and
  4. a HRLDAS_CONSTANTS_FILE (normally wrfinput).

call end_model()

end_model is used to clean up storage for the model, etc. when the model is no longer needed. There are no arguments and no return values. The grid variables are deallocated.

call init_time(time)
type(time_type), intent(out) :: time

init_time returns the time at which the model will start if no input initial conditions are to be used. This is frequently used to spin-up models from rest, but is not meaningfully supported for the NOAH model. The only time this routine would get called is if the input.nml &perfect_model_obs_nml:start_from_restart is .false., which is not supported in the NOAH model.

time the starting time for the model if no initial conditions are to be supplied. This is hardwired to be identical to valid time of the model state in the NOAH restart file specified in noah_netcdf_filename.

call init_conditions(x)
real(r8), dimension(:), intent(out) :: x

init_conditions returns default initial conditions for the model; generally used for spinning up initial model states. For the NOAH model it is just a stub because the initial state is always provided by the input files.

x Initial conditions for state vector. This is hardwired to 0.0

ierr = nc_write_model_atts(ncFileID)
integer             :: nc_write_model_atts
integer, intent(in) :: ncFileID

nc_write_model_atts writes model-specific attributes to an opened netCDF file. In the NOAH case, this includes information like the coordinate variables (the grid arrays: XLONG, XLAT, and soil_layers_stag), information from some of the namelists, and the attributes for either the 1D state vector or the prognostic variables (those listed in noah_state_variables). All the required information (except for the netCDF file identifier) is obtained from the scope of the model_mod module. Both the input.nml and namelist.hrldas files are preserved in the netCDF file as variables inputnml and namelist.hrldas, respectively.

ncFileID Integer file descriptor to previously-opened netCDF file.
ierr Returns a 0 for successful completion.

nc_write_model_atts is responsible for the model-specific attributes in the following DART-output netCDF files:,, and

ierr = nc_write_model_vars(ncFileID, statevec, copyindex, timeindex)
integer,                intent(in) :: ncFileID
real(r8), dimension(:), intent(in) :: statevec
integer,                intent(in) :: copyindex
integer,                intent(in) :: timeindex
integer                            :: ierr

nc_write_model_vars writes a copy of the state variables to a NetCDF file. Multiple copies of the state for a given time are supported, allowing, for instance, a single file to include multiple ensemble estimates of the state. Whether the state vector is parsed into prognostic variables (i.e. those listed in noah_state_variables) or simply written as a 1D array is controlled by input.nml &model_mod_nml:output_state_vector. If output_state_vector = .true. the state vector is written as a 1D array (the simplest case, but hard to explore with the diagnostics). If output_state_vector = .false. the state vector is parsed into prognostic variables before being written.

ncFileID file descriptor to previously-opened netCDF file.
statevec A model state vector.
copyindex Integer index of copy to be written.
timeindex The timestep counter for the given state.
ierr Returns 0 for normal completion.

call pert_model_state(state, pert_state, interf_provided)
real(r8), dimension(:), intent(in)  :: state
real(r8), dimension(:), intent(out) :: pert_state
logical,                intent(out) :: interf_provided

pert_model_state cannot be used with NOAH. The intent is to to generate ensemble initial conditions around some control trajectory state when one is preparing to spin-up an ensemble. However, simply adding gaussian noise about a central value does not result in states that NOAH can advance. Consequently, you are responsible for providing a complete initial ensemble. A more robust perturbation mechanism is needed. Until then, you may avoid this routine by using your own ensemble of initial conditions. This is done by setting: &filter_nml:start_from_restart = .true.

state State vector to be perturbed.
pert_state The perturbed state vector.
interf_provided Because of the 'wet/dry' issue discussed above, this is always .true., indicating a model-specific perturbation is available.

call get_close_maxdist_init(gc, maxdist)
type(get_close_type), intent(inout) :: gc
real(r8),             intent(in)    :: maxdist

Pass-through to the 3-D sphere locations module. See get_close_maxdist_init() for the documentation of this subroutine.

call get_close_obs_init(gc, num, obs)
type(get_close_type),                intent(inout) :: gc
integer,                             intent(in)    :: num
type(location_type), dimension(num), intent(in)    :: obs

Pass-through to the 3-D sphere locations module. See get_close_obs_init() for the documentation of this subroutine.

call get_close_obs(gc, base_obs_loc, base_obs_kind, obs, obs_kind, &
num_close, close_ind [, dist])
type(get_close_type),              intent(in ) :: gc
type(location_type),               intent(in ) :: base_obs_loc
integer,                           intent(in ) :: base_obs_kind
type(location_type), dimension(:), intent(in ) :: obs
integer,             dimension(:), intent(in ) :: obs_kind
integer,                           intent(out) :: num_close
integer,             dimension(:), intent(out) :: close_ind
real(r8), optional,  dimension(:), intent(out) :: dist

Pass-through to the 3-D sphere locations module. See get_close_obs() for the documentation of this subroutine.

call ens_mean_for_model(ens_mean)
real(r8), dimension(:), intent(in) :: ens_mean

ens_mean_for_model normally saves a copy of the ensemble mean to module-local storage. This is a NULL_INTERFACE for the NOAH model. At present there is no application which requires module-local storage of the ensemble mean. No storage is allocated.

ens_mean State vector containing the ensemble mean.

Unique Interface Routines

call noah_to_dart_vector( filename, state_vector, restart_time )
character(len=*), intent(in)  :: filename
real(r8),         intent(out) :: state_vector(:)
type(time_type),  intent(out) :: restart_time

noah_to_dart_vector unpacks the specified variables from a NOAH restart file into a DART state vector. The NOAH variables are those specified by noah_state_variables.

filename The NOAH restart file of interest. In normal DART practice, the unique NOAH restart file name has been linked to a static to ease scripting. This is possible since each NOAH model advance takes place in a unique directory.
state_vector The DART state vector from this NOAH state. The variable must be allocated before this routine is called.
restart_time The VALID TIME of the NOAH restart file. As noted previously, the VALID time of the variables in the NOAH restart file must be computed.

call dart_vector_to_model_file(state_vector, filename, dart_time, skip_variables)
real(r8),         dimension(:), intent(in) :: state_vector
character(len=*),               intent(in) :: filename
type(time_type),                intent(in) :: dart_time
character(len=*), dimension(:), intent(in) :: skip_variables

dart_vector_to_model_file Updates a NOAH netCDF restart file with the assimilated values from DART. A list of variables that should NOT be updated in the NOAH restart file allows NOAH variables to be part of the DART state (say, for example, for the observation operators) without concern that the values in the NOAH restart file will change. Each NOAH variable modified by DART will have a netCDF attribute added. For example:

float SOIL_W(Time, soil_layers_stag, south_north, west_east) ;
         SOIL_W:MemoryOrder = "XYZ" ;
         SOIL_W:description = "-" ;
         SOIL_W:units = "-" ;
         SOIL_W:stagger = "Z" ;
SOIL_W:DART = "variable modified by DART" ;
state_vector The 1D array to be used by DART.
filename The name of the netCDF format NOAH restart file.
dart_time ensures that the proper NOAH restart file is being updated.
skip_variables the list of variables that may be in the DART state vector that SHOULD NOT be updated in the NOAH restart file. This list is read from the input.nml dart_to_noah_nml namelist.

call get_noah_restart_filename( filename )
character(len=*), intent(out) :: filename

get_noah_restart_filename allows other programs and modules access to the noah_netcdf_filename. The scoping rules in model_mod require an interface routine to access this information.

filename the netCDF-format NOAH restart file.

call get_noah_timestepping( day, hour, dynamical, output, forcing, restart )
integer, intent(out) :: day
integer, intent(out) :: hour
integer, intent(out) :: dynamical
integer, intent(out) :: output
integer, intent(out) :: forcing
integer, intent(out) :: restart

get_noah_timestepping allows other routines (such as those in dart_to_noah) access to the NOAH timestepping information from the namelist.hrldas  NOAHLSM_OFFLINE namelist.

day the value of NOAHLSM_OFFLINE:kday
hour the value of NOAHLSM_OFFLINE:khour
dynamical the value of NOAHLSM_OFFLINE:noah_timestep
output the value of NOAHLSM_OFFLINE:output_timestep
forcing the value of NOAHLSM_OFFLINE:forcing_timestep
restart the value of NOAHLSM_OFFLINE:restart_frequency_hours*3600

debug = get_debug_level()
integer :: debug

get_debug_level allows external routines access to the variable controlling the level of run-time output specified in input.nml model_nml:debug .



filename purpose
input.nml to read the model_mod namelist
namelist.hrldas to read the NOAHLSM_OFLINE namelist
wrfinput provides NOAH grid information
&model_nml:noah_netcdf_filename the RESTART file containing the NOAH model state.


&model_nml:noah_netcdf_filename the updated RESTART file containing the NOAH model state. the time-history of the "true" model state from an OSSE the time-history of the model state(s) before assimilation the time-history of the model state(s) after assimilation
dart_log.out [default name] the run-time diagnostic output
dart_log.nml [default name] the record of all the namelists actually USED - contains the default values




static_init_model Expected ## soil layers ... We read the model_nml namelist for the name of the NOAH restart file. NOAH restart files (at present) do not actually have the depths of the soil interfaces recorded in them - they come from the NOAHLSM_OFFLINE namelist. static_init_model checks to make sure the namelist and the restart file are compatible.
model_interpolate unable to find state vector component matching type 'xxxx' The observation operator requires a certain model state variable but it is not part of the model state.
get_state_meta_data PROBLEM: not set up for a case with multiple locations yet. This is on my short list for future work.


This is not really a bug, but it is a nuisance. DART requires that the number of MPI tasks cannot exceed the state vector length. In a single-column configuration, the DART state vector is simply not very long. My initial throught was to run with 40 MPI tasks for a 40 member ensemble ... this cannot work because the dimension of the model is less than 40! With SOIL_T, SOIL_M, SOIL_W, SKINTEMP, SNODEP, WEASD, CANWAT, QFX, HFX, and GRDFLX the DART state vector is still only 19 elements long (for a 4-layer run).


FUTURE PLANS - in no particular order.

Support multiple grid cells. Current implementation only allows for a single gridcell.

Ensure the model_time_step is a multiple of OUTPUT_TIMESTEP.

More Error-checking for shapes, dimension orders, etc.

Provide a better mechanism for generating a set of perturbed initial conditions - pert_model_state()

Use the namelist.hrldas &NOAHLSM_OFFLINE:RESTART_FILENAME_REQUESTED variable and remove &model_nml:noah_netcdf_filename





Terms of Use

DART software - Copyright UCAR. This open source software is provided by UCAR, "as is", without charge, subject to all terms of use at

Contact: DART core group
Revision: $Revision: 11626 $
Source: $URL: $
Change Date: $Date: 2017-05-11 11:27:50 -0600 (Thu, 11 May 2017) $
Change history: try "svn log" or "svn diff"