Scheduled Downtime
On Friday 21 April 2023 @ 5pm MT, this website will be down for maintenance and expected to return online the morning of 24 April 2023 at the latest

Outputting a New Variable

Status
Not open for further replies.

kwerner

Administrator
Staff member
Note: This example shows the process for outputting an existing local variable within a routine, but the steps would be similar if creating a new variable to output.
Note: This example uses the WRFV4.6.1 code.
Note: For all code changes, make sure to follow Fortran syntax - use existing code as an example.

For this example, we want to output the variable CLDFRA1D, which is found in the RRTMLWRAD subroutine within the phys/module_ra_rrtm.F file.

Step 1 : Modify the module_ra_rrtm.F file to change CLDFRA1D from a local variable, to a variable that will be called/seen by other routines.

In the declarations, CLDFRA1D is listed on line 1812. Remove it from that line.
Code:
1810    REAL, DIMENSION( kts:kte ) ::                          TTEN1D, &
1811                                                          TTEN1DC, &
1812                                                         CLDFRA1D, &

Create a new declaration for CLDFRA1D, as it was in the original declaration, but now adding an "INTENT." This can be added anywhere within the declarations, but let's add it to line 1760, right below the declaration line for ICLOUD and ghg_input.
Code:
1759    INTEGER, INTENT(IN )      ::        ICLOUD, ghg_input
1760    REAL, DIMENSION( kts: kte ), INTENT(OUT) ::          cldfra1d

Now add CLDFRA1D to the RRTMLWRAD subroutine's argument list (the parentheses following the subroutine name). We added it right after ghg_input. Take note of which variable you add after because order is important for these argument lists.
Code:
1731    SUBROUTINE RRTMLWRAD(                                          &
1732                         p_top                                     &
1733                        ,rthraten,rthratenc,glw,olr,emiss          &
1734                        ,p8w,p3d,pi3d                              &
1735                        ,dz8w,tsk,t3d,t8w,rho3d,r,g                &
1736                        ,icloud, warm_rain                         &
1737                        ,ids,ide, jds,jde, kds,kde                 &
1738                        ,ims,ime, jms,jme, kms,kme                 &
1739                        ,its,ite, jts,jte, kts,kte                 &
1740                        ,qv3d,qc3d,qr3d                            &
1741                        ,qi3d,qs3d,qg3d,cldfra3d                   &
1742                        ,f_qv,f_qc,f_qr,f_qi,f_qs,f_qg             &
1743 !ccc Added for time-varying trace gases.
1744                        ,yr, julian, ghg_input, cldfra1d            )

Save module_ra_rrtm.F


Step 2 : Figure out what routine calls subroutine RRTMLWRAD, and then modify that file.

