Using namelists
Overview
Teaching: 20 min
Exercises: 20 minQuestions
What is a namelist?
How can I use a namelist to read and write grouped data?
Objectives
Understand what a namelist is and how to create declare one.
Be able to read and write namelists from file.
Understand how namelists store structured data such as arrays and derived types.
Fortran namelists
Fortran supports a special form of file I/O called namelists which enable the grouping of variables for reading and writing.
The namelist specification
The namelist associates a name with a list of variables. The namelist is
declared using a namelist construct which takes the form
  namelist /namelist-group-name/ variable-name-list
where the namelist-group-name is surrounded by forward slashes / and the
variable-name-list is a comma separated list of variables, e.g.:
  integer :: a, b, c
  namelist /ints/ a, b, c
Namelists in a file
A namelist file is plain text and may contain one or more namelists. Each of
these is begun by &namelist-group-name and terminated by /. Variable-value
assignments occur in the body of the namelist, e.g. the file may contain
&ints
a = 1
b = 2
c = 3
/
The ordering of variables in the namelist does not matter, so the previous example could also have been written as
&ints
c = 3
a = 1
b = 2
/
Reading a namelist
A common usecase for namelists is to specify parameters for a program at
runtime. For example a simulation code might read its configuration from a
namelist called run as follows:
&run
name = "TGV" ! Case name
nsteps = 100 ! Number of timesteps
dt = 0.1     ! Timestep
/
As you can see, an extra nice feature of namelists is their support for
comments using the same ! character as in Fortran code.
To read the namelist from a file, the namelist-group-name is passed as the
argument to read(), so in order to read this run namelist we might do the
following:
  integer :: myunit
  character(len=:) :: name
  integer :: nsteps
  real :: dt
  namelist /run/ name, nsteps, dt
  open(newunit = myunit, file = 'config', action = 'read', status = 'old')
  read(myunit, run)
  close(myunit)
Note that any variables not set in the namelist file will retain their initial
values.
Exercise (5 minutes)
Reading a namelist from file
Using namelist-read.f90, confirm that the runtime values can be specified by changing the contents of the namelist in config.nml. Modify the program to specify a default value for
dtand confirm thatdtretains its value unless otherwise set in thenamelist.What happens if the value set is not of the same type as the variable specification in the program?
What happens if you add an unexpected value to the namelist?
Solution
If the value in the namelist is not of the same type as the program’s variable, you will receive an error stating that it is mismatched.
Any unexpected values will also trigger an error stating that the namelist object cannot be matched to a variable.
Reading multiple namelists
As stated earlier, we can have multiple namelists within a single file.
Continuing with our simulation example we might additionally want to specify
some numerical schemes for the simulation, e.g. adding the schemes namelist:
&run
name = "TGV" ! Case name
nsteps = 100 ! Number of timesteps
dt = 0.1     ! Timestep
/
&schemes
advection = "upwind"  ! Advection scheme
diffusion = "central" ! Diffusion scheme
transient = "RK3"     ! Timestepping scheme
/
We can read the values for each of these namelists as outlined previously, but
note, however that the order of the namelists themselves is important. After
reading a namelist the file reader will be positioned at its end, and trying to
read a namelist that occurred previously in the file will fail. Either the
reading subroutine must match the order of the namelists which occur in the
file or file motion calls such as rewind() should be used to ensure that
reading is independent of order.
Exercise (5 mins)
Reading multiple namelists
Extend the example program namelist-read.f90 to read the numerical
schemesnamelist from config-full.nml.(Optional) Ensure that your program can read the
runconfiguration and the numericalschemesregardless of the order in which they appear.Solution
Add some
charactervariables to store the items from theschemesnamelist, declare the namelist itself with those variables, then, after reading therunnamelist, readschemes. To make sure it can read the two schemes in any order, do arewind(nmlunit)in between them. This way, you read through to the first namelist, reset position to the start, then read through to the second.If they are in the wrong order and you don’t do this, you will encounter an end of file error.
Writing a namelist
Writing a namelist works similarly to reading one. With an open file, or other
output device, passing the namelist as the argument to write() will write the
namelist to the file.
  integer :: myunit
  integer :: a, b, c
  namelist /ints/ a, b, c
  a = 1
  b = 2
  c = 3
  open(newunit = myunit, file = 'output.nml', action = 'write', status = 'new')
  write(myunit, ints)
  close(myunit)
will output the following to the new file output.nml:
&INTS
 A=1          ,
 B=2          ,
 C=3          ,
 /
Exercise (10 minutes)
Writing namelists to file
Write a program to write the simulation parameters as a namelist so that it can be read by the previous example program.
(Optional) If you completed the extension to read the namelists in any order, confirm that this works with your new program when writing in any order.
Solution
A solution writing the
runnamelist can be found in namelist-write.f90.
Handling complex data
So far we have only considered simple scalars and strings, but namelists also support I/O of more complex data structures such as arrays or user-defined types. These are handled similarly to the code we have seen so far.
Exercise (10 minutes)
Writing complex data to namelists
An example program namelist-complex.f90 is provided to write more complex data structures to a namelist. Try running this program and inspecting the output to see how these data structures are represented.
Modify the program to read the namelist back into data and confirm that the data is correct, for example by testing array elements match their expected values.
Key Points
Namelists are declared using the
namelist /namelist-group-name/ variable-name-listconstruct.Read and write namelists by passing them directly to the
readandwritestatements.Remember that namelists cannot be read out of order from a file without first moving backwards through the file.