edoddridge / aronnax

An idealised isopycnal model that can be run either with n+1/2 layers, or with n layers and variable bathymetry.
http://aronnax.readthedocs.io/en/latest/
MIT License
24 stars 6 forks source link

What's a convenient way to accept an nlayers-long vector of inputs? #53

Closed axch closed 7 years ago

axch commented 7 years ago

The current code has three such vectors: ah, hmean, and g_vec. Currently, it reads the values from parameters.in, using the namelist mechanism. However, apparently, allocatable arrays cannot be read by namelist input in Fortran 90 or 95, because the compiler generates the code for parsing name lists at compile time, and for some reason needs to know how many elements to expect. This restriction is allegedly lifted in Fortran 2003, but that doesn't seem like a great reason to change standards.

So, how should MIM accept this input? Replicating the filename-read mechanism used for the input fields and the wind time series seems rather heavy-weight (for the users). Would it be reasonable to have a compile-time constant maximum number of layers for this purpose? Or, more specifically, maximum number of layers that can have distinct values for those three parameters? Are there any other options? (I don't know Fortran I/O very well.)

axch commented 7 years ago

I suppose one option would be to accept a list of length up to N in the parameter file, and provide an optional filename style parameter for those users who want more layers. Then the user neither needs to mess with more input files for cases with small numbers of layers, nor needs to recompile MIM to simulate a large number of layers.

What happens when not enough values are supplied in the input for a namelist array?

edoddridge commented 7 years ago

That's awkward.

I agree that using the framework of putting the values in a file and reading them in is overkill. It's also a lot of hassle to go through just to load a few numbers.

Given the extremely small overhead of storing a few unused elements in these arrays I think it's reasonable to have a maximum number of layers set at compile time. Something like 10 or 20 is almost certainly enough.

I just tried running the test suite without specifying enough values for g_vec and, while the tests failed the simulation did run. So that suggests the Fortran was happy enough without getting as many values as it had spaces. This isn't something I've looked at before.

edoddridge commented 7 years ago

Actually, how about having the namelist read them into temporary variables that are much larger than required, then moving those values into allocated arrays? Once the model reads the namelist parameters it knows how many layers there are and can allocate vectors that are the right size to hold these values.

See the comments here: http://stackoverflow.com/questions/40935059/reading-allocatable-arrays-from-namelists

axch commented 7 years ago

Section 10.9.1.2 of the standard says that having the array being read be too big is acceptable; remaining slots in it are filled with nulls. Too small is an error.

From this I conclude that the thing to do is to define input arrays for these three things with a hardcoded maximum size, and then copy the values out of there into correctly-sized arrays for computation, if needed. We can leave size-unlimited file-based input for these things off as a feature to be added separately.

edoddridge commented 7 years ago

Sounds good.