[Dart-dev] [9464] DART/trunk/models/ROMS: Enforcing the DART style guide and adding support for doxygen documentation .

nancy at ucar.edu nancy at ucar.edu
Thu Jan 7 16:08:09 MST 2016


Revision: 9464
Author:   thoar
Date:     2016-01-07 16:08:09 -0700 (Thu, 07 Jan 2016)
Log Message:
-----------
Enforcing the DART style guide and adding support for doxygen documentation.
No (intentional) code changes. Formatting, comments, and documentation only.

Modified Paths:
--------------
    DART/trunk/models/ROMS/dart_to_roms.f90
    DART/trunk/models/ROMS/model_mod.f90
    DART/trunk/models/ROMS/roms_to_dart.f90

-------------- next part --------------
Modified: DART/trunk/models/ROMS/dart_to_roms.f90
===================================================================
--- DART/trunk/models/ROMS/dart_to_roms.f90	2016-01-07 22:41:25 UTC (rev 9463)
+++ DART/trunk/models/ROMS/dart_to_roms.f90	2016-01-07 23:08:09 UTC (rev 9464)
@@ -4,30 +4,27 @@
 !
 ! $Id$
 
+!-----------------------------------------------------------------------
+!> One of the interface executables between DART and ROMS.
+!>
+!> Reads a file containing a DART state vector and overwrite the 
+!> corresponding values in a ROMS model analysis file.
+!> If the DART state vector has an 'advance_to_time' present, a
+!> file called model_in.DART is created with a time_manager_nml namelist 
+!> appropriate to advance model to the requested time.
+!>
+!> The dart_to_roms_nml namelist setting for advance_time_present 
+!> determines whether or not the input file has an 'advance_to_time'.
+!> Typically, only temporary files like 'assim_model_state_ic' have
+!> an 'advance_to_time'.
+!>
+!> author: PENG XIU 12/2013 @ University of Maine
+!>         peng.xiu at maine.edu
+!>
+!> subsequently modified by TJH 1/2015
+
 program dart_to_roms
 
-!----------------------------------------------------------------------
-! purpose: interface between DART and the ROMS model
-!
-!          overwrite ROMS restart file
-! method: Read DART state vector and overwrite values in a model analysis file.
-!         If the DART state vector has an 'advance_to_time' present, a
-!         file called model_in.DART is created with a time_manager_nml namelist 
-!         appropriate to advance model to the requested time.
-!
-!         The dart_to_roms_nml namelist setting for advance_time_present 
-!         determines whether or not the input file has an 'advance_to_time'.
-!         Typically, only temporary files like 'assim_model_state_ic' have
-!         an 'advance_to_time'.
-!
-!----------------------------------------------------------------
-!
-! author: PENG XIU 12/2013 @ University of Maine
-!         peng.xiu at maine.edu
-!
-! subsequently modified by TJH 1/2015
-!----------------------------------------------------------------
-
 use        types_mod, only : r8
 use    utilities_mod, only : initialize_utilities, finalize_utilities, &
                              find_namelist_in_file, check_namelist_read, &

Modified: DART/trunk/models/ROMS/model_mod.f90
===================================================================
--- DART/trunk/models/ROMS/model_mod.f90	2016-01-07 22:41:25 UTC (rev 9463)
+++ DART/trunk/models/ROMS/model_mod.f90	2016-01-07 23:08:09 UTC (rev 9464)
@@ -4,19 +4,28 @@
 !
 ! $Id$
 !----------------------------------------------------------------
-!
-! author: PENG XIU 12/2013 @ University of Maine
-!         peng.xiu at maine.edu
-!
-! based on subroutines from others work in the DART package
-! NOTE: For now, this code does not rotate ROMS vectors,
-!       so, rotate them in the observation data if needed
+!>
+!> This is the interface between the ROMS ocean model and DART.
+!> There are 16 required public interfaces whose arguments CANNOT be changed.
+!> There are potentially many more public routines that are typically
+!> used by the converter programs. As the converter programs get phased out
+!> with the impending native netCDF read/write capability, these extra
+!> public interfaces may not need to be public. 
+!>
+!> author: PENG XIU 12/2013 @ University of Maine
+!>         peng.xiu at maine.edu
+!>
+!> based on subroutines from others work in the DART package
+!> NOTE: For now, this code does not rotate ROMS vectors,
+!>       so, rotate them in the observation data if needed
+!>
+!> subsequently modified by the DART team.
+!>
+!> \todo
 !----------------------------------------------------------------
 
 module model_mod
 
-! This is the interface between the ROMS ocean model and DART.
-
 ! Modules that are absolutely required for use are listed
 use        types_mod, only : r4, r8, digits12, SECPERDAY, DEG2RAD, rad2deg, PI, &
                              MISSING_I, MISSING_R4, MISSING_R8, i4, i8
@@ -209,14 +218,20 @@
 
 contains
 
-!------------------------------------------------------------------
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> Called to do one time initialization of the model.
+!> In this case, it reads in the grid information, the namelist
+!> containing the variables of interest, where to get them, their size, 
+!> their associated DART KIND, etc.
+!>
+!> In addition to harvesting the model metadata (grid,
+!> desired model advance step, etc.), it also fills a structure
+!> containing information about what variables are where in the DART
+!> framework.
 
 subroutine static_init_model()
 
