# DART software - Copyright UCAR. This open source software is provided
# by UCAR, "as is", without charge, subject to all terms of use at
# http://www.image.ucar.edu/DAReS/DART/DART_download
#
# DART $Id$

Hints for porting a new model to DART:

copy this template directory into a DART/models/xxx
directory for your new model.

if the coordinate system for the model is 1d, you're ok as-is.
if model coordinates are 3d, edit the work/path_names_* files
and change location/oned/* to location/threed_sphere/*

edit all the work/path_names_* files and change models/template/xxx
to use the name of the directory for your model.

try ./quickbuild.csh and everything should compile at this point.

the required subroutines are these:
public :: get_model_size,         &
          adv_1step,              &
          get_state_meta_data,    &
          model_interpolate,      &
          get_model_time_step,    &
          end_model,              &
          static_init_model,      &
          init_time,              &
          init_conditions,        &
          nc_write_model_atts,    &
          nc_write_model_vars,    &
          pert_model_state,       &          
          get_close_maxdist_init, &
          get_close_obs_init,     &
          get_close_obs,          &
          ens_mean_for_model

in addition, model_mod can contain subroutines that are used
for other utility programs and we recommend at least the following
routines be added to model_mod.f90:

public :: model_file_to_dart_vector, &     ! converter
          dart_vector_to_model_file, &     ! converter
          get_gridsize,              &     ! called by everyone
          get_model_filename,        &     ! called by both (set_model_filename?)
          get_state_time,            &     ! model_to_sv, static_init_model
          set_state_time  !(?)             ! sv_to_model, trans_time


edit the model mod and fill in the routines in this order:

1. static_init_model() - make it read in the grid information
  and the number of variables that will be in the state vector
 (fill in the progvar derived type).   fill in the model_size
  variable.  as part of this work, fill in the get_gridsize() 
  code.

  after number 1 is done, get_model_size() and 
  get_model_time_step() from the template should be ok as-is.

2. model_file_to_dart_vector() - given a model data file, read in
  the fields and put them into the 1D DART state vector.  make
  sure the order and values match the progvar array.  

3. dart_vector_to_model_file() - do the reverse of the previous step.

4. get_state_meta_data() - given an index number into the state vector
    return the location and type.  the code which loops over the
    progvar should already do the type, but code to compute what
    lon, lat, and vertical (for a 3d model) or x location (1d)
    corresponds to this item must be written.

5. model_interpolate() - given a location (lon/lat/vert in 3d, x in 1d)
   and a state QTY_xxx kind, return the interpolated value the field
   has at that location.   this is probably one of the routines that
   will take the most code to write.

6. nc_write_model_atts(), nc_write_model_vars() - when filter runs
   it calls these routines to output model data into a netcdf diagnostic
   file which is unrelated to the model data files.  it is possible to
   have the ensemble data just be dumped as a single 1D vector but
   that makes the files less useful.  generally it's most useful to
   put the grid info and dump each variable from the state vector
   into a separate netcdf variable.  the diagnostic files contain the
   ensemble mean, the ensemble stddev, the inflation information, and
   then optionally some or all of the individual ensemble members.

for now, ignore these routines:
   get_close_maxdist_init()
   get_close_obs_init()
   get_close_obs()
   ens_mean_for_model()
   end_model()
 
if you have data in a dart initial condition/restart file, then you
can ignore these routines:
   init_time()
   init_conditions()
otherwise, have them return an initial time and an initial default
ensemble state.

if your model is NOT subroutine callable, you can ignore this routine:
   adv_1step()
otherwise have it call the interface to your model and add the files
necessary to build your model to all the work/path_names_* files.
add the model source to a src/ directory.

if you want to let filter add gaussian noise to a single state vector
to generate an ensemble, you can ignore this routine
   pert_model_state()
otherwise fill in code that does whatever perturbation makes sense
to have an initial ensemble of states.  in some cases that means
adding a different range of values to each different field in the
state vector.

at this point you should have enough code to test and run simple
experiments.  the 'model_mod_check' utility program can be used 
during this process to check your implementation.

the general flow is:

   ./model_to_dart - read model data and convert it into a dart state vector file
   ./create_obs_sequence - make a file with a single observation in it
   ./perfect_model_obs - should interpolate a value for the obs
   ./dart_to_model - convert the dart vector back into a model data file

   generate an ensemble of states, or set 'start_from_restart' to .false.
   run ./filter with the single observation 
   look at the preassim.nc and analysis.nc files
      diff them with ncdiff:  ncdiff analysis.nc preassim.nc Innov.nc
      plot it, with ncview if possible:  ncview Innov.nc
      the difference between the two is the impact of that single observation
      see if it's at the right location and if the differences seem reasonable

TJH - aka - SoYoung ... making changes to test the whole svn commit concept.


From: Mark Petersen [mpetersen@lanl.gov]
Sent: Thursday, September 13, 2012 3:50 PM
To: Urban, Nathan
Subject: restart variables

Nathan,

For next week, you should take a look at the restart variables in the
Registry file at
mpas_repo/trunk/mpas/src/core_ocean

Every variable in mpas-o is listed there with a line like
var persistent real    h ( nVertLevels nCells Time ) 2 iro h state - -

iro means that the variable is specified in input, restart, and output
files.  For you, you need to know what is required in the restart
files.  The great majority of these variables are grid variables, like

var persistent real    latVertex ( nVertices ) 0 iro latVertex mesh - -
var persistent integer cellsOnEdge ( TWO nEdges ) 0 iro cellsOnEdge mesh - -
etc.

The important lines for you are:
% Prognostic variables: read from input, saved in restart, and written to output
var persistent real          u (nVertLevels nEdges Time) 2 ir  u state - -
var persistent real          h (nVertLevels nCells Time) 2 iro h state - -
var persistent real        rho (nVertLevels nCells Time) 2 iro rho state - -
var persistent real temperature(nVertLevels nCells Time) 2 iro temperature state tracers dynamics
var persistent real    salinity(nVertLevels nCells Time) 2 iro salinity state tracers dynamics
var persistent real     tracer1(nVertLevels nCells Time) 2 iro tracer1 state tracers testing

The variables you need to modify with DART are u,h,temperature, salinity.
Rho is recomputed by the EOS upon start-up for our runs.
It is in the restart file when config_vert_grid_type = 'isopycnal'
in which case rho is specified rather than computed from the EOS.
You can ignore tracer1 as well as it is just used for a test variable to
test conservation.  Or you can think of tracer1 as nitrogen, carbon,etc
if that is helpful.

Feel free to write me with questions next week while you are at NCAR, if
that is helpful.

Mark

# <next few lines under version control, do not edit>
# $URL$
# $Revision$
# $Date$
