Adding and Using Variables in RAMS 4.3.0 and Viewing with REVU 2.3.1
Marty Bell – 5th June 2001
The following details how to add and used user defined variables in RAMS 4.3.0, and how to view them with REVU 2.3.1. Apart from adding prognostic scalars, which has been made simple through RAMSIN namelist control, the follow changes must be executed very carefully since model memory allocations are modified in the process. Remember to save copies of your code before making any changes so you can go back if necessary.
Adding Other Variables to
the A Array
Initialization of a
Prognostic Scalar
Initialization of a
Non-Prognostic Scalar
Updating the Prognostic
Scalar During the Simulation
RAMS 4.3.0 has been coded to allow the simple addition of prognostic scalars. Prognostic scalars are variables that are advected and diffused within the model domain in the same manner as the other prognostic variables in RAMS. Prognostic scalars are used, for example, to track the dispersion of atmospheric pollutants in the model domain.
In the $MODEL_OPTIONS namelist in your RAMSIN file, set NADDSC to the number of prognostic scalars you wish to add (up to a maximum of MAXSCLR set in rconfig.h). This will add array space for NADDSC grid dependant scalar quantities and grid independent scalar tendencies to the A array. No recompilation is required for these changes.
You can refer to these scalar quantities in two ways:
In both cases, you refer to the scalar tendencies with the grid independent indices, ISCLT(ISCALAR).
If you require more prognostic scalars than the maximum set by MAXSCLR in rconfig.h, you can modify MAXSCLR and recompile the model.
Users can also add non-prognostic scalars to RAMS 4.3.0. Non-prognostic scalars are variables that are not advected and diffused, rather, hold whatever values are placed in them. Non-prognostic scalars are used, for example, to hold source terms for atmospheric pollutants. During the simulation these can then be applied to a prognostic scalar that is used to track the dispersion of the atmospheric pollutant in the model domain.
Adding non-prognostic scalars is a little more involved than adding prognostic scalars, and the model must be recompiled after making the changes. To do so for a 3-dimensional variable, do all of the following:
1. In your VTABLES file, look for
SCLP :87:3
This is the variable table location for the prognostic scalars. Because it has variable length, as set by the RAMSIN file $MODEL_OPTIONS namelist parameter NADDSC (to a maximum set by MAXSCLR in rconfig.h), it must appear as the last 3-dimensional variable. Thus to add a variable the prognostic scalar variable table entry must be move down and the added variable inserted immediate prior to it. For example, adding one non-prognostic variable (named SCL1 in this example) should appear in the VTABLES file as:
# Added non-prognostic scalar SCL1 :87:3: 0:110000:vard:hist:anal:lite:mpti # Added prognostic scalars SCLP :88:3:25:110000:vard:sclp:hist:anal:lite:mpti:mpt3:mpt1 |
Note that this VTABLES file can only be used for this version of RAMS 4.3.0. It would be wise to indicate this with the following flags (so the model stops if you erroneously use the incorrect file). In your RAMSIN file, change:
VTABCUST = 'standard',
to (for example)
VTABCUST = 'scalar',
And in your VTABLES file, modify:
#CUSTOM : standard
to
#CUSTOM : scalar
2. In your rvtables.h file, modify the parameter MAX3DV and INDEX3N common block and integer declarations as follows:
integer, parameter ::
maxvar=103+maxsclr & ,max3dv=87+maxsclr & ,max2dv=103 & ,max4ds=8 & ,max3dm=41+maxsclr ... skipping
some lines ... integer,
dimension(maxgrds) :: marker3n & ,iupn ,iucn ,ivpn & ...
skipping some lines ... ,ifthrdmn ,ivkmmn ,ivkhmn & ,iscl1n integer,dimension(maxgrds,maxsclr)
:: isclpn common /index3n/
marker3n & ,iupn ,iucn ,ivpn & ... skipping some
lines ... ,ifthrdmn ,ivkmmn ,ivkhmn
& ,iscl1n ,isclpn |
Note that we have added the grid dependent indices, ISCL1N. As with the modifications to the rcommons.h file, order is important here. In this case, ISCL1N must occur at the 87th location (before ISCLPN). Note also that, if you are adding a 2-dimensional variable you should modify the parameter MAX2DV, and the parameter MAXVAR should be set to the maximum of MAX2DV and MAX3DV,
3. In your rcommons.h file, modify the INDEX3 common block and integer declarations as follows:
integer :: marker3 & ,iup ,iuc ,ivp ,ivc ,iwp & ... skipping some lines ... ,ifthrdm ,ivkmm ,ivkhm ,ISCL1 integer,
dimension(maxsclr) :: isclp common/index3/
marker3 & ,iup ,iuc ,ivp ,ivc ,iwp & ... skipping some
lines ... ,ifthrdm ,ivkmm ,ivkhm ,ISCL1 ,isclp |
Note that we have added the grid independent index, ISCL1. As with the modifications to the rvtables.h file, order is important here. In this case, ISCL1 must occur at the 87th location (before ISCLP).
As for the prognostic scalar variable, you can refer to these scalar quantities in two ways:
Note that there is no tendency array for the non-prognostic variable. Once you have made your modifications you must recompile the model.
Adding non-prognostic scalars to RAMS 4.3.0 is one example of adding variables to the A array. To add alternative type of variables, following the instructions above considering the following notes.
Variables are listed in the VTABLES file in the following form:
name :number:dimension:conditional number:option flags:tables
Number: See above section for allocation of the variable number.
Dimension:
Condition Number: Used in the file rvtab.f90 to determine whether a variable is actually used. A setting of 0 indicates unconditional use.
Option Flags: Usually set to 110000.
Tables:
Parallel tables:
Add variables as required and make the necessary changes to your rvtables.h and rcommons.h files. Then make your code changes to other modules as you need to and recompile the model.
You will likely need to add an initialization routine to ruser.f90 to give your scalar fields some initial value. You will also likely need a source routine if you wish to add to your scalar field during the simulation. In both cases you may want to read in the initialization and source data from data files. In addition, you may wish to make the source terms time dependant. Solutions to these requirements are cover in the next sections.
You should call the initialization routine from INITLZ in rdint.f90. This should be done after the call to GEONEST within the IF (RUNTYPE .EQ. 'INITIAL'… condition (about line 207). For example:
IF (RUNTYPE .EQ. 'INITIAL' .OR. & RUNTYPE .EQ. 'MAKESFC' .OR. & RUNTYPE .EQ. 'MAKELAND' .OR. & RUNTYPE .EQ. 'MAKESST' .OR. & RUNTYPE .EQ. 'MAKEVFILE') THEN ... skipping some lines ... CALL GEONEST(1,NGRIDS,'NOFILE',A)
! Fill scalar arrays DO IFM=1,NGRIDS CALL NEWGRID (IFM) ! prognostic scalar CALL SCALAR_INIT (IFM,NZP,NXP,NYP,A(ISCLP(1))) ! non-prognostic source CALL SCALAR_SRC_INIT (IFM,NZP,NXP,NYP,A(ISCL1)) ENDDO ELSEIF(RUNTYPE.EQ.'HISTORY') THEN |
Then in ruser.f90 you need something like:
SUBROUTINE SCALAR_INIT (NZ,NX,NY,SCALAR1) IMPLICIT NONE INTEGER :: NZ,NX,NY REAL, DIMENSION(NZ,NX,NY) :: SCALAR1 ! Initialize SCALAR1 SCALAR1(1:NZ,1:NX,1:NY)=10.0 RETURN END |
Note that this routine initializes SCALAR1 for the full domain in both parallel and single processor runs. Updating these arrays for a parallel run during the simulation is not quite so simple as it must be done on the nodes (see below).
As for the prognostic scalar, you should call the initialization routine from INITLZ in rdint.f90. An example of this is included above. Then in ruser.f90 you need something like:
SUBROUTINE SCALAR_SRC_INIT (NZ,NX,NY,SOURCE1) IMPLICIT NONE INTEGER :: NZ,NX,NY REAL, DIMENSION(NZ,NX,NY) :: SOURCE1 REAL :: RATE ! Initialize SOURCE1 RATE=1. ! (kg/kg)/s SOURCE1(1:NZ,1:NX,1:NY)=RATE RETURN END |
You should call the updating routine from TIMESTEP in rtimh.f90. This should be done just before the call to PREDTR, which performs the advection and diffusion. For example:
! Apply source to scalar array CALL SCALAR_SRC (NGRID,DTLT,MZP,MXP,MYP,IA,IZ,JA,JZ & ,A(ISCL1),A(ISCLP(1))) t1=cputime(w1) CALL PREDTR(A) ! Update scalars call acctimes(16,'PREDTR',t1,w1,a) |
Then in ruser.f90 you need something like:
SUBROUTINE SCALAR_SRC (IGRD,DT,M1,M2,M3,IA,IZ,JA,JZ & ,SOURCE1,SCALAR1) IMPLICIT NONE INTEGER :: IGRD,M1,M2,M3,IA,IZ,JA,JZ REAL :: DT REAL, DIMENSION(M1,M2,M3) :: SOURCE1,SCALAR1 INTEGER :: I,J,K ! Update SCALAR1 DO J=JA,JZ DO I=IA,IZ DO K=1,M1 SCALAR1(K,I,J)=SCALAR1(K,I,J)+SOURCE1(K,I,J)*DT ENDDO ENDDO ENDDO
RETURN END |
· Source scaling by the timestep must occur in the final stage (in SCALAR_SRC) as the grid and timestep scheme dependant timesteps (controlled by the RAMSIN $MODEL_GRIDS namelist parameters DTLONG, NNDTRAT and IDELTAT) are not computed in rdint.f90 until after INITLZ.
· Although scaling by the volume (if the source term is not defined as a mixing ratio) may occur in either the initialization or source stage, it is more efficiently performed in the initialization.
· If you intend to read in either the initialization or source data from a file, the data on that file must be on the RAMS gird(s).
Viewing up to 5 prognostic scalars is pre-configured in REVU 2.3.1. To view these you need to modify the CFRAME_A or CFRAME_C settings in your REVU_IN file. For example, to view the first scalar, set:
CFRAME_A(1)='/scalar1/',
Then run REVU and view as you would normally (with NCAR Graphics, GRADS, VIS5D, etc). In any output, this will give a positive definite field with a variable name of “scalar1 mixing ratio” with units of “units/kg”.
To adjust this, or add more prognostic scalars, you need to edit the hvlib.f90 file. Look for the following (again for the first scalar) and modify as required:
elseif(cvar(1:lv).eq.'scalar1') then ivar_type=3
ierr=RAMS_getvar('SCLR001',idim_type,ngrd,a,b,flnm) ! If you want this to be positive definite call RAMS_comp_noneg(n1,n2,n3,a) cdname='scalar1 mixing ratio;' cdunits='units/kg;' |
To add the ability to plot any other variable you need to edit the hvlib.f90 file. Following on from the example adding the non-prognostic scalar, this modification would look something like:
elseif(cvar(1:lv).eq.'scalarnp1') then ivar_type=3
ierr=RAMS_getvar('SCL1',idim_type,ngrd,a,b,flnm) ! If you want this to be positive definite call RAMS_comp_noneg(n1,n2,n3,a) cdname='scalarnp1 mixing ratio;' cdunits='units/kg;' |
Where, in your REVU_IN file, you would refer to:
CFRAME_A(1)='/scalarnp1/',