Reading allocatable arrays from namelists
Asked Answered
C

2

6

I am using GNU Fortran (GCC) 4.8.2

I want to read allocatable arrays from a namelist. But I don't know in advance how many elements have to be read into the allocatable array, so I cannot allocate it before to read the namelist.

This is my namelist: namelist.nml:

&SECTION_1
    intList = 5,6,7
/ ! End of SECTION_1

And this is my program: namelist.f08:

program namelist
    implicit none

    integer, allocatable    :: intList(:)
    integer                 :: U    ! Unit to read the namelist file

    namelist /SECTION_1/ intList

    !allocate(intList(3)) ! <-- If I uncomment this, the program works.
    open(NEWUNIT=U, file="namelist.nml", status='OLD', recl=80, delim='APOSTROPHE')
    rewind(U)
    read(U, nml=SECTION_1)
    close(U)

    write (*,*) intList
end program namelist

If I uncomment the labeled line, the program works, but, as I said before, I cannot allocate before to read the namelist. Does anybody know how to accomplish this?.

Carline answered 2/12, 2016 at 14:56 Comment(6)
Are you happy to allocate to larger than required, read in, then resize (based on null values)? Essentially, whenever you read into an allocatable object it has to be allocated.Busyness
Instead of basing the resize on null values you could include a second parameter in the namelist which is just an integer which defines the size -- this has the advantage of not making any value special but has the downside of being more fragile (have to change two things if you want to add an element).Ramble
To follow up -- if you're happy with the fragility of an extra input that defines the length then you could just put that in a second namelist, which is read first and used to allocate the array appropriately.Ramble
Note the namelist input is missing the terminating slash.Scrip
Thank you all. I think that I'll feel happier if I write a function that pre-processes the namelist in the sense that it counts the number of elements of a given parameter in a given section. @IanH, is it not enough to use the '&END' termination?.Carline
&END indicates the start of namelist input for a namelist named END. You use a slash character to terminate namelist input. I am a little surprised that the processor doesn't complain at runtime about that. Note that you can read in arbitrary length namelist input using Fortran 2003's UDDTIO feature, but that would require gfortran >= 7.0.Scrip
T
1

There are informal calls for proposals for automatic allocation when reading for the future Fortran standards. At least for character data to be able to read lines of text of unknown length https://github.com/j3-fortran/fortran_proposals/issues/9 An actual proposal exists for automatic allocation for IOMSG or ERRMSG specifiers in I/O statements https://j3-fortran.org/doc/year/19/19-252.txt

But nothing is finished, AFAIK. There is no automatic solution in current Fortran.

You must allocate to a large enough size before reading. There is no other way. There are other ways how to read data and there are custom data formats and custom parsers. Namelists are not everything even if often convenient.

Trometer answered 28/3, 2023 at 13:9 Comment(0)
C
0

Well, in the mean time, I have found and implemented two different solutions that perhaps are useful for others.

  • One of them is to preprocess the namelist as a text file, finding the required variable and counting the number of parameters. I do not read the values with this routine, only count the values, allocate arrays and then read the file again but, this time, as a standard namelist. This solution is near a reimplementation of the namelists.
  • The other solution is to pass the values, not as a list of numbers but as a string consisting of the comma separated list of numbers. This string is later processed in order to get the number of elements and convert them from string into floats.
Carline answered 15/11, 2023 at 9:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.