From the top-level WRF directory, search for the call to the subroutine, and specifically look in the files ending with *.F.
Code:
grep -i "call RRTMLWRAD" */*.F

This search tells us the RRTMLWRAD subroutine is called from phys/module_radiation_driver.F


Step 3 : Modify module_radiation_driver.F to add the CLDFRA1D variable.

Open phys/module_radiation_driver.F and search for the call to the RRTMLWRAD subroutine. It's found at line 1848 and has all the variables it brought in the argument list that follows.

Add the CLDFRA1D variable to that list, right after the "GHG_INPUT" variable since this is the variable we added it after in the RRTMLWRAD subroutine argument list (note the syntax).
Code:
1848              CALL RRTMLWRAD(                                        &
1849                   P_TOP=p_top_dummy                                 &
1850                  ,RTHRATEN=RTHRATEN,RTHRATENC=RTHRATENLWC,GLW=GLW   &
1851                  ,OLR=RLWTOA,EMISS=EMISS                            &
1852                  ,QV3D=QV                                           &
1853                  ,QC3D=QC                                           &
1854                  ,QR3D=QR                                           &
1855                  ,QI3D=QI                                           &
1856                  ,QS3D=QS                                           &
1857                  ,QG3D=QG                                           &
1858                  ,P8W=p8w,P3D=p,PI3D=pi,DZ8W=dz8w,TSK=tsk,T3D=t     &
1859                  ,T8W=t8w,RHO3D=rho,CLDFRA3D=CLDFRA,R=R_d,G=G       &
1860                  ,F_QV=F_QV,F_QC=F_QC,F_QR=F_QR                     &
1861                  ,F_QI=F_QI,F_QS=F_QS,F_QG=F_QG                     &
1862                  ,ICLOUD=icloud,WARM_RAIN=warm_rain                 &
1863 !ccc Added for time-varying trace gases.
1864                  ,YR=YR,JULIAN=JULIAN,GHG_INPUT=GHG_INPUT           &
1865                  ,CLDFRA1D=CLDFRA1D                                 &
1866 !ccc             
1867                  ,IDS=ids,IDE=ide, JDS=jds,JDE=jde, KDS=kds,KDE=kde &     
1868                  ,IMS=ims,IME=ime, JMS=jms,JME=jme, KMS=kms,KME=kme &
1869                  ,ITS=its,ITE=ite, JTS=jts,JTE=jte, KTS=kts,KTE=kte &
1870                                                                     )

This call to RRTMLWRAD is inside SUBROUTINE radiation_driver, so we also need to add CLDFRA1D to the radiation_driver subroutine's argument list. Again, we are going to add it right after GHG_INPUT.
Code:
 190               ,mp_physics                                                 &
 191               ,EFCG,EFCS,EFIG,EFIS,EFSG,aercu_opt                         &
 192               ,EFSS,QS_CU                                                 &
 193               ,GHG_INPUT, CLDFRA1D                                        &
 194 #if (WRF_CHEM == 1)
 195               ,chem                                                       &
 196               ,aod_out                                                    &

Just as we did in the previous file, we need to declare the CLDFRA1D variable in the list of declarations for SUBROUTINE radiation_driver. Give it all the same descriptions. Again, this can be added anywhere in the descriptions, but for this example, we are adding it just below the declaration for ghg_input.
Code:
 502    INTEGER, INTENT(IN)            :: ghg_input
 503    REAL, INTENT(INOUT), DIMENSION(kts:kte) :: cldfra1d

Save the radiation_driver.F file.


Step 4: Add cldfra1d to dyn_em/module_first_rk_step_part1.F

The radiation driver (and other drivers) is called by SUBROUTINE first_rk_step_part1, within dyn_em/module_first_rk_step_part1.F. We only need to make sure this routine is able to see the new variable, so we only need to add it to the argument list for the call to the radiation_driver. Again, it will be added right after ghg_input.
Code:
470      &         ,shadowmask=grid%shadowmask,ghg_input=config_flags%ghg_input   &
 471      &         ,cldfra1d=grid%cldfra1d     &

Note that ghg_input points to config_flags%ghg_input. This syntax means that this is a namelist variable. Because CLDFRA1D is not a namelist parameter, and just an output variable, we will use "grid%," instead. This indicates the variable is from the Registry file.

Save the module_first_rk_step_part1.F file.


Step 5: Add the CLDFRA1D variable to the Registry
Add the new variable to the Registry/Registry.EM_COMMON file. This can be added anywhere that makes sense.
Code:
state   real    cldfra1d       ij       misc      -         -     rh        "cldfra1d"               "1d cloud fraction"   ""

Save the registry file.


Step 6: Recompile the code

Because changes were made to the registry, the code must be cleaned, reconfigured, and then recompiled. Go back to the top-level WRF directory and issue the following.
Code:
./clean -a

./configure

./compile em_real >& compile.log

After these steps, if the code compiles correctly, the model can be run, and if ra_lw_physics = 1 (for the RRTM scheme), the variable CLDFRA1D will be included in the output.
 
Status
Not open for further replies.
Top