Search code examples
iofortranintel-fortran

Is there a way to use the namelist I/O feature to read in a derived type with allocatable components?


Is there a way to use the namelist I/O feature to read in a derived type with allocatable components?

The only thing I've been able to find about it is https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/269585 which ended on an fairly unhelpful note.

Edit:

I have user-defined derived types that need to get filled with information from an input file. So, I'm trying to find a convenient way of doing that. Namelist seems like a good route because it is so succinct (basically two lines). One to create the namelist and then a namelist read. Namelist also seems like a good choice because in the text file it forces you to very clearly show where each value goes which I find highly preferable to just having a list of values that the compiler knows the exact order of. This makes it much more work if I or anyone else needs to know which value corresponds to which variable, and much more work to keep clean when inevitably a new value is needed.

I'm trying to do something of the basic form:

!where myType_T is a type that has at least one allocatable array in it
type(myType_T) :: thing 

namelist /nmlThing/ thing

open(1, file"input.txt")

read(1, nml=nmlThing)

I may be misunderstanding user-defined I/O procedures, but they don't seem to be a very generic solution. It seems like I would need to write a new one any time I need to do this action, and they don't seem to natively support the

&nmlThing

  thing%name = "thing1"
  thing%siblings(1) = "thing2"
  thing%siblings(2) = "thing3"
  thing%siblings(3) = "thing4"
  !siblings is an allocatable array
/

syntax that I find desirable.

There are a few solutions I've found to this problem, but none seem to be very succinct or elegant. Currently, I have a dummy user-defined type that has arrays that are way large instead of allocatable and then I write a function to copy the information from the dummy namelist friendly type to the allocatable field containing type. It works just fine, but it is ugly and I'm up to about 4 places were I need to do this same type of operation in the code.

Hence trying to find a good solution.


Solution

  • If you want to use allocatable components, then you need to have an accessible generic interface for a user defined derived type input/output procedure (typically by the type having a generic binding for such a procedure). You link to a thread with an example with such a procedure.

    Once invoked, that user defined derived type input/output procedure is then responsible for reading and writing the data. That can include invoking namelist input/output on the components of the derived type.

    Fortran 2003 also offers derived types with length parameters. These may offer a solution without the need for a user defined derived type input/output procedure. However, use of derived types with length parameters, in combination with namelist, will put you firmly in the "highly experimental" category with respect to the current compiler implementation.