This page describes the generation of Fortran90 code that declares and dynamically allocates/deallocates state array fields in the derived data type TYPE(domain), which is defined in frame/module_domain.F in the WRF framework. The table below lists and describes the Registry-generated files:
Generated File: |
Included by: |
Generated by: |
Description: |
tools/gen_defs.c: gen_state_struct.c |
field declarations (simple data types) |
||
tools/gen_defs.c: gen_state_subtypes() |
field declarations (derived data types) |
||
tools/gen_allocs.c: gen_alloc() |
core-specific field memory allocation |
||
tools/gen_allocs.c: gen_dealloc() |
core-specific field memory deallocation |
The generation of these files is controlled by dimspec and state entries of the Registry database.
Click for Registry
Reference Manual in PDF.
State_struct.inc contains the declarations of fields that make up TYPE(domain) in the WRF framework. In WRF, this Fortran90 derived datatype is used to represent the state data for each domain. Each field is either a scalar, a pointer to a dynamically allocated deferred shape array, or a derived data type. Registry-generated derived data types are discussed in the next section.
Included in frame/module_domain.F as part of the TYPE(domain) declaration:
TYPE domain
#include <state_struct.inc>
END TYPE domain
The code in state_struct.inc expands to:
TYPE domain
(scalar field
declarations)
real :: epsts
integer ::
step_number
(pointers to
core-specific deferred shape arrays)
real ,DIMENSION(:,:) ,POINTER :: em_muu ! 2-D, single
time level
real ,DIMENSION(:,:,:) ,POINTER
:: em_u_1 ! 3-D, 1 of 2 time
levels
real ,DIMENSION(:,:,:) ,POINTER
:: em_u_2 ! 3-D, 2 of 2 time
levels
(pointers to
non-core-specific deferred shape arrays)
real ,DIMENSION(:) ,POINTER ::
fcx ! 1-D
real ,DIMENSION(:,:) ,POINTER :: psfc ! 2-D
real ,DIMENSION(:,:,:) ,POINTER
:: div ! 3-D
(pointers to
deferred-shape 4D arrays for tracers)
real ,DIMENSION(:,:,:,:) ,POINTER :: moist_1
! 4-D, 1 of 2 time levels
real ,DIMENSION(:,:,:,:) ,POINTER :: moist_2
! 4-D, 2 of 2 time levels
END TYPE domain
For a given field, the code generated to state_struct.inc is based on dimspec and state entries within the Registry file. The code shown above is generated from the following Registry entries:
#keyword
dim order definition coord axis
dimension name
dimspec
i 1 standard_domain
x west_east
dimspec
j 3 standard_domain y
south_north
dimspec k 2 standard_domain z bottom_top
dimspec w - namelist=spec_bdy_width c spec_bdy_width
#keyword type varname dims use
ntl . . . description
state
real epsts -
misc - . . . "leapfrog time filter
constant"
state integer step_number -
misc - . . .
state
real muu ij dyn_em
1 . . .
state real u ikj dyn_em 2 . . . "x-wind component" "m s-1"
state
real fcx w misc - . . . "RELAXATION TERM FOR BOUNDARY
state
real psfc ij misc 1 . . . "SFC PRESSURE" "Pa"
state
real div ikj misc 1 . . . "DIVERGENCE"
state
real qv ikjft moist 2 . . . "Water vapor mixing ratio"
"kg kg-1"
The dimspec entries define the dimension descriptors that are used in the dims field of the state entry. For the purpose of generating the state_struct.inc file, in which the declarations are pointers to deferred shape arrays, it is sufficient to know only the number of dimensions. Most of the information in the dimspec entries is used later, in the Registry-generated code to allocate the fields.
The type field of the state arrays is self-explanatory.
With the exception of qv, the varname field provides the base name of the field to be declared in state_struct.inc. Qv is a tracer in a four-dimensional tracer array (as indicated by the special descriptor ‘f’ in the dims field). These will be discussed shortly. For the other varnames:
In the case of tracers, such as Qv, the base name of the variable declared in state_struct.inc is the name of the four-dimensional array that will contain the tracers, not the tracer names themselves (rather, these are indexed over the fourth dimension of the array). The base name for tracers is given in the use field of the state entry. As above, multiple time level suffixed declarations will be generated if ntl is 2 or 3. Four-dimensional arrays are never core-associated.
The code that generates state_struct.inc is the subroutine gen_state_struct() defined in tools/gen_defs.c in the WRF source code distribution.
The derived data types defined in state_subtypes may be used to declare state fields in the TYPE(domain) or to declare variables of the derived data type in code that USEs module_domain of the framework. Registry-generated derived data types are used in WRF 3DVAR. The WRF model itself does not define or use Registry-generated derived data types at this time.
Included in frame/module_domain.F prior to the main TYPE(domain) declaration.
#include <state_subtypes.inc>
(Note, the link to the file may not contain any generated code since it links back to the WRF model, which does not use derived data types).
Registry entries for derived data types look like state declarations except that instead of the keyword state they begin with the keyword typedef followed by the name of the type being defined. Fields of a type are declared in the order the entries appear. The third element of a typedef entry is the type of the field, which may be a simple type or a previously defined derived type.
(Registry definition of a derived data
type)
typedef
vp_type real v1 ijk
- 1 - -
typedef
vp_type real v2 ijk - 1 - -
typedef
vp_type real v3 ijk - 1 - -
typedef
vp_type real v4 ijk
- 1 - -
typedef
vp_type real v5 ijk - 1 - -
Once defined, a derived type may be used to define state entries in the Registry:
(Registry declaration of a state variable
using derived data type)
state vp_type vv - -
The Registry program generates the following declarations in state_subtypes.inc from the typedefs shown above.
(Registry-generated declaration of a
derived data type in state_subtypes.inc)
TYPE vp_type
real ,DIMENSION(:,:,:) ,POINTER
:: v1
real ,DIMENSION(:,:,:) ,POINTER
:: v2
real ,DIMENSION(:,:,:) ,POINTER
:: v3
real ,DIMENSION(:,:,:) ,POINTER
:: v4
real ,DIMENSION(:,:,:) ,POINTER
:: v5
END TYPE vp_type
The above example of a state declaration that uses the
derived type results in the following being generated to state_struct.inc:
(Registry-generated declaration using the
derived data type in state_struct.inc)
TYPE(vp_type) :: vv
The code that generates state_struct.inc is the subroutine gen_state_subtypes() defined in tools/gen_defs.c in the WRF source code distribution.
Core_allocs.inc includes Fortran90 ALLOCATE
statements and related code for dynamically allocating memory for fields that
are pointers to deferred shape arrays in TYPE(domain) in frame/module_dm.F that
are associated with the dynamic core core. In addition to ALLOCATE
statements for multi-dimensional fields, core_allocs includes to set
the array and scalar fields of TYPE(domain) to an initial value, the value for
which is declared as the real initial_data_value and defined in the including
routine. For other integer fields, the initial value is zero. For logical the
initial value is .FALSE.
In the WRF framework, core_allocs.inc files (e.g. em_allocs.inc) are included inside a conditional in the routine alloc_space_field, also in frame/module_dm.F.
The registry specification is the same as Section 1.3 above. For a given field, the code generated to state_struct.inc is based on dimspec and state entries within the Registry file. The logic is more complicated, however, since in addition to knowing the number of dimensions, we also must generate the correct extents for each dimension.
The following code is generated to a file em_allocs.inc for the example Registry entries in Section 1.3 above. For readability, some comments and spacing have been added between entries, and the base names of the variables are highlighted in blue:
(scalars; first a real then an integer. neither is core associated.)
IF ( setinitval .EQ. 3 )
grid%epsts=initial_data_value
IF ( setinitval .EQ. 3 )
grid%step_number=0
(an em core-associated variable)
ALLOCATE(grid%em_muu(sm31:em31,sm33:em33),STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to allocate grid%em_muu(sm31:em31,sm33:em33).
')
endif
IF ( setinitval .EQ. 1 .OR. setinitval .EQ. 3 ) grid%em_muu=initial_data_value
(first and second time levels of the em
core-associated variable u)
ALLOCATE(grid%em_u_1(sm31:em31,sm32:em32,sm33:em33),STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to allocate grid%em_u_1(sm31:em31,sm32:em32,sm33:em33).
')
endif
IF ( setinitval .EQ. 1 .OR. setinitval .EQ. 3 ) grid%em_u_1=initial_data_value
ALLOCATE(grid%em_u_2(sm31:em31,sm32:em32,sm33:em33),STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to allocate grid%em_u_2(sm31:em31,sm32:em32,sm33:em33).
')
endif
IF ( setinitval .EQ. 1 .OR. setinitval .EQ. 3 ) grid%em_u_2=initial_data_value
(non core-associated arrays of various
dimensions)
ALLOCATE(grid%fcx(model_config_rec%spec_bdy_width),STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to allocate grid%fcx(model_config_rec%spec_bdy_width).
')
endif
IF ( setinitval .EQ. 1 .OR. setinitval .EQ. 3 ) grid%fcx=initial_data_value
ALLOCATE(grid%psfc(sm31:em31,sm33:em33),STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to allocate grid%psfc(sm31:em31,sm33:em33).
')
endif
IF ( setinitval .EQ. 1 .OR. setinitval .EQ. 3 ) grid%psfc=initial_data_value
ALLOCATE(grid%div(sm31:em31,sm32:em32,sm33:em33),STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to allocate grid%div(sm31:em31,sm32:em32,sm33:em33).
')
endif
IF ( setinitval .EQ. 1 .OR. setinitval .EQ. 3 ) grid%div=initial_data_value
(first and second time levels of the 4d array of
3d moisture tracers)
ALLOCATE(grid%moist_1(sm31:em31,sm32:em32,sm33:em33,num_moist),STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to allocate grid%moist_1(sm31:em31,sm32:em32,sm33:em33,num_moist).
')
endif
IF ( setinitval .EQ. 1 .OR. setinitval .EQ. 3 ) grid%moist_1=initial_data_value
ALLOCATE(grid%moist_2(sm31:em31,sm32:em32,sm33:em33,num_moist),STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to allocate grid%moist_2(sm31:em31,sm32:em32,sm33:em33,num_moist).
')
endif
IF ( setinitval .EQ. 1 .OR. setinitval .EQ. 3 ) grid%moist_2=initial_data_value
Notes:
The code that generates core_allocs.inc is the subroutine gen_alloc() defined in tools/gen_allocs.c in the WRF source code distribution.
Core_deallocs.inc is relatively simple to generate, since it does require information about dimensionality of the fields being deallocated (except to check that the field is not a scalar).
In the WRF framework, core_deallocs.inc files (e.g. em_deallocs.inc) are included inside a conditional in the routine dealloc_space_field, also in frame/module_dm.F.
DEALLOCATE(grid%em_muu,STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to dallocate grid%em_muu. ')
endif
DEALLOCATE(grid%em_u_1,STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to dallocate grid%em_u_1. ')
endif
DEALLOCATE(grid%em_u_2,STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to dallocate grid%em_u_2. ')
endif
DEALLOCATE(grid%fcx,STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to dallocate grid%fcx. ')
endif
DEALLOCATE(grid%psfc,STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to dallocate grid%psfc. ')
endif
DEALLOCATE(grid%div,STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to dallocate grid%div. ')
endif
DEALLOCATE(grid%moist_1,STAT=ierr)
if (ierr.ne.0) then
CALL wrf_error_fatal ( &
'frame/module_domain.f:
Failed to dallocate grid%moist_1. ')
endif
The registry specification is the same as Section 1.3 above. For a given field, the code generated to state_struct.inc is based on dimspec and state entries within the Registry file. The logic is more complicated, however, since in addition to knowing the number of dimensions, we also must generate the correct extents for each dimension.
The code that generates core_deallocs.inc is the subroutine gen_dealloc() defined in tools/gen_allocs.c in the WRF source code distribution.
Page created: March 14, 2005, John Michalakes