Scheduled Downtime
On Tuesday 24 October 2023 @ 5pm MT the forums will be in read only mode in preparation for the downtime. On Wednesday 25 October 2023 @ 5am MT, this website will be down for maintenance and expected to return online later in the morning.
Normal Operations
The forums are back online with normal operations. If you notice any issues or errors related to the forums, please reach out to help@ucar.edu

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? -Ethan
 

eaton

CSEG and Liaisons
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.
 

bundy

New Member
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!  
 

eaton

CSEG and Liaisons
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,Benjamin
 
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. Thanks-Benjamin 
 
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. 
 

eaton

CSEG and Liaisons
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:


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,
e.g.,

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

 
I have been trying to add a new topography file reading variable, bnd_topo2 in cam_inparm in CAM5, (This is similar as bnd_topo exept it reads in a separate topography file that contains more information on topography character). Yet, I followed the steps above and always meet the problem as "segmentatino fault." And I can not even find the error. Is there any uniqueness in adding &cam_inparm group namelist in cam5 than other group variables?
 
Top