1

I am trying to run a really large FORTRAN model, so I can't give all the code that's involved but I hope I can give enough information for this to make sense. The code compiled fine (using Intel 2016.0.109 compiler, OpenMPI 1.10.2 and HDF5 1.8.17).

When I try to run it though, it tells me that two of my inputs (called NZG and NZS) are set to -999, hence it fails.

> >>>>  opspec_grid  error! in your namelist!
>     ---> Reason:      Too few soil layers.  Set it to at least 2. Your nzg is currently set to -999...
>     ---> Reason:      Too few maximum # of snow layers. Set it to at least 1.  Your nzs is currently set to -999.

However, in the input file, they are really specified as

   NL%NZG  = 9
   NL%NZS  = 1

I went through all the modules that somehow have something to do with these variables and cannot find anywhere where this should go off the rails. So I am starting to think now that maybe there is something wrong with the way the values are read in. The input file is a text file. The variables are specified as integers in the module that reads them in, FYI. Should I check for special characters or something? I know Fortran can be picky with inputs...

EDIT: Below the code sequence tracing back the error

1) The main module opens the namelist

write (unit=*,fmt='(a)') 'Reading namelist information'
call read_nl(trim(name_name))

read_nl is

subroutine read_nl(namelist_name)
   use ename_coms, only : nl              & ! intent(inout)
                        , init_ename_vars ! ! subroutine

   implicit none
   !----- Arguments. ----------------------------------------------------------------------!
   character(len=*), intent(in) :: namelist_name
   !----- Local variables. ----------------------------------------------------------------!
   logical                      :: fexists
   !----- Name lists. ---------------------------------------------------------------------!
   namelist /ED_NL/ nl
   !---------------------------------------------------------------------------------------!

   !----- Open the namelist file. ---------------------------------------------------------!
   inquire (file=trim(namelist_name),exist=fexists)
   if (.not. fexists) then
      call fatal_error('The namelist file '//trim(namelist_name)//' is missing.'           &
                      ,'read_nl','ed_load_namelist.f90')
   end if

   !----- Initialise the name list with absurd, undefined values. -------------------------!
   call init_ename_vars(nl) 

   !----- Read grid point and options information from the namelist. ----------------------!
   open (unit=10, status='OLD', file=namelist_name)
   read (unit=10, nml=ED_NL)
   close(unit=10)

   return
end subroutine read_nl

2) Then there are specifics about how (what variables) to read from the namelist (the input)

write (unit=*,fmt='(a)') 'Copying namelist'
call copy_nl('ALL_CASES')  

if (runtype == 'HISTORY') then
  call copy_nl('HISTORY')
else
  call copy_nl('NOT_HISTORY')
end if

My simulation is 'NOT_HISTORY': copy_nl('ALL_CASES') is specified so it reads a number of the namelist variables, including the variable 'runtype' - which is then used in that if-else statement.

3) Then copy_nl('NOT_HISTORY') is the following, this is where nzg and nzs are defined.

subroutine copy_nl(copy_type)
use grid_coms            , only : time                      & ! intent(out)
                                   , centlon                   & ! intent(out)
                                   , centlat                   & ! intent(out)
                                   , deltax                    & ! intent(out)
                                   , deltay                    & ! intent(out)
                                   , nnxp                      & ! intent(out)
                                   , nnyp                      & ! intent(out)
                                   , nstratx                   & ! intent(out)
                                   , nstraty                   & ! intent(out)
                                   , polelat                   & ! intent(out)
                                   , polelon                   & ! intent(out)
                                   , ngrids                    & ! intent(out)
                                   , timmax                    & ! intent(out)
                                   , time                      & ! intent(out)
                                   , nzg                       & ! intent(out)
                                   , nzs                       ! ! intent(out)
implicit none
   !----- Arguments. ----------------------------------------------------------------------!
   character(len=*), intent(in) :: copy_type
   !----- Internal variables. -------------------------------------------------------------!
   integer                      :: ifm
   !---------------------------------------------------------------------------------------!

   !---------------------------------------------------------------------------------------!
   !     Here we decide which variables we should copy based on the input variable.        !
   !---------------------------------------------------------------------------------------!
select case (trim(copy_type))
case ('NOT_HISTORY')

  itimea        = nl%itimea
  idatea        = nl%idatea
  imontha       = nl%imontha
  iyeara        = nl%iyeara

  nzg           = nl%nzg
  nzs           = nl%nzs

  slz(1:nzgmax) = nl%slz(1:nzgmax)

  current_time%year  = iyeara
  current_time%month = imontha
  current_time%date  = idatea
  current_time%time  = real(int(real(itimea) * 0.01)) * hr_sec                         &
                     + (real(itimea) * 0.01 - real(int(real(itimea)*0.01)))            &
                     * 100.0 * min_sec
  time               = 0.0d0

NOTE that I have not put all the modules and variables in use, otherwise this post would become insanely long. FYI the module grid_coms specifies the type the variable is. See below the relevant part (the whole module is a list of variables, nothing else)

module grid_coms
  integer :: nzg                            ! Number of soil levels
  integer :: nzs                            ! Number of snow/surface water levels
end module grid_coms

4) Back to the main module, this then calls ed_opspec_grid to check that the variables make sense, and this is where things go wrong. Again, with use the variables are initialized at the start, I'm leaving that out here.