-! Called to do one time initialization of the model. In this case,
-! it reads in the grid information.
-
 integer :: iunit, io,index1,indexN,ivar
 integer :: ss, dd,i,TimeDimID
 integer, dimension(NF90_MAX_VAR_DIMS) :: dimIDs
@@ -224,21 +239,15 @@
 character(len=paramname_length)       :: kind_string
 integer :: ncid, VarID, numdims, varsize, dimlen
 
-
 if ( module_initialized ) return
 
 ! The Plan:
 !
-!   read in the grid sizes from grid file
-!
-!   allocate space, and read in actual grid values
-!
-!   figure out model timestep
-!
-!   Compute the model size.
-!
-!   set the index numbers where the field types change
-!
+! * read in the grid sizes from grid file
+! * allocate space, and read in actual grid values
+! * figure out model timestep
+! * Compute the model size.
+! * set the index numbers where the field types change
 
 ! Print module information to log file and stdout.
 call register_module(source, revision, revdate)
@@ -259,7 +268,7 @@
 
 ! Set the time step ... causes ROMS namelists to be read.
 ! Ensures model_timestep is multiple of 'ocean_dynamics_timestep'
-! FIXME 'ocean_dynamics_timestep' could/should be gotten from ROMS 
+!> @todo FIXME 'ocean_dynamics_timestep' could/should be gotten from ROMS 
 
 model_timestep = set_model_time_step()
 
