Main menu


How to add new namelist variables

10 posts / 0 new
Last post
How to add new namelist variables

I have been trying to add a new namelist variable for use in CAM/WACCM4. I can't seem to find any tutorials or instructions on how to do this. Could someone lay out step by step instructions or a link to directions on how to create a new namelist variable?



This is not yet documented to my knowledge. Here is a rough outline assuming that you wish to add a variable to an existing namelist group. If you wanted to add an entirely new namelist group then the procedure would need to include adding a subroutine that reads the namelist and making a call to that subroutine from an appropriate place. Suppose, for example, that you want to add a new namelist variable to the namelist group phys_ctl_nl. This namelist is read from subroutine phys_ctl_readnl in module phys_control. All the namelist variables are private module data, so add a declaration for the new variable in the data section of the phys_control module. The namelist itself is declared in subroutine phys_ctl_readnl, so add the new variable to the namelist declaration there. The subroutine is set up to work in an MPI environment, so the namelist file is actually being read only by the master task, and then the values are broadcast to all other tasks. So it is necessary to add a call to mpibcast to do the broadcast. There are existing calls for variables of type character, integer, logical, and real(r8). It's important that the mpibcast call be imitated so that it works for the particular type of data that's being broadcast. The next step is to allow the new variable to be recognized by the build-namelist utility. This is done simply by adding the variable's definition to the file atm/cam/bld/namelist_files/namelist_definition.xml. There is documentation in that file to explain the xml format. The important points are that the new "entry" element has an "id" attribute which contains the name of the new variable, a "group" attribute which is the name of the namelist group (phys_ctl_nl in the example above), and a "type" attribute that contains the variable's type. The content of the "entry" element is used to autogenerate the namelist documentation. Once these steps have been performed you should be able to add the new namelist variable to the "-namelist" argument of build-namelist, or to the user_nl_cam file if using CESM scripts.

When using the CESM build scripts, where can I put a modified version of atm/cam/bld/namelist_files/namelist_definition.xml ?  With the stand-alone CAM scripts it seemed to pick it up from the usr_mods dir.  Thanks!



Dani Bundy Coleman


The CESM build scripts are not currently set up to leverage this feature of CAM's build-namelist script.  But it shouldn't be too hard to do.

CAM's build-namelist knows about directories that contain user source mods by looking at the value of the usr_src element in the config_cache.xml file generated by CAM's configure utility.  This information comes from the value of the -usr_src argument to configure.  When building with the CESM scripts, CAM's configure is invoked by the cam.buildnml.csh script, and currently the -usr_src argument is not being used.  It should be possible to add the CESM source mods directory to the CAM configure commandline in cam.buildnml.csh, and then things would work as you expect.


Hi, Just wanted to check to see whether adding a new variable to the namelist had been streamlined for CESM 1.2.2. Is it still the same process described above? I would like to be able to perturb a variable with user_nl_cam, but since the variable isn't in the namelist, the only way I can do it is to place the subroutine in Sourcemods. This works for now, but I want to add it to the namelist if possible. 


Thank you,



It looks like this information is still correct.

Sean Patrick Santos

CESM Software Engineering Group


I'm not able to replicate the example. The goal is adding a parameter from the module micro_mg1_0.F90 to a namelist and then perturbing it from user_nl_cam.

The micro_mg1_0.F90 module reads in a couple parameters in the subroutine "micro_mg_init." To add my own, "dcs_in", I'm using "rhmini_in" as an example. My plan is to declare dcs_in inside user_nl_cam, and then within the module, 1)read dcs_in and 2) assign dcs=dcs_in.

This seems simple to do. However, it's not clear to me where micro_mg_init is reading rhmini_in and the other input variables from. It's not micro_mg_nl, and I can't find them anywhere. So I'm not sure how to get dcs_in from user_nl_cam into the module. 

Also, there is no mpibcast call in micro_mg1_0.F90. Hopefully the method still works. I can attach code if that would help. 





micro_mg1_0.F90 reads constants that appear to be shared with other modules, having been read by physconst.F90. So, I suppose I could add my parameter, dcs, to physconst_nl. 


Here is an outline for adding dcs to the namelist in cesm1_2_2 code.

1) The namelist definition file must be
modified (bld/namelist_files/namelist_definition.xml).  The new
variable should be added near the other micro_mg_*
variables (around line 1541).  The entry could be:

<entry id="micro_mg_dcs" type="real" category="microphys"
       group="micro_mg_nl" valid_values="" >
Autoconversion size threshold
Default: 400.e-6

This gives the new variable the name micro_mg_dcs.  That's the
name you'll add to user_nl_cam.

2) The namelist is read by micro_mg_cam_readnl (in micro_mg_cam.F90).
A declaration for micro_mg_dcs needs to be added there around line 51,

real(r8) :: micro_mg_dcs=400.e-6_r8

Note that by initializing micro_mg_dcs to 400.e-6_r8 this value will
be used as the default if the user does not override this by
setting a value in user_nl_cam.

3) micro_mg_dcs needs to be added to the namelist declaration in
micro_mg_cam_readnl (around line 157), e.g.,

  namelist /micro_mg_nl/ micro_mg_version, micro_mg_sub_version, &
       micro_mg_do_cldice, micro_mg_do_cldliq, micro_mg_dcs

4) After the namelist is read there needs to be an mpibcast
statement so that all tasks get the value.  This is in
micro_mg_cam_readnl after line 200, e.g.,

  call mpibcast(micro_mg_dcs,   1, mpir8, 0, mpicom)

After this call is executed the module data for micro_mg_dcs will have been
been set in all tasks.

5) The call to the micro_mg1_0 version of micro_mg_init is made
from micro_mg1_0_init_intr.  The value of micro_mg_dcs needs to be
passed through this interface.  For example line 689 should look like

       rhmini, micro_mg_dcs, errstring)

6) Now go to the micro_mg_init subroutine in micro_mg1_0.F90 and add the
dummy argument for dcs, e.g., line 150 should read

    rhmini_in, dcs_in, errstring)

And add the corresponding declaration for the new argument near line 170:

real(r8),  intent(in)  :: dcs_in

7) Finally at line 277 the hardcoded value of dcs is replaced by

Dcs = dcs_in


It worked. Thank you so much for this thorough reply! I hope it will be useful to others too. 

Log in or register to post comments

Who's new

  • m.kliphuis@...
  • ddc3061993@...
  • hui.ding@...
  • zhouc@...
  • arianna.valmass...