subroutine ed_opspec_grid
!---------------------------------------------------------------------------------------!
   !      Check whether soil layers are reasonable, i.e, enough layers, sorted from the !
   ! deepest to the shallowest.                                                            !
   !---------------------------------------------------------------------------------------!
   if (nzg < 2) then
      write (reason,'(a,1x,i4,a)')                                                         &
            'Too few soil layers.  Set it to at least 2. Your nzg is currently set to'     &
           ,nzg,'...'
      call opspec_fatal(reason,'opspec_grid')  
      ifaterr=ifaterr+1        
   elseif (nzg > nzgmax) then 
      write (reason,'(2(a,1x,i5,a))')                                                      &
            'The number of soil layers cannot be greater than ',nzgmax,'.'                 &
           ,' Your nzg is currently set to',nzg,'.'
      call opspec_fatal(reason,'opspec_grid') 
      ifaterr=ifaterr+1 
   end if
   do k=1,nzg
      if (slz(k) > -.001) then
         write (reason,'(a,1x,i4,1x,a,1x,es14.7,a)')                                       &
               'Your soil level #',k,'is not enough below ground. It is currently set to'  &
               ,slz(k),', make it deeper than -0.001...'
         call opspec_fatal(reason,'opspec_grid')  
         ifaterr=ifaterr+1        
      end if
   end do

   do k=1,nzg-1
      if (slz(k)-slz(k+1) > .001) then
         write (reason,'(2(a,1x,i4,1x),a,2x,a,1x,es14.7,1x,a,1x,es14.7,a)')                &
               'Soil layers #',k,'and',k+1,'are not enough apart (i.e. > 0.001).'          &
              ,'They are currently set as ',slz(k),'and',slz(k+1),'...'
         call opspec_fatal(reason,'opspec_grid')  
         ifaterr=ifaterr+1        
      end if
   end do
end subroutine ed_opspec_grid

NOTE that this is not the first check in this subroutine. Other variables are checked before this part (I left those out), but this is the first error message. Which makes me think that maybe part of the input is read okay and some is not.

Finally, let me stress again that this is a very large project, I really cannot show all the code, which is why I framed the question very simply: are there any (text) input requirements for Fortran that I might have missed (special characters, returns, maybe different for different systems?). Plus, this code is used by a lot of researchers, on different platforms, so I doubt it very much there is something wrong with the code itself... (but let me know if I'm wrong).

6
  • 2
    You need to give us much more - code and input file - to get a meaningful response. Code wise show at least the relevant namelist input statement and the surrounding operations on nzg and nzs that result in those variables having a value of -999 and being tested for that value. Input wise we would ideally see the entire sequence of namelist records relevant for the problematic input/output statement. Commented Aug 9, 2016 at 22:22
  • My very, very wild guess is that you have a slash character in your input (perhaps in a path specification or similar) that precedes the lines shown that causes premature termination of namelist input, and leaves the nzg and nzs values at a default value explicitly set up to detect faulty input. Commented Aug 9, 2016 at 22:23
  • 1
    You are not supposed to show all the code. But you are supposed to show some relevant piece of code. At least the actual read statement responsible for this namelist, definition of the namelist and any type definitions. It is not that difficult to isolate these, much easier than in many other kinds of bugs. Commented Aug 9, 2016 at 23:13
  • I abandoned all use of namelist as a non-portable mess years ago, but now i look a that and ask is it standards conforming to use derived type components in a namelist? Commented Aug 10, 2016 at 0:11
  • 2
    with the edit there is a lot of code but we still need the contents of the namelist file, and probalby module ename_coms Commented Aug 10, 2016 at 21:21

1 Answer 1

3

You are not giving us enough data to pinpoint the issue, so I'll just tell you two of the issues that I have come across using namelists:

  1. If you read several (even different) namelists from the same file, the order counts: If in the file namelist a preceeds namelist b, but the code reads b first, then it won't find a unless you rewind the file.

  2. If the namelist in the data file does not include one or more values, these values will simply stay the same. It is quite likely that in the code these variables are set to -999 specifically so that their absence would be noted. So double-check that the data file is correct. Look for stray / characters that might end the namelist prematurely

All in all, in order to correctly assess what's happening, we'd need at least 3 things:

  1. The declaration block, including all the variables that form part of this namelist, and the namelist /.../ ...,...,... specification

  2. The part of the namelist file that declares this specific namelist, and

  3. Whether any other namelists are also in the same file and whether they're before or after this namelist (both in the file, and in the code)

Sign up to request clarification or add additional context in comments.

3 Comments

As for the namelist/input, there is one input file. Also, I checked it for stray / characters, but could not find any (since the input file is 1591 lines, it's probably not useful to post it here).
Though the actual issue was slightly different, your remark to look for stray / characters helped me figure it out, so I am accepting this as the answer. My input file was also reading paths (with / in it), so I started thinking that could be it. I started shortening my input file by taking out all the many comments put in there by the developers, and that's when I saw it: the apostrophes around a path specified early on in the input file were different from others...
Turns out that TextEdit makes apostrophes more 'curly', while TextMate uses the more straight ones (I use a Mac). I use both these text editors; I would have never guessed TextEdit would use 'smart quotes' (grumble grumble). Changing them all to straight ones solved the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.