Skip to content

Latest commit

 

History

History
51 lines (33 loc) · 2.93 KB

README.org

File metadata and controls

51 lines (33 loc) · 2.93 KB

nml4types

Sick and tired using temporary variables to read nml files into members of derived types? I know I am. Well, the pain ends here…

The issue

The built-in namelist (nml) reader of Fortran is quite nice and capable. It does, however, have certain drawbacks. For example, it is difficult to read the full list of variables from an nml group into members of a derived type object. The technical reason for this is that the language does not allow reading into an nml defined from a polymorphic type.

Don’t believe me? Try to write an nml reader where you pass your data type in as class(*). Go on…give it a try! What’s that? You want to extend your data type into a nml_readable type and pass that in instead? Well, try it! Are you now mumbling something about using an association block? Won’t work. How about pointer association, type check, and a block? Still no.

Practically, what this means is that a bunch of temporary variables have to be defined to read the nml variables before copying them into the appropriate members of some derived type object. It gets pretty tedious pretty quickly…

A solution

Here, I pass the name of the group, the name of the object (obj), the name of the parent nml file, and a result child nml file to the subroutine get_group_nml_file. Note that the parent file can contain many nml groups. The subroutine uses awk and sed to pull from the parent file the specied group and creates a child file containing just that group. It then prepends <obj>% before all the elements of the group in that child file. Now the child file can be used to read the nml for the object in one fell swoop.

The client side code can then look like the following:

subroutine read_from_input(this, parent_nml_file)
    type(data), intent(inout) :: this
    character(*), intent(in) :: parent_nml_file

    integer :: ifile
    character(:), allocatable :: group_nml_file

    namelist /params/ this

    call get_group_nml_file(group = 'params', obj = 'this', &
	   parent_nml_file = parent_nml_file, &
	   child_nml_file = group_nml_file)

    open(newunit = ifile, file = group_nml_file, &
	   status = 'old', action = 'read')
    read(ifile, nml = params)
    close(ifile)
end subroutine read_from_input  

Building

To build and install the library, and to run the example client app showing the usage of the library, say

fpm install; fpm run

The library is a single file, which, if you want, you can simply place in your own (GPL3+ compatible) project. Or you can specify the dependency to this git repo in your fpm.toml file.

A challenge

Are you disgusted by regular expressions and find awk and sed headache inducing? Do you have a more elegant solution to this problem? Are you a functional warrior and by Tour de Force wrote an I/O monad in Fortran that solves this issue? Well, I’d love to hear about your solution, genius!