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.
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.
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.
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.
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).
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.
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.
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.
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.
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.
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.
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.