@@ -275,10 +284,10 @@
 call nc_check( nf90_open(trim(model_restart_filename), NF90_NOWRITE, ncid), &
                   'static_init_model', 'open '//trim(model_restart_filename))
 
-call verify_state_variables( variables, ncid, model_restart_filename, &
+call verify_variables( variables, ncid, model_restart_filename, &
                              nfields, variable_table )
 
-TimeDimID = FindTimeDimension( ncid, model_restart_filename )
+TimeDimID = find_time_dimension( ncid, model_restart_filename )
 
 if (TimeDimID < 0 ) then
    write(*,*) 'CAUTION: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
@@ -427,31 +436,39 @@
 
 end subroutine static_init_model
 
-!------------------------------------------------------------
 
+!-----------------------------------------------------------------------
+!>
+!> Set the desired minimum model advance time. This is generally NOT the
+!> dynamical timestep of the model, but rather the shortest forecast length
+!> you are willing to make. This impacts how frequently the observations
+!> may be assimilated.
+!>
 
 function set_model_time_step()
 
-! the static_init_model ensures that the model namelists are read.
-
 type(time_type) :: set_model_time_step
 
 if ( .not. module_initialized ) call static_init_model
 
-! these are from the namelist
+! assimilation_period_seconds, assimilation_period_days are from the namelist
 
+!> @todo FIXME make sure set_model_time_step is an integer multiple of 
+!> the dynamical timestep or whatever strategy ROMS employs.
+
 set_model_time_step = set_time(assimilation_period_seconds, assimilation_period_days)
 
 end function set_model_time_step
 
 
-!------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> return the name of the ROMS analysis filename that was set
+!> in the model_nml namelist
+!>
 
 subroutine get_model_restart_filename( filename )
 
-! return the name of the analysis filename that was set
-! in the model_nml namelist
-
 character(len=*), intent(OUT) :: filename
 
 if ( .not. module_initialized ) call static_init_model
@@ -460,14 +477,19 @@
 
 end subroutine get_model_restart_filename
 
-!------------------------------------------------------------
 
+!-----------------------------------------------------------------------
+!>
+!> Read the grid dimensions from the ROMS grid netcdf file.
+!> By reading the dimensions first, we can use them in variable
+!> declarations later - which is faster than using allocatable arrays.
+!>
+!> @todo FIXME Since every stagger dimension is specified, we should explicitly 
+!> use them instead of trying to add or subtract 1 from some nominal value 
+!>
+
 subroutine get_grid_dimensions()
 
-! Read the grid dimensions from the ROMS netcdf file.
-! By reading the dimensions first, we can use them in variable
-! declarations later - which is faster than using allocatable arrays.
-
 integer  :: ncid
 
 integer :: xi_rho
@@ -509,17 +531,23 @@
 end subroutine get_grid_dimensions
 
 
-!------------------------------------------------------------
+!-----------------------------------------------------------------------
+!> 
+!> Read the actual grid values from the ROMS netcdf file.
+!>
+!> @todo FIXME If the grid variables do not exist, they are calculated.
+!> It is not clear to me if this code block is correct in all circumstances,
+!> as I do not have access to a good test file. Minimally, instead of requiring
+!> setting a hardcoded logical, a simple test to see if the required variables
+!> exist and then taking appropriate action would be greatly preferred.
 
 subroutine get_grid()
 
-! Read the actual grid values in from the ROMS netcdf file.
-!
-! The file name comes from module storage ... namelist.
-! This reads in the following arrays:
-
 integer  :: k,ncid, VarID,stat,i,j
 
+! The following 'automatic' arrays are more efficient than allocatable arrays.
+! This is, in part, why the grid dimensions were determined previously.
+
 real(r8) :: dzt0(Nx,Ny)
 real(r8) :: s_rho(Nz),Cs_r(Nz),SSH(Nx,Ny)
 real(r8) :: x_rho(Nx,Ny), &
@@ -538,7 +566,7 @@
    call error_handler(E_MSG,'get_grid:',string1,text2=string2,text3=string3)
 endif
 
-! Read the netcdf file data
+! Open the netcdf file data
 
 call nc_check(nf90_open(trim(grid_definition_filename), nf90_nowrite, ncid), &
       'get_grid', 'open '//trim(grid_definition_filename))
@@ -557,10 +585,9 @@
 
 ! Read the variables
 
-!---------------------------------------
 ! If there are no lat and lon information in the file
-! TJH FIXME ... just test for the presence of the variables ... do not
-! depend on setting a logical
+!> @todo  FIXME ... just test for the presence of the variables ... 
+!> do not depend on setting a logical
 
 if (nolatlon) then
 
@@ -607,8 +634,6 @@
    VLON=TLON(:,1:Ny-1)
    VLAT=TLAT(:,1:Ny-1)
    
-   !---------------------------------------
-
 else
 
    call nc_check(nf90_inq_varid(ncid, 'lon_rho', VarID), &
@@ -693,7 +718,6 @@
 !            -0.00517297115481568, -0.00168895354075999/)
 
 
-
 ! Also get zeta values in order to calculate ZC
 
 call nc_check(nf90_open(trim(model_restart_filename), nf90_nowrite, ncid), &
@@ -717,17 +741,27 @@
 end subroutine get_grid
 
 
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> Determines if the variables and DART KINDs specified by the 'variables'
+!> namelist variable are available in the ROMS analysis file and that the
+!> corresponding DART KIND is also supported.
+!>
+!>@param state_variables the list of variables and kinds from model_mod_nml
+!>@param ncid the netCDF handle to the ROMS analysis file
+!>@param filename the name of the ROMS analysis file (for error messages, mostly)
+!>@param ngood the number of variable/KIND pairs specified
+!>@param table a more convenient form for the variable/KIND pairs. Each row
+!>       is a pair, column 1 is the variable, column 2 is the DART KIND
 
+subroutine verify_variables( state_variables, ncid, filename, ngood, table )
 
-subroutine verify_state_variables( state_variables, ncid, filename, ngood, table )
+character(len=*), intent(in)    :: state_variables(:)
+integer,          intent(in)    :: ncid
+character(len=*), intent(in)    :: filename
+integer,          intent(out)   :: ngood
+character(len=*), intent(inout) :: table(:,:)
 
-character(len=*), dimension(:),   intent(in)  :: state_variables
-integer,                          intent(in)  :: ncid
-character(len=*),                 intent(in)  :: filename
-integer,                          intent(out) :: ngood
-character(len=*), dimension(:,:), intent(inout) :: table
-
 integer :: nrows, ncols, i, VarID
 character(len=NF90_MAX_NAME) :: varname
 character(len=NF90_MAX_NAME) :: dartstr
@@ -751,7 +785,7 @@
 
    if ( table(i,1) == ' ' .or. table(i,2) == ' ' ) then
       string1 = 'model_nml:model "variables" not fully specified'
-      call error_handler(E_ERR,'verify_state_variables:',string1,source,revision,revdate)
+      call error_handler(E_ERR,'verify_variables:',string1,source,revision,revdate)
    endif
 
    ! Make sure variable exists in model analysis variable list
@@ -759,17 +793,15 @@
    write(string1,'(''variable '',a,'' in '',a)') trim(varname), trim(filename)
    write(string2,'(''there is no '',a)') trim(string1)
    call nc_check(NF90_inq_varid(ncid, trim(varname), VarID), &
-                 'verify_state_variables', trim(string2))
+                 'verify_variables', trim(string2))
 
-
    ! Make sure DART kind is valid
 
    if( get_raw_obs_kind_index(dartstr) < 0 ) then
       write(string1,'(''there is no obs_kind <'',a,''> in obs_kind_mod.f90'')') trim(dartstr)
-      call error_handler(E_ERR,'verify_state_variables:',string1,source,revision,revdate)
+      call error_handler(E_ERR,'verify_variables:',string1,source,revision,revdate)
    endif
 
-
    ngood = ngood + 1
 enddo MyLoop
 
@@ -777,31 +809,43 @@
 if (ngood == nrows) then
    string1 = 'WARNING: There is a possibility you need to increase ''max_state_variables'''
    write(string2,'(''WARNING: you have specified at least '',i4,'' perhaps more.'')')ngood
-   call error_handler(E_MSG,'verify_state_variables:',string1,source,revision,revdate,text2=string2)
+   call error_handler(E_MSG,'verify_variables:',string1,source,revision,revdate,text2=string2)
 endif
 
 
-end subroutine verify_state_variables
+end subroutine verify_variables
 
 
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> matches variable name in bounds table to assign
+!> the bounds if they exist.  otherwise sets the bounds
+!> to missing_r8 which means they are unbounded.
+!> @todo FIXME the roms_state_bounds module variable that specifies the
+!>       bounds is not actually set nor checked nor ... so all variables
+!>       are unbounded.
+!>
+!> @param bounds_table table specifying the numeric bounds for each variable.
+!>                     as currently envisioned, a table specifying the variable
+!>                     name and its boundaries must be supplied ... ?namelist?
+!> @param ivar the handle to the variable in question
+!>
 
-
 subroutine get_variable_bounds(bounds_table, ivar)
 
-! matches variable name in bounds table to assign
-! the bounds if they exist.  otherwise sets the bounds
-! to missing_r8
-!
-character(len=*), intent(in)  :: bounds_table(num_bounds_table_columns, max_state_variables)
-integer,          intent(in)  :: ivar
+character(len=*), intent(in) :: bounds_table(num_bounds_table_columns, max_state_variables)
+integer,          intent(in) :: ivar
 
 ! local variables
-character(len=50)             :: bounds_varname, bound
-character(len=10)             :: clamp_or_fail
-real(r8)                      :: lower_bound, upper_bound
-integer                       :: n
+character(len=50) :: bounds_varname, bound
+character(len=10) :: clamp_or_fail
+real(r8)          :: lower_bound, upper_bound
+integer           :: n
 
+write(string1,*)'WARNING routine not tested.'
+write(string2,*)'"roms_state_bounds" from namelist is not set, not tested.'
+call error_handler(E_MSG,'get_variable_bounds:',string1, text2=string2)
+
 n = 1
 do while ( trim(bounds_table(1,n)) /= 'NULL' .and. trim(bounds_table(1,n)) /= '' )
 
@@ -867,25 +911,34 @@
 end subroutine get_variable_bounds
 
 
-!-------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!> 
+!> Reads the last timestep of the ROMS variables and packs them into a 
+!> DART state vector. At present, only the last timestep is considered.
+!> @todo determining the timestep of the DESIRED time might be a nice extension.
+!>
+!> @param filename the ROMS file that contains the variables of interest. 
+!> @param state_vector the DART state vector
+!> @param last_file_time the last time in the file.
+!>
+!> @todo FIXME last_file_time is provided as a convenience, not sure
+!>       I am decoding the information correctly given the test file 
+!>       that I had. It would be nice to get an accurate time and ensure
+!>       that the desired time is being read.
 
-
 subroutine restart_file_to_sv(filename, state_vector, last_file_time)
 
-! Reads the current time and state variables
-! file and packs them into a dart state vector.
+character(len=*), intent(in)  :: filename
+real(r8),         intent(out) :: state_vector(:)
+type(time_type),  intent(out) :: last_file_time
 
-character(len=*), intent(in)    :: filename
-real(r8),         intent(inout) :: state_vector(:)
-type(time_type),  intent(out)   :: last_file_time
-
 ! temp space to hold data while we are reading it
 integer  :: ndim1, ndim2, ndim3,ndim4
 integer  :: indx, iostatus, ivar
-real(r8), allocatable, dimension(:)         :: data_1d_array
-real(r8), allocatable, dimension(:,:)       :: data_2d_array
-real(r8), allocatable, dimension(:,:,:)     :: data_3d_array
-real(r8), allocatable, dimension(:,:,:,:)   :: data_4d_array
+real(r8), allocatable, dimension(:)       :: data_1d_array
+real(r8), allocatable, dimension(:,:)     :: data_2d_array
+real(r8), allocatable, dimension(:,:,:)   :: data_3d_array
+real(r8), allocatable, dimension(:,:,:,:) :: data_4d_array
 
 integer, dimension(NF90_MAX_VAR_DIMS) :: dimIDs, mystart, mycount
 character(len=NF90_MAX_NAME) :: varname
@@ -922,7 +975,7 @@
 ! IF the netCDF variable has an 'ocean_time' dimension, 
 ! we need to read the LAST timestep  ...
 
-TimeDimID = FindTimeDimension(ncid, filename, last_file_time)
+TimeDimID = find_time_dimension(ncid, filename, last_file_time)
 
 if (TimeDimID < 0) then
    write(string1,*) trim(filename)//' has no "ocean_time" coordinate variable.'
@@ -1053,14 +1106,14 @@
 end subroutine restart_file_to_sv
 
 
-!-----------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> parse the model_nml "analysis_time" string to extract a DART time.
+!> the expected format of the string is YYYY-MM-DD HH:MM:SS
+!> The time is expected to come from the Gregorian calendar.
 
-
 function get_time_from_namelist()
 
-! parse a string to extract time.
-! the expected format of the string is YYYY?MM?DD?hh
-
 type(time_type) :: get_time_from_namelist
 
 integer :: iyear, imonth, iday, ihour, imin, isec
@@ -1082,18 +1135,20 @@
 end function get_time_from_namelist
 
 
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> Pack the values from a 1d array into the DART array
+!>
+!> @param data_1d_array the array containing the ROMS variable
+!> @param x the array containing the DART state
+!> @param ivar handle to the DART structure relating what variable is where.
 
-
 subroutine prog_var_1d_to_vector(data_1d_array, x, ivar)
 
-! convert the values from a 1d array into a 1d array
-! starting at an offset.
+real(r8), intent(in)    :: data_1d_array(:)
+real(r8), intent(inout) :: x(:)
+integer,  intent(in)    :: ivar
 
-real(r8), dimension(:),   intent(in)    :: data_1d_array
-real(r8), dimension(:),   intent(inout) :: x
-integer,                  intent(in)    :: ivar
-
 integer :: idim1,ii
 
 if ( .not. module_initialized ) call static_init_model
@@ -1116,17 +1171,21 @@
 end subroutine prog_var_1d_to_vector
 
 
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> Pack the values from a 2D array into the 1D DART array
+!> 
+!> @param data_2d_array the array containing the ROMS variable
+!> @param x the array containing the DART state
+!> @param ivar handle to the DART structure relating what variable is where.
+!>
 
 subroutine prog_var_2d_to_vector(data_2d_array, x, ivar)
 
-! convert the values from a 2d array into a 1d array
-! starting at an offset.
+real(r8), intent(in)    :: data_2d_array(:,:)
+real(r8), intent(inout) :: x(:)
+integer,  intent(in)    :: ivar
 
-real(r8), dimension(:,:), intent(in)    :: data_2d_array
-real(r8), dimension(:),   intent(inout) :: x
-integer,                  intent(in)    :: ivar
-
 integer :: idim1,idim2,ii
 
 if ( .not. module_initialized ) call static_init_model
@@ -1150,17 +1209,22 @@
 
 end subroutine prog_var_2d_to_vector
 
-!------------------------------------------------------------------
 
+!-----------------------------------------------------------------------
+!>
+!> Pack the values from a 3D array into the 1D DART array
+!> 
+!> @param data_3d_array the array containing the ROMS variable
+!> @param x the array containing the DART state
+!> @param ivar handle to the DART structure relating what variable is where.
+!>
+
 subroutine prog_var_3d_to_vector(data_3d_array, x, ivar)
 
-! convert the values from a 2d array into a 1d array
-! starting at an offset.
+real(r8), intent(in)    :: data_3d_array(:,:,:)
+real(r8), intent(inout) :: x(:)
+integer,  intent(in)    :: ivar
 
-real(r8), dimension(:,:,:), intent(in)    :: data_3d_array
-real(r8), dimension(:),     intent(inout) :: x
-integer,                    intent(in)    :: ivar
-
 integer :: idim1,idim2,idim3,ii
 
 if ( .not. module_initialized ) call static_init_model
@@ -1187,18 +1251,21 @@
 end subroutine prog_var_3d_to_vector
 
 
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> Pack the values from a 4D array into the 1D DART array
+!> 
+!> @param data_4d_array the array containing the ROMS variable
+!> @param x the array containing the DART state
+!> @param ivar handle to the DART structure relating what variable is where.
+!>
 
-
 subroutine prog_var_4d_to_vector(data_4d_array, x, ivar)
 
-! convert the values from a 2d array into a 1d array
-! starting at an offset.
+real(r8), intent(in)    :: data_4d_array(:,:,:,:)
+real(r8), intent(inout) :: x(:)
+integer,  intent(in)    :: ivar
 
-real(r8), dimension(:,:,:,:), intent(in)    :: data_4d_array
-real(r8), dimension(:),       intent(inout) :: x
-integer,                      intent(in)    :: ivar
-
 integer :: idim1,idim2,idim3,idim4,ii
 
 if ( .not. module_initialized ) call static_init_model
@@ -1226,18 +1293,22 @@
 
 end subroutine prog_var_4d_to_vector
 
-!------------------------------------------------------------------
 
+!-----------------------------------------------------------------------
+!>
+!> Extract the values from the 1D DART array into a 1D array 
+!> 
+!> @param x the array containing the DART state
+!> @param ivar handle to the DART structure relating what variable is where.
+!> @param data_1d_array the array containing the ROMS variable
+!>
 
 subroutine vector_to_1d_prog_var(x, ivar, data_1d_array)
 
-! convert the values from a 1d array, starting at an offset,
-! into a 1d array.
+real(r8), intent(in)  :: x(:)
+integer,  intent(in)  :: ivar
+real(r8), intent(out) :: data_1d_array(:)
 
-real(r8), dimension(:),   intent(in)  :: x
-integer,                  intent(in)  :: ivar
-real(r8), dimension(:),   intent(out) :: data_1d_array
-
 integer :: idim1,ii
 
 if ( .not. module_initialized ) call static_init_model
@@ -1260,17 +1331,21 @@
 end subroutine vector_to_1d_prog_var
 
 
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!> 
+!> Extract the values from the 1D DART array into a 2D array 
+!> 
+!> @param x the array containing the DART state
+!> @param ivar handle to the DART structure relating what variable is where.
+!> @param data_2d_array the array containing the ROMS variable
+!>
 
 subroutine vector_to_2d_prog_var(x, ivar, data_2d_array)
 
-! convert the values from a 1d array, starting at an offset,
-! into a 2d array.
+real(r8), intent(in)  :: x(:)
+integer,  intent(in)  :: ivar
+real(r8), intent(out) :: data_2d_array(:,:)
 
-real(r8), dimension(:),   intent(in)  :: x
-integer,                  intent(in)  :: ivar
-real(r8), dimension(:,:), intent(out) :: data_2d_array
-
 integer :: idim1,idim2,ii
 
 if ( .not. module_initialized ) call static_init_model
@@ -1295,17 +1370,21 @@
 end subroutine vector_to_2d_prog_var
 
 
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> Extract the values from the 1D DART array into a 3D array 
+!> 
+!> @param x the array containing the DART state
+!> @param ivar handle to the DART structure relating what variable is where.
+!> @param data_3d_array the array containing the ROMS variable
+!>
 
 subroutine vector_to_3d_prog_var(x, ivar, data_3d_array)
 
-! convert the values from a 1d array, starting at an offset,
-! into a 3d array.
+real(r8), intent(in)  :: x(:)
+integer,  intent(in)  :: ivar
+real(r8), intent(out) :: data_3d_array(:,:,:)
 
-real(r8), dimension(:),     intent(in)  :: x
-integer,                    intent(in)  :: ivar
-real(r8), dimension(:,:,:), intent(out) :: data_3d_array
-
 integer :: idim1,idim2,idim3,ii
 
 if ( .not. module_initialized ) call static_init_model
@@ -1332,13 +1411,18 @@
 end subroutine vector_to_3d_prog_var
 
 
-!------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> given a DART KIND string,
+!> return the first and last index into the DART array of that KIND.
+!> 
+!> @param string the variable name
+!> @param index1 first index into the DART state
+!> @param indexN last index into the DART state
+!>
 
 subroutine get_index_range_string(string,index1,indexN)
 
-! Determine where a particular DART kind (string) exists in the
-! DART state vector.
-
 character(len=*),  intent(in)  :: string
 integer,           intent(out) :: index1
 integer, optional, intent(out) :: indexN
@@ -1359,16 +1443,22 @@
    write(string1,*) 'Problem, cannot find indices for '//trim(string)
    call error_handler(E_ERR,'get_index_range_string:',string1,source,revision,revdate)
 endif
+
 end subroutine get_index_range_string
 
 
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> given a DART KIND integer,
+!> return the first and last index into the DART array of that KIND.
+!> 
+!> @param dartkind the integer describing the DART KIND
+!> @param index1 first index into the DART state
+!> @param indexN last index into the DART state
+!>
 
 subroutine get_index_range_int(dartkind,index1,indexN)
 
-! Determine where a particular DART kind (integer) exists in the
-! DART state vector.
-
 integer,           intent(in)  :: dartkind
 integer,           intent(out) :: index1
 integer, optional, intent(out) :: indexN
@@ -1396,13 +1486,28 @@
 end subroutine get_index_range_int
 
 
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> Find the 'ocean_time' dimension in a ROMS netCDF file.
+!> If there is none - it is a fatal error.
+!> If the optional argument is present, the time of the last timestep
+!> is also returned.
+!>
+!> @param TimeDimID the netCDF dimension ID for 'ocean_time'
+!> @param ncid the netCDF handle to the ROMS netCDF file.
+!> @param filename the name of the ROMS netCDF file
+!>                 (used to generate useful error messages).
+!> @param last_time the time/date of the last timestep in the file.
+!>
+!> @todo FIXME Make sure the calculation is correct.
+!>       The metadata claims to have a julian calendar, the 64bit real
+!>       can support whole numbers that overflow a 32 bit integer. The
+!>       only test file I have is for year 223 or something like that.
+!>       DART normally uses a Gregorian calendar since our observations
+!>       use that same calendar.
 
-function FindTimeDimension(ncid, filename, last_time) result(TimeDimId)
+function find_time_dimension(ncid, filename, last_time) result(TimeDimId)
 
-! Find the 'ocean_time' Dimension in a netCDF file.
-! If there is none - it is a fatal error.
-
 integer                                :: TimeDimId
 integer,                   intent(in)  :: ncid
 character(len=*),          intent(in)  :: filename
@@ -1420,7 +1525,7 @@
 integer :: some_seconds, some_days
 
 call nc_check(nf90_inq_dimid(ncid,'ocean_time',dimid=TimeDimId), &
-       'FindTimeDimension','cannot find "ocean_time" dimension in '//trim(filename))
+       'find_time_dimension','cannot find "ocean_time" dimension in '//trim(filename))
 
 ! If you want the last time from the 'ocean_time' variable,
 ! you have to decode it a bit from the netCDF file metadata.
@@ -1428,15 +1533,15 @@
 if (present(last_time)) then
 
    call nc_check(nf90_inquire_dimension(ncid, TimeDimID, len=dimlen), &
-          'FindTimeDimension', 'inquire_dimension ocean_time'//trim(filename))
+          'find_time_dimension', 'inquire_dimension ocean_time'//trim(filename))
 
    call nc_check(nf90_inq_varid(ncid, 'ocean_time', VarID), &
-          'FindTimeDimension', 'inq_varid ocean_time from '//trim(filename))
+          'find_time_dimension', 'inq_varid ocean_time from '//trim(filename))
 
    allocate(ocean_time(dimlen))
 
    call nc_check(nf90_get_var( ncid, VarID, ocean_time), &
-          'FindTimeDimension', 'get_var ocean_time from '//trim(filename))
+          'find_time_dimension', 'get_var ocean_time from '//trim(filename))
 
    ! Make sure the calendar is expected form
    ! ocean-time:calendar = "julian" ;
@@ -1444,14 +1549,14 @@
    !                        1234567890123
    
    call nc_check(nf90_get_att(ncid, VarID, 'units', unitstring), &
-          'FindTimeDimension', 'get_att ocean_time units '//trim(filename))
+          'find_time_dimension', 'get_att ocean_time units '//trim(filename))
    call nc_check(nf90_get_att(ncid, VarID, 'calendar', calendarstring), &
-          'FindTimeDimension', 'get_att ocean_time units '//trim(filename))
+          'find_time_dimension', 'get_att ocean_time units '//trim(filename))
 
    if (trim(calendarstring) /= 'julian') then
       write(string1,*)'expecting ocean_time calendar of "julian"'
       write(string2,*)'got '//trim(calendarstring)
-      call error_handler(E_ERR,'FindTimeDimension:', string1, &
+      call error_handler(E_ERR,'find_time_dimension:', string1, &
                 source, revision, revdate, text2=string2, text3=string3)
    endif
 
@@ -1461,7 +1566,7 @@
       write(string1,*)'expecting ocean_time units of "seconds since ..."'
       write(string2,*)'got '//trim(unitstring)
       write(string3,*)'Cannot proceed. Stopping.'
-      call error_handler(E_ERR,'FindTimeDimension:', string1, &
+      call error_handler(E_ERR,'find_time_dimension:', string1, &
                 source, revision, revdate, text2=string2, text3=string3)
    endif
 
@@ -1470,7 +1575,7 @@
       write(string1,*)'Unable to read ocean_time units. Error status was ',ios
       write(string2,*)'expected "seconds since YYYY-MM-DD HH:MM:SS"'
       write(string3,*)'was      "'//trim(unitstring)//'"'
-      call error_handler(E_ERR, 'FindTimeDimension:', string1, &
+      call error_handler(E_ERR, 'find_time_dimension:', string1, &
              source, revision, revdate, text2=string2, text3=string3)
    endif
 
@@ -1491,28 +1596,28 @@
    ! DART is interpreting this as the number of days of the 'origin'
 
    call nc_check(nf90_inq_varid(ncid, 'dstart', VarID), &
-          'FindTimeDimension', 'inq_varid dstart from '//trim(filename))
+          'find_time_dimension', 'inq_varid dstart from '//trim(filename))
 
    call nc_check(nf90_get_var( ncid, VarID, dstart), &
-          'FindTimeDimension', 'get_var dstart from '//trim(filename))
+          'find_time_dimension', 'get_var dstart from '//trim(filename))
 
    call nc_check(nf90_get_att(ncid, VarID, 'units', unitstring), &
-          'FindTimeDimension', 'get_att dstart units '//trim(filename))
+          'find_time_dimension', 'get_att dstart units '//trim(filename))
    call nc_check(nf90_get_att(ncid, VarID, 'calendar', calendarstring), &
-          'FindTimeDimension', 'get_att dstart units '//trim(filename))
+          'find_time_dimension', 'get_att dstart units '//trim(filename))
 
    if (unitstring(1:10) /= 'days since') then
       write(string1,*)'expecting dstart units of "days since ..."'
       write(string2,*)'got '//trim(unitstring)
       write(string3,*)'Cannot proceed. Stopping.'
-      call error_handler(E_ERR,'FindTimeDimension:', string1, &
+      call error_handler(E_ERR,'find_time_dimension:', string1, &
                 source, revision, revdate, text2=string2, text3=string3)
    endif
 
    if (trim(calendarstring) /= 'julian') then
       write(string1,*)'expecting dstart calendar of "julian"'
       write(string2,*)'got '//trim(calendarstring)
-      call error_handler(E_ERR,'FindTimeDimension:', string1, &
+      call error_handler(E_ERR,'find_time_dimension:', string1, &
                 source, revision, revdate, text2=string2, text3=string3)
    endif
 
@@ -1521,7 +1626,7 @@
       write(string1,*)'Unable to read dtime units. Error status was ',ios
       write(string2,*)'expected "days since YYYY-MM-DD HH:MM:SS"'
       write(string3,*)'was      "'//trim(unitstring)//'"'
-      call error_handler(E_ERR, 'FindTimeDimension:', string1, &
+      call error_handler(E_ERR, 'find_time_dimension:', string1, &
              source, revision, revdate, text2=string2, text3=string3)
    endif
 
@@ -1546,25 +1651,35 @@
    deallocate(ocean_time)
 endif
 
-end function FindTimeDimension
+end function find_time_dimension
 
-!------------------------------------------------------------------
 
+!-----------------------------------------------------------------------
+!> 
+!> Writes the (posterior) DART state into a ROMS netCDF analysis file.
+!> Just to be clear: only the ROMS variables that are part of the DART
+!> state are overwritten.
+!>
+!> @param state_vector the DART posterior state.
+!> @param filename the ROMS netCDF analysis file.
+!> @param statetime the DART time of the posterior.
+!>
+!> @todo FIXME ... use 'statetime' to find the proper time slot in the 
+!>       restart file. At present, we just stuff it into the last slot, 
+!>       regardless.
+!>
 
 subroutine sv_to_restart_file(state_vector, filename, statetime)
 
-! Writes the current time and state variables from a dart state
-! vector (1d array) into a ROMS netcdf analysis file.
-
 real(r8),         intent(in) :: state_vector(:)
 character(len=*), intent(in) :: filename
 type(time_type),  intent(in) :: statetime
 
 ! temp space to hold data while we are writing it
 integer :: i, ivar
-real(r8), allocatable, dimension(:)         :: data_1d_array
-real(r8), allocatable, dimension(:,:)       :: data_2d_array
-real(r8), allocatable, dimension(:,:,:)     :: data_3d_array
+real(r8), allocatable, dimension(:)     :: data_1d_array
+real(r8), allocatable, dimension(:,:)   :: data_2d_array
+real(r8), allocatable, dimension(:,:,:) :: data_3d_array
 
 integer, dimension(NF90_MAX_VAR_DIMS) :: dimIDs, mystart, mycount
 character(len=NF90_MAX_NAME) :: varname
@@ -1594,11 +1709,8 @@
 ! IF the netCDF variable has a TIME dimension, it must be the last dimension,
 ! and we need to read the LAST timestep and effectively squeeze out the
 ! singleton dimension when we stuff it into the DART state vector.
-! FIXME ... it is also a good idea to make sure that the state time
-! matches the time in the restart file
-!>@TODO use 'statetime' to find proper slot for the write. 
 
-TimeDimID = FindTimeDimension( ncFileID, filename )
+TimeDimID = find_time_dimension( ncFileID, filename )
 
 if ( TimeDimID > 0 ) then
    call nc_check(nf90_inquire_dimension(ncFileID, TimeDimID, len=TimeDimLength), &
@@ -1724,21 +1836,36 @@
 end subroutine sv_to_restart_file
 
 
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> for a given directive and range, do the data clamping for the given
+!> input array.  only one of the optional array args should be specified - the
+!> one which matches the given dimsize.  this still has replicated sections for
+!> each possible dimensionality (which so far is only 1 to 3 - add 4-7 only
+!> if needed) but at least it is isolated to this subroutine.
+!> 
+!> @param out_of_range_fail switch to prescribe action. if TRUE and the data 
+!>                          value is outside the expected range, issue a FATAL 
+!>                          error. if FALSE, set the offending value to the 
+!>                          appropriate max or min described by the 'range' variable.
+!> @param range the expected min and max describing the allowable range. 
+!> @param dimsize the rank of the variable to be clamped. 
+!> @param varname the name of the variable to be clamped.
+!> @param array_1d if dimsize == 1, this contains the data to be clamped.
+!> @param array_2d if dimsize == 1, this contains the data to be clamped.
+!> @param array_3d if dimsize == 3, this contains the data to be clamped.
+!>
 
-subroutine do_clamping(out_of_range_fail, range, dimsize, varname, array_1d, array_2d, array_3d)
- logical,          intent(in)    :: out_of_range_fail
- real(r8),         intent(in)    :: range(2)
- integer,          intent(in)    :: dimsize
- character(len=NF90_MAX_NAME), intent(in)    :: varname
- real(r8),optional,intent(inout) :: array_1d(:), array_2d(:,:), array_3d(:,:,:)
+subroutine do_clamping(out_of_range_fail, range, dimsize, varname, &
+                       array_1d, array_2d, array_3d)
+logical,                      intent(in)    :: out_of_range_fail
+real(r8),                     intent(in)    :: range(2)
+integer,                      intent(in)    :: dimsize
+character(len=NF90_MAX_NAME), intent(in)    :: varname
+real(r8), optional,           intent(inout) :: array_1d(:)
+real(r8), optional,           intent(inout) :: array_2d(:,:)
+real(r8), optional,           intent(inout) :: array_3d(:,:,:)
 
-! for a given directive and range, do the data clamping for the given
-! input array.  only one of the optional array args should be specified - the
-! one which matches the given dimsize.  this still has replicated sections for
-! each possible dimensionality (which so far is only 1 to 3 - add 4-7 only
-! if needed) but at least it is isolated to this subroutine.
-
 ! these sections should all be identical except for the array_XX specified.
 ! if anyone can figure out a way to defeat fortran's strong typing for arrays
 ! so we don't have to replicate each of these sections, i'll buy you a cookie.
@@ -1888,13 +2015,22 @@
 end subroutine do_clamping
 
 
-!------------------------------------------------------------------
+!-----------------------------------------------------------------------
+!>
+!> writes the time of the current state and (optionally) the time
+!> to be conveyed to ROMS to dictate the length of the forecast.
+!> This file is then used by scripts to modify the ROMS run.
+!> The format in the time information is totally at your discretion.
+!>
+!> @param time_filename name of the file (name is set by dart_to_roms_nml:time_filename) 
+!> @param model_time the current time of the model state
+!> @param adv_to_time the time in the future of the next assimilation.
+!>
 
-
 subroutine write_model_time(time_filename, model_time, adv_to_time)
- character(len=*), intent(in)           :: time_filename
- type(time_type),  intent(in)           :: model_time
- type(time_type),  intent(in), optional :: adv_to_time
+character(len=*), intent(in)           :: time_filename
+type(time_type),  intent(in)           :: model_time
+type(time_type),  intent(in), optional :: adv_to_time
 
 integer :: iunit

@@ Diff output truncated at 40000 characters. @@


More information about the Dart-dev mailing list