LCOV - code coverage report
Current view: top level - src - mo_ncwrite.f90 (source / functions) Hit Total Coverage
Test: forces coverage Lines: 58 2431 2.4 %
Date: 2024-03-13 19:03:28 Functions: 2 39 5.1 %

          Line data    Source code
       1             : !> \file mo_ncwrite.f90
       2             : !> \brief \copybrief mo_ncwrite
       3             : !> \details \copydetails mo_ncwrite
       4             : 
       5             : !> \brief Writing netcdf files
       6             : !> \details Subroutines for writing arrays on nc file using the netcdf4 library.
       7             : !> \author Stephan Thober, Luis Samaniego, Matthias Cuntz
       8             : !> \date Nov 2011
       9             : !> \copyright Copyright 2005-\today, the CHS Developers, Sabine Attinger: All rights reserved.
      10             : !! FORCES is released under the LGPLv3+ license \license_note
      11             : module mo_ncwrite
      12             : 
      13             :   use mo_kind, only : i1, i4, sp, dp
      14             :   use mo_string_utils, only : nonull
      15             :   use mo_utils, only : ne
      16             : 
      17             :   ! functions and constants of netcdf4 library
      18             :   use netcdf, only : nf90_create, nf90_def_dim, NF90_UNLIMITED, nf90_def_var, &
      19             :           NF90_CHAR, nf90_put_att, NF90_INT, NF90_INT, NF90_GLOBAL, &
      20             :           nf90_enddef, nf90_put_var, NF90_FLOAT, NF90_DOUBLE, NF90_BYTE, &
      21             :           NF90_close, nf90_noerr, nf90_strerror, NF90_CLOBBER, &
      22             :           NF90_MAX_NAME, NF90_WRITE, nf90_inq_varid, nf90_inquire_variable, &
      23             :           nf90_inquire_dimension, nf90_open, NF90_64BIT_OFFSET, NF90_NETCDF4, &
      24             :           nf90_inq_varid, nf90_inq_dimid, nf90_inquire, nf90_get_var, nf90_fill_float, &
      25             :           nf90_fill_double, nf90_fill_int
      26             : 
      27             :   ! public routines -------------------------------------------------------------------
      28             :   public :: close_netcdf         ! save and close the netcdf file
      29             :   public :: create_netcdf        ! create the nc file with variables and their attributes, after they were set
      30             :   public :: dump_netcdf          ! simple dump of variable into a netcdf file
      31             :   public :: var2nc               ! simple dump of multiple variables with attributes into one netcdf file
      32             :   public :: write_dynamic_netcdf ! write dynamically (one record after the other) in the file
      33             :   public :: write_static_netcdf  ! write static data in the file
      34             :   ! public types -------------------------------------------------------------------
      35             :   public :: dims
      36             :   public :: variable
      37             :   public :: attribute
      38             : 
      39             :   ! public parameters
      40             :   integer(i4), public, parameter :: nMaxDim = 5         !< nr. max dimensions
      41             :   integer(i4), public, parameter :: nMaxAtt = 20        !< nr. max attributes
      42             :   integer(i4), public, parameter :: maxLen = 256       !< nr. string length
      43             :   integer(i4), public, parameter :: nGAtt = 20        !< nr. global attributes
      44             :   integer(i4), public, parameter :: nAttDim = 2         !< dim array of attribute values
      45             : 
      46             :   ! public types -----------------------------------------------------------------
      47             :   !> \brief NetCDF dims
      48             :   type dims
      49             :     character (len = maxLen) :: name                !< dim. name
      50             :     integer(i4) :: len                 !< dim. lenght, undefined time => NF90_UNLIMITED
      51             :     integer(i4) :: dimId               !< dim. Id
      52             :   end type dims
      53             : 
      54             :   !> \brief NetCDF attribute
      55             :   type attribute
      56             :     character (len = maxLen) :: name                !< attribute name
      57             :     integer(i4) :: xType               !< attribute of the values
      58             :     integer(i4) :: nValues             !< number of attributes
      59             :     character (len = maxLen) :: values              !< numbers or "characters" separed by spaces
      60             :   end type attribute
      61             : 
      62             :   !> \brief NetCDF variable
      63             :   type variable
      64             :     character (len = maxLen) :: name                !< short name
      65             :     integer(i4) :: xType               !< NF90 var. type
      66             :     integer(i4) :: nLvls               !< number of levels
      67             :     integer(i4) :: nSubs               !< number of subparts
      68             :     logical :: unlimited           !< time limited
      69             :     integer(i4) :: variD               !< Id
      70             :     integer(i4) :: nDims               !< field dimension
      71             :     integer(i4), dimension(nMaxDim) :: dimIds              !< passing var. dimensions
      72             :     integer(i4), dimension(nMaxDim) :: dimTypes            !< type of dimensions
      73             :     integer(i4) :: nAtt                !< nr. attributes
      74             :     type(attribute), dimension(nMaxAtt) :: att                 !< var. attributes
      75             :     integer(i4), dimension(nMaxDim) :: start               !< starting indices for netcdf
      76             :     integer(i4), dimension(nMaxDim) :: count               !< counter          for netcdf
      77             :     logical :: wFlag               !< write flag
      78             :     integer(i1), pointer :: G0_b              !< array pointing model variables
      79             :     integer(i1), dimension(:), pointer :: G1_b              !< array pointing model variables
      80             :     integer(i1), dimension(:, :), pointer :: G2_b              !< array pointing model variables
      81             :     integer(i1), dimension(:, :, :), pointer :: G3_b              !< array pointing model variables
      82             :     integer(i1), dimension(:, :, :, :), pointer :: G4_b              !< array pointing model variables
      83             :     integer(i4), pointer :: G0_i              !< array pointing model variables
      84             :     integer(i4), dimension(:), pointer :: G1_i              !< array pointing model variables
      85             :     integer(i4), dimension(:, :), pointer :: G2_i              !< array pointing model variables
      86             :     integer(i4), dimension(:, :, :), pointer :: G3_i              !< array pointing model variables
      87             :     integer(i4), dimension(:, :, :, :), pointer :: G4_i              !< array pointing model variables
      88             :     real(sp), pointer :: G0_f              !< array pointing model variables
      89             :     real(sp), dimension(:), pointer :: G1_f              !< array pointing model variables
      90             :     real(sp), dimension(:, :), pointer :: G2_f              !< array pointing model variables
      91             :     real(sp), dimension(:, :, :), pointer :: G3_f              !< array pointing model variables
      92             :     real(sp), dimension(:, :, :, :), pointer :: G4_f              !< array pointing model variables
      93             :     real(dp), pointer :: G0_d              !< array pointing model variables
      94             :     real(dp), dimension(:), pointer :: G1_d              !< array pointing model variables
      95             :     real(dp), dimension(:, :), pointer :: G2_d              !< array pointing model variables
      96             :     real(dp), dimension(:, :, :), pointer :: G3_d              !< array pointing model variables
      97             :     real(dp), dimension(:, :, :, :), pointer :: G4_d              !< array pointing model variables
      98             :   end type variable
      99             : 
     100             :   ! public variables -----------------------------------------------------------------
     101             :   integer(i4), public :: nVars   !< nr. variables
     102             :   integer(i4), public :: nDims   !< nr. dimensions
     103             :   type (dims), public, dimension(:), allocatable :: Dnc     !< dimensions list
     104             :   type(variable), public, dimension(:), allocatable :: V       !< variable list, THIS STRUCTURE WILL BE WRITTEN IN THE FILE
     105             :   type(attribute), public, dimension(nGAtt) :: gatt    !< global attributes for netcdf
     106             : 
     107             : 
     108             :   ! ------------------------------------------------------------------
     109             : 
     110             :   !>    \brief Variable simple write in netcdf.
     111             : 
     112             :   !>    \details
     113             :   !!    Simple write of a variable in a netcdf file.\n
     114             :   !!    The variabel can be 1 to 5 dimensional and single or double precision.\n
     115             :   !!    1D and 2D are dumped as static variables. From 3 to 5 dimension, the last
     116             :   !!    dimension will be defined as time.\n
     117             :   !!    The Variable will be called var.
     118             :   !!
     119             :   !!    \b Example
     120             :   !!
     121             :   !!         call dump_netcdf('test.nc', myarray)
     122             :   !!         call dump_netcdf('test.nc', myarray, netcdf4=.true.)
     123             :   !!
     124             :   !!    See also example in test!
     125             : 
     126             :   !>    \param[in]  "character(len=*) :: filename"                  Name of netcdf output file.
     127             :   !>    \param[in]  "real(sp/dp)      :: arr(:[,:[,:[,:[,:]]]])"    1D to 5D-array with input numbers.
     128             :   !>    \param[in]  "logical, optional :: lfs"                      True: enable netcdf3 large file support, i.e. 64-bit offset.
     129             :   !>    \param[in]  "logical, optional :: logical"                  True: use netcdf4 format.
     130             :   !>    \param[in]  "integer(i4), optional   :: deflate_level"      Compression level in netcdf4 (default: 1).
     131             : 
     132             :   !>    \author Matthias Cuntz
     133             :   !>    \date Nov 2012
     134             :   !>    \author Stephan Thober
     135             :   !>    \date Nov 2012
     136             :   !!      - added functions for i4 variables
     137             :   !>    \author Matthias Cuntz and Juliane Mai
     138             :   !>    \date Nov 2012
     139             :   !!      - append
     140             :   !!      - fake time dimension for 1D and 2D
     141             :   !!      - make i4 behave exactly as sp and dp
     142             :   !>    \date Mar 2013
     143             :   !!      - lfs, netcdf4, deflate_level
     144             :   interface dump_netcdf
     145             :     module procedure dump_netcdf_1d_sp, dump_netcdf_2d_sp, dump_netcdf_3d_sp, &
     146             :             dump_netcdf_4d_sp, dump_netcdf_5d_sp, &
     147             :             dump_netcdf_1d_dp, dump_netcdf_2d_dp, dump_netcdf_3d_dp, &
     148             :             dump_netcdf_4d_dp, dump_netcdf_5d_dp, &
     149             :             dump_netcdf_1d_i4, dump_netcdf_2d_i4, dump_netcdf_3d_i4, &
     150             :             dump_netcdf_4d_i4, dump_netcdf_5d_i4
     151             :   end interface dump_netcdf
     152             : 
     153             : 
     154             :   ! ------------------------------------------------------------------
     155             : 
     156             :   !>    \brief Extended dump_netcdf for multiple variables
     157             : 
     158             :   !>    \details
     159             :   !!    Write different variables including attributes to netcdf
     160             :   !!    file. The attributes are restricted to long_name, units,
     161             :   !!    and missing_value. It is also possible to append variables
     162             :   !!    when an unlimited dimension is specified.
     163             :   !!
     164             :   !!    \b Example
     165             :   !!
     166             :   !!    Let <field> be some three dimensional array
     167             :   !!
     168             :   !!    \code{.f90}
     169             :   !!    dnames(1) = 'x'
     170             :   !!    dnames(2) = 'y'
     171             :   !!    dnames(3) = 'time'
     172             :   !!    \endcode
     173             :   !!
     174             :   !!    The simplest call to write <field> to a file is
     175             :   !!
     176             :   !!    \code{.f90}
     177             :   !!    call var2nc('test.nc', field, dnames, 'h')
     178             :   !!    \endcode
     179             :   !!
     180             :   !!    With attributes it looks like
     181             :   !!
     182             :   !!    \code{.f90}
     183             :   !!    call var2nc('test.nc', field, dnames, 'h', &
     184             :   !!    long_name = 'height', units = '[m]', missing_value = -9999)
     185             :   !!    \endcode
     186             :   !!
     187             :   !!    or alternatively
     188             :   !!
     189             :   !!    \code{.f90}
     190             :   !!    character(256), dimension(3,2) :: attributes
     191             :   !!    attributes(1,1) = 'long_name'
     192             :   !!    attributes(1,2) = 'precipitation'
     193             :   !!    attributes(2,1) = 'units'
     194             :   !!    attributes(2,2) = '[mm/d]'
     195             :   !!    attributes(3,1) = 'missing_value'
     196             :   !!    attributes(3,2) = '-9999.'
     197             :   !!    call var2nc('test.nc', field, dnames, 'h', attributes = attributes, create = .true. )
     198             :   !!    \endcode
     199             :   !!
     200             :   !!    To be able to dynamically write <field>, an unlimited dimension
     201             :   !!    needs to be specified (in this example field could also be only two
     202             :   !!    dimensional)
     203             :   !!
     204             :   !!    \code{.f90}
     205             :   !!    call var2nc('test.nc', field(:,:,1), dnames, 'h', dim_unlimited=3)
     206             :   !!    \endcode
     207             :   !!
     208             :   !!    Now one can append an arbitrary number of time steps, e.g., the next 9
     209             :   !!    and the time has to be added again before
     210             :   !!
     211             :   !!    \code{.f90}
     212             :   !!    call var2nc('test.nc', (/20,...,100/), dnames(3:3), 'time',
     213             :   !!                dim_unlimited = 1 )
     214             :   !!    call var2nc('test.nc', field(:,:,2:10, dnames, 'h', dim_unlimited=3)
     215             :   !!    \endcode
     216             :   !!
     217             :   !!    You can also write another variable sharing the same dimensions
     218             :   !!
     219             :   !!    \code{.f90}
     220             :   !!    call var2nc('test.nc', field_2, dnames(1:2), 'h_2')
     221             :   !!    \endcode
     222             :   !!
     223             :   !!    The netcdf file can stay open after the first call and subsequent calls can use the file unit
     224             :   !!
     225             :   !!    \code{.f90}
     226             :   !!    ncid = -1_i4
     227             :   !!    call var2nc('test.nc', field_1, dnames(1:1), 'h_1', ncid=ncid) ! opens file
     228             :   !!    call var2nc('test.nc', field_2, dnames(1:2), 'h_2', ncid=ncid) ! uses ncid from last call
     229             :   !!    call close_netcdf(ncid)
     230             :   !!    \endcode
     231             :   !!
     232             :   !!    One can also give the start record number (on the unlimited dimension)
     233             :   !!
     234             :   !!    \code{.f90}
     235             :   !!    ncid = -1_i4
     236             :   !!    call var2nc('test.nc', time1, dnames(3:3), 'time', dim_unlimited=1_i4, ncid=ncid, create=.true.)
     237             :   !!    do i=1, n
     238             :   !!        call var2nc('test.nc', field_2(:,:,i), dnames(1:3), 'h_2', dim_unlimited=3_i4, ncid=ncid, nrec=i)
     239             :   !!    end do
     240             :   !!    call close_netcdf(ncid)
     241             :   !!    \endcode
     242             :   !!
     243             :   !!    That's it, enjoy!
     244             :   !!
     245             :   !!    \b Literature
     246             :   !!
     247             :   !!    The manual of the used netcdf fortran library can be found in
     248             :   !!    Robert Pincus & Ross Rew, The netcdf Fortran 90 Interface Guide
     249             : 
     250             :   !>        \param[in] "character(*) :: f_name"                             filename
     251             :   !>        \param[in] "integer(i4)/real(sp,dp) :: arr(:[,:[,:[,:[,:]]]])"  array to write
     252             :   !>        \param[in] "character(*) :: dnames(:)"                          dimension names
     253             :   !>        \param[in] "character(*) :: v_name"                             variable name
     254             :   !>        \param[in] "integer(i4),             optional :: dim_unlimited"     index of unlimited dimension
     255             :   !>        \param[in] "character(*),            optional :: long_name"         attribute
     256             :   !>        \param[in] "character(*),            optional :: units"             attribute
     257             :   !>        \param[in] "integer(i4)/real(sp,dp), optional :: missing_value"     attribute
     258             :   !>        \param[in] "character(256), dimension(:,:), optional :: attributes" two dimensional array of attributes
     259             :   !!                                                                size of first dimension equals number of attributes
     260             :   !!                                                                first entry of second dimension equals attribute name
     261             :   !!                                                                (e.g. long_name)\n
     262             :   !!                                                                second entry of second dimension equals attribute value
     263             :   !!                                                                (e.g. precipitation)\n
     264             :   !!                                                                every attribute is written as string with the exception of
     265             :   !!                                                                missing_value
     266             :   !>        \param[in] "logical,                 optional :: create"            flag - specify whether a
     267             :   !>                                                                            output file should be
     268             :   !>                                                                            created, default
     269             :   !>        \param[inout] "integer(i4)/real(sp,dp), optional :: ncid"   if not given filename will be opened and closed
     270             :   !!                                                                    if given and <0 then file will be opened
     271             :   !!                                                                    and ncid will return the file unit.
     272             :   !!                                                                    if given and >0 then file is assumed open and
     273             :   !!                                                                    ncid is used as file unit.
     274             :   !>        \param[in] "integer(i4),                optional :: nrec"   if given: start point on unlimited dimension.
     275             :   !>        \note It is not allowed to write the following numbers for the indicated type\n
     276             :   !!                        number | kind\n
     277             :   !!                -2.1474836E+09 | integer(i4)\n
     278             :   !!                 9.9692100E+36 | real(sp)\n
     279             :   !!        9.9692099683868690E+36 | real(dp)\n
     280             :   !!        These numbers are netcdf fortran 90 constants! They are used to determine the
     281             :   !!        chunksize of the already written variable. Hence, this routine cannot append
     282             :   !!        correctly to variables when these numbers are used. Only five dimensional
     283             :   !!        variables can be written, only one unlimited dimension can be defined.
     284             : 
     285             :   !>    \author Stephan Thober & Matthias Cuntz
     286             :   !>    \date May 2014
     287             :   !!        - created
     288             :   !>    \date Jun 2014
     289             :   !!        - added deflate, shuffle, and chunksizes
     290             :   !!        - automatically append variable at the end, renamed _FillValue to missing_value
     291             :   !>    \date Jul 2014
     292             :   !!        - add attributes array, introduced unlimited dimension that is added to the dimensions of the given array
     293             :   !>    \date Jan 2015
     294             :   !!        - changed chunk_size convention to one chunk per unit in unlimited dimension (typically time)
     295             :   !>    \date Feb 2015
     296             :   !!        - d_unlimit was not set in 5d cases
     297             :   !!        - use ne from mo_utils for fill value comparisons
     298             :   !!        - dummy(1) was sp instead of i4 in var2nc_1d_i4
     299             :   !>    \date May 2015
     300             :   !!        - ncid for opening the file only once
     301             :   !!        - nrec for writing a specific record
     302             : 
     303             :   interface var2nc
     304             :     module procedure var2nc_1d_i4, var2nc_1d_sp, var2nc_1d_dp, &
     305             :             var2nc_2d_i4, var2nc_2d_sp, var2nc_2d_dp, &
     306             :             var2nc_3d_i4, var2nc_3d_sp, var2nc_3d_dp, &
     307             :             var2nc_4d_i4, var2nc_4d_sp, var2nc_4d_dp, &
     308             :             var2nc_5d_i4, var2nc_5d_sp, var2nc_5d_dp
     309             :   end interface var2nc
     310             : 
     311             :   ! ----------------------------------------------------------------------------
     312             : 
     313             :   private
     314             : 
     315             :   ! ----------------------------------------------------------------------------
     316             : 
     317             : contains
     318             : 
     319             :   ! ----------------------------------------------------------------------------
     320             : 
     321             :   !>    \brief  Closes netcdf file stream.
     322             : 
     323             :   !>    \details
     324             :   !!    Closes a stream of an open netcdf file and saves the file.
     325             :   !!
     326             :   !!    \b Example
     327             :   !!
     328             :   !!    See test_mo_ncwrite.
     329             :   !!
     330             :   !!    \b Literature
     331             :   !!
     332             :   !!    1. http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-f90.html
     333             : 
     334             :   !>    \param[in]  "integer(i4) :: ncid"  Stream id of an open netcdf file which shall be closed
     335             : 
     336             :   !>    \note Closes only an already open stream
     337             : 
     338             :   !>    \author Luis Samaniego
     339             :   !>    \date   Feb 2011
     340             : 
     341             :   !>    \author Stephan Thober
     342             :   !>    \date   Dec 2011
     343             :   !!        - added comments and generalized
     344             : 
     345             :   !>    \author Matthias Cuntz
     346             :   !>    \date   Jan 2012
     347             :   !!        - Info
     348             :   !>    \date   Mar 2013
     349             :   !!        - removed Info
     350             : 
     351           0 :   subroutine close_netcdf(ncId)
     352             : 
     353             :     implicit none
     354             : 
     355             :     integer(i4), intent(in) :: ncId
     356             : 
     357             :     ! close: save new netcdf dataset
     358           0 :     call check(nf90_close(ncId))
     359             : 
     360           0 :   end subroutine close_netcdf
     361             : 
     362             :   ! ------------------------------------------------------------------------------
     363             : 
     364             :   !>    \brief Open and write on new netcdf file.
     365             : 
     366             :   !>    \details
     367             :   !!    This subroutine will open a new netcdf file and write the variable
     368             :   !!    attributes stored in the structure V in the file. Therefore V
     369             :   !!    has to be already set. See the file set_netcdf in test_mo_ncwrite
     370             :   !!    for an example.
     371             :   !!
     372             :   !!    \b Literature
     373             :   !!
     374             :   !!    1. http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-f90.html
     375             : 
     376             :   !>    \param[in]  "character(len=maxLen) :: File"             Filename of file to be written
     377             : 
     378             :   !>    \param[in]  "logical, optional     :: lfs"              True: enable netcdf3 large file support, i.e. 64-bit offset
     379             :   !>    \param[in]  "logical, optional     :: logical"          True: use netcdf4 format
     380             :   !>    \param[in]  "integer(i4), optional :: deflate_level"    compression level in netcdf4 (default: 1)
     381             :   !>    \param[out] "integer(i4)           :: ncid"             integer value of the stream for the opened file
     382             : 
     383             :   !>    \note This routine only writes attributes and variables which have been stored in V
     384             :   !!     nothing else.
     385             : 
     386             :   !>    \author Luis Samaniego
     387             :   !>    \date  Feb 2011
     388             : 
     389             :   !>    \author Stephan Thober
     390             :   !>    \date   Dec 2011
     391             :   !!        - added comments and generalized
     392             :   !>    \date   Feb 2013
     393             :   !!        - added flag for large file support
     394             :   !>    \date   Mar 2013
     395             :   !!        - buffersize
     396             : 
     397             :   !>    \author Matthias Cuntz
     398             :   !>    \date   Jan 2012
     399             :   !!        - Info
     400             :   !>    \date   Mar 2013
     401             :   !!        - netcdf4, deflate_level
     402             :   !!        - removed Info
     403             : 
     404           0 :   subroutine create_netcdf(Filename, ncid, lfs, netcdf4, deflate_level)
     405             : 
     406             :     implicit none
     407             : 
     408             :     ! netcdf related variables
     409             :     character(len = *), intent(in) :: Filename
     410             :     integer(i4), intent(out) :: ncid
     411             :     logical, intent(in), optional :: lfs           ! netcdf3 Large File Support
     412             :     logical, intent(in), optional :: netcdf4       ! netcdf4
     413             :     integer(i4), intent(in), optional :: deflate_level ! compression level in netcdf4
     414             : 
     415             :     integer(i4) :: i, j, k
     416             :     integer(i4), dimension(nAttDim) :: att_INT
     417           0 :     real(sp), dimension(nAttDim) :: att_FLOAT
     418           0 :     real(dp), dimension(nAttDim) :: att_DOUBLE
     419             :     character(len = maxLen), dimension(nAttDim) :: att_CHAR
     420             :     logical :: LargeFile
     421             :     logical :: inetcdf4
     422             :     integer(i4) :: deflate
     423             :     integer(i4) :: buffersize
     424           0 :     integer(i4), dimension(:), allocatable :: chunksizes ! Size of chunks in netcdf4 writing
     425             : 
     426           0 :     LargeFile = .false.
     427           0 :     if (present(lfs)) LargeFile = lfs
     428           0 :     inetcdf4 = .true.
     429           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
     430           0 :     deflate = 1
     431           0 :     if (present(deflate_level)) deflate = deflate_level
     432             :     ! 1  Create netcdf dataset: enter define mode     ->  get ncId
     433           0 :     if (inetcdf4) then
     434           0 :       call check(nf90_create(trim(Filename), NF90_NETCDF4, ncId))
     435             :     else
     436           0 :       if (LargeFile) then
     437           0 :         call check(nf90_create(trim(Filename), NF90_64BIT_OFFSET, ncId, chunksize = buffersize))
     438             :       else
     439             :         ! let the netcdf library chose a buffersize, that results in lesser write system calls
     440           0 :         call check(nf90_create(trim(Filename), NF90_CLOBBER, ncId, chunksize = buffersize))
     441             :       end if
     442             :     end if
     443             : 
     444             :     ! 2  Define dimensions                                 -> get dimId
     445           0 :     do i = 1, nDims
     446           0 :       call check(nf90_def_dim(ncId, Dnc(i)%name, Dnc(i)%len, Dnc(i)%dimId))
     447             :     end do
     448             : 
     449             :     ! 3 Define dimids array, which is used to pass the dimids of the dimensions of
     450             :     ! the netcdf variables
     451           0 :     do i = 1, nVars
     452           0 :       V(i)%unlimited = .false.
     453           0 :       V(i)%dimids = 0
     454           0 :       V(i)%start = 1
     455           0 :       V(i)%count = 1
     456           0 :       do k = 1, V(i)%nDims
     457           0 :         if (Dnc(V(i)%dimTypes(k))%len  == NF90_UNLIMITED) V(i)%unlimited = .true.
     458           0 :         V(i)%dimids(k) = Dnc(V(i)%dimTypes(k))%dimId
     459             :       end do
     460           0 :       if (V(i)%unlimited) then
     461             :         ! set counts for unlimited files (time is always the last dimension)
     462           0 :         if (V(i)%nDims == 1) cycle
     463           0 :         do k = 1, V(i)%nDims - 1
     464           0 :           V(i)%count(k) = Dnc(V(i)%dimTypes(k))%len
     465             :         end do
     466             :       end if
     467             :     end do
     468             : 
     469             :     ! 4 Define the netcdf variables and attributes                            -> get varId
     470           0 :     allocate(chunksizes(maxval(V(1 : nVars)%nDims)))
     471           0 :     do i = 1, nVars
     472           0 :       if (.not. V(i)%wFlag) cycle
     473           0 :       if (inetcdf4) then
     474           0 :         chunksizes(1 : V(i)%nDims) = Dnc(V(i)%dimTypes(1 : V(i)%nDims))%len
     475           0 :         chunksizes(V(i)%nDims) = 1
     476           0 :         call check(nf90_def_var(ncId, V(i)%name, V(i)%xtype, V(i)%dimids(1 : V(i)%nDims), V(i)%varId, &
     477           0 :                 chunksizes = chunksizes(1 : V(i)%nDims), shuffle = .true., deflate_level = deflate))
     478             :       else
     479           0 :         call check(nf90_def_var(ncId, V(i)%name, V(i)%xtype, V(i)%dimids(1 : V(i)%nDims), V(i)%varId))
     480             :       end if
     481           0 :       do k = 1, V(i)%nAtt
     482           0 :         select case (V(i)%att(k)%xType)
     483             :         case (NF90_CHAR)
     484             :           ! read(V(i)%att(k)%values, *) (att_CHAR(j), j =1, V(i)%att(k)%nValues)
     485           0 :           read(V(i)%att(k)%values, '(a)')  att_CHAR(1)
     486           0 :           call check(nf90_put_att (ncId, V(i)%varId, V(i)%att(k)%name, att_CHAR(1)))
     487             :         case (NF90_INT)
     488           0 :           read(V(i)%att(k)%values, *) (att_INT(j), j = 1, V(i)%att(k)%nValues)
     489           0 :           call check(nf90_put_att (ncId, V(i)%varId, V(i)%att(k)%name, att_INT(1 : V(i)%att(k)%nValues)))
     490             :         case (NF90_FLOAT)
     491           0 :           read(V(i)%att(k)%values, *) (att_FLOAT(j), j = 1, V(i)%att(k)%nValues)
     492           0 :           call check(nf90_put_att (ncId, V(i)%varId, V(i)%att(k)%name, att_FLOAT(1 : V(i)%att(k)%nValues)))
     493             :         case (NF90_DOUBLE)
     494           0 :           read(V(i)%att(k)%values, *) (att_DOUBLE(j), j = 1, V(i)%att(k)%nValues)
     495           0 :           call check(nf90_put_att (ncId, V(i)%varId, V(i)%att(k)%name, att_DOUBLE(1 : V(i)%att(k)%nValues)))
     496             :         end select
     497             :       end do
     498             :     end do
     499             : 
     500             :     ! 5 Global attributes
     501           0 :     do k = 1, nGAtt
     502           0 :       if (nonull(Gatt(k)%name)) then
     503           0 :         call check(nf90_put_att(ncId, NF90_GLOBAL, Gatt(k)%name, Gatt(k)%values))
     504             :       end if
     505             :     end do
     506             : 
     507             :     ! 6 end definitions: leave define mode
     508           0 :     call check(nf90_enddef(ncId))
     509             : 
     510           0 :     deallocate(chunksizes)
     511             : 
     512           0 :   end subroutine create_netcdf
     513             : 
     514             : 
     515             :   ! ------------------------------------------------------------------
     516             : 
     517           0 :   subroutine dump_netcdf_1d_sp(filename, arr, append, lfs, netcdf4, deflate_level)
     518             : 
     519             :     implicit none
     520             : 
     521             :     character(len = *), intent(in) :: filename ! netcdf file name
     522             :     real(sp), dimension(:), intent(in) :: arr      ! input array
     523             :     logical, optional, intent(in) :: append   ! append to existing file
     524             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
     525             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
     526             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
     527             : 
     528             :     integer(i4), parameter :: ndim = 1 ! Routine for ndim dimensional array
     529             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
     530             :     integer(i4), dimension(ndim + 1) :: dims     ! Size of each dimension
     531             :     integer(i4), dimension(ndim + 1) :: dimid    ! netcdf IDs of each dimension
     532             :     integer(i4), dimension(ndim + 2) :: varid    ! dimension variables and var id
     533             :     integer(i4), dimension(ndim + 1) :: start    ! start array for write of each time step
     534             :     integer(i4), dimension(ndim + 1) :: counter  ! length array for write of each time step
     535             :     integer(i4), dimension(ndim + 1) :: chunksizes ! Size of chunks in netcdf4 writing
     536             :     integer(i4) :: ncid                             ! netcdf file id
     537             :     integer(i4) :: i, j
     538             :     logical :: iappend
     539             :     integer(i4) :: idim    ! read dimension on append
     540             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
     541             :     logical :: LargeFile
     542             :     logical :: inetcdf4
     543             :     integer(i4) :: deflate
     544             :     integer(i4) :: buffersize
     545             : 
     546             :     ! append or not
     547           0 :     if (present(append)) then
     548           0 :       if (append) then
     549             :         iappend = .true.
     550             :       else
     551           0 :         iappend = .false.
     552             :       end if
     553             :     else
     554             :       iappend = .false.
     555             :     end if
     556           0 :     LargeFile = .false.
     557           0 :     if (present(lfs)) LargeFile = lfs
     558           0 :     inetcdf4 = .false.
     559           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
     560           0 :     deflate = 1
     561           0 :     if (present(deflate_level)) deflate = deflate_level
     562             : 
     563             :     ! dimension names
     564           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
     565             : 
     566           0 :     if (iappend) then
     567             :       ! open file
     568           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
     569             : 
     570             :       ! inquire variables time and var
     571           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim + 1)))
     572           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 2)))
     573           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 2), ndims = idim, dimids = dimid))
     574           0 :       if (idim /= ndim + 1) stop "dump_netcdf_1d_sp: number of variable dimensions /= number of file variable dimensions."
     575             : 
     576             :       ! inquire dimensions
     577           0 :       do i = 1, ndim + 1
     578           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
     579           0 :         if (i < ndim + 1) then
     580           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_1d_sp: dimension name problem."
     581           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_1d_sp: variable dimension /= file variable dimension."
     582             :         else
     583           0 :           if (trim(name) /= 'time') stop "dump_netcdf_1d_sp: time name problem."
     584             :         end if
     585             :       enddo
     586             : 
     587             :       ! append
     588           0 :       start(:) = 1
     589           0 :       counter(:) = dims
     590           0 :       counter(ndim + 1) = 1
     591           0 :       do i = 1, 1
     592           0 :         start(ndim + 1) = dims(ndim + 1) + i
     593           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/dims(ndim + 1) + i/), (/dims(ndim + 1) + i/)))
     594           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
     595             :       end do
     596             :     else
     597             :       ! open file
     598           0 :       if (inetcdf4) then
     599           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
     600             :       else
     601           0 :         if (LargeFile) then
     602           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
     603             :         else
     604           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
     605             :         end if
     606             :       end if
     607             : 
     608             :       ! define dims
     609           0 :       dims(1 : ndim) = shape(arr)
     610           0 :       do i = 1, ndim
     611           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
     612             :       end do
     613             :       ! define dim time
     614           0 :       dims(ndim + 1) = 1
     615           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim + 1)))
     616             : 
     617             :       ! define dim variables
     618           0 :       do i = 1, ndim
     619           0 :         if (inetcdf4) then
     620           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
     621             :         else
     622           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
     623             :         end if
     624             :       end do
     625             :       ! define time variable
     626           0 :       if (inetcdf4) then
     627           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
     628             :       else
     629           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
     630             :       end if
     631             : 
     632             :       ! define variable
     633           0 :       if (inetcdf4) then
     634           0 :         chunksizes(1 : ndim) = dims(1 : ndim)
     635           0 :         chunksizes(ndim + 1) = 1
     636             :         call check(nf90_def_var(ncid, 'var', NF90_FLOAT, dimid, varid(ndim + 2), &
     637           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
     638             :       else
     639           0 :         call check(nf90_def_var(ncid, 'var', NF90_FLOAT, dimid, varid(ndim + 2)))
     640             :       end if
     641             : 
     642             :       ! end define mode
     643           0 :       call check(nf90_enddef(ncid))
     644             : 
     645             :       ! write dimensions
     646           0 :       do i = 1, ndim
     647           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
     648             :       end do
     649             : 
     650             :       ! write time and variable
     651           0 :       start(:) = 1
     652           0 :       counter(:) = dims
     653           0 :       counter(ndim + 1) = 1
     654           0 :       do i = 1, 1
     655           0 :         start(ndim + 1) = i
     656           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/i/), (/i/)))
     657           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
     658             :       end do
     659             :     end if
     660             : 
     661             :     ! close netcdf file
     662           0 :     call check(nf90_close(ncid))
     663             : 
     664           0 :   end subroutine dump_netcdf_1d_sp
     665             : 
     666             : 
     667           0 :   subroutine dump_netcdf_2d_sp(filename, arr, append, lfs, netcdf4, deflate_level)
     668             : 
     669             :     implicit none
     670             : 
     671             :     character(len = *), intent(in) :: filename ! netcdf file name
     672             :     real(sp), dimension(:, :), intent(in) :: arr      ! input array
     673             :     logical, optional, intent(in) :: append   ! append to existing file
     674             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
     675             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
     676             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
     677             : 
     678             :     integer(i4), parameter :: ndim = 2 ! Routine for ndim dimensional array
     679             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
     680             :     integer(i4), dimension(ndim + 1) :: dims     ! Size of each dimension
     681             :     integer(i4), dimension(ndim + 1) :: dimid    ! netcdf IDs of each dimension
     682             :     integer(i4), dimension(ndim + 2) :: varid    ! dimension variables and var id
     683             :     integer(i4), dimension(ndim + 1) :: start    ! start array for write of each time step
     684             :     integer(i4), dimension(ndim + 1) :: counter  ! length array for write of each time step
     685             :     integer(i4), dimension(ndim + 1) :: chunksizes ! Size of chunks in netcdf4 writing
     686             :     integer(i4) :: ncid                             ! netcdf file id
     687             :     integer(i4) :: i, j
     688             :     logical :: iappend
     689             :     integer(i4) :: idim    ! read dimension on append
     690             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
     691             :     logical :: LargeFile
     692             :     logical :: inetcdf4
     693             :     integer(i4) :: deflate
     694             :     integer(i4) :: buffersize
     695             : 
     696             :     ! append or not
     697           0 :     if (present(append)) then
     698           0 :       if (append) then
     699             :         iappend = .true.
     700             :       else
     701           0 :         iappend = .false.
     702             :       end if
     703             :     else
     704             :       iappend = .false.
     705             :     end if
     706           0 :     LargeFile = .false.
     707           0 :     if (present(lfs)) LargeFile = lfs
     708           0 :     inetcdf4 = .false.
     709           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
     710           0 :     deflate = 1
     711           0 :     if (present(deflate_level)) deflate = deflate_level
     712             : 
     713             :     ! dimension names
     714           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
     715             : 
     716           0 :     if (iappend) then
     717             :       ! open file
     718           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
     719             : 
     720             :       ! inquire variables time and var
     721           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim + 1)))
     722           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 2)))
     723           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 2), ndims = idim, dimids = dimid))
     724           0 :       if (idim /= ndim + 1) stop "dump_netcdf_2d_sp: number of variable dimensions /= number of file variable dimensions."
     725             : 
     726             :       ! inquire dimensions
     727           0 :       do i = 1, ndim + 1
     728           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
     729           0 :         if (i < ndim + 1) then
     730           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_2d_sp: dimension name problem."
     731           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_2d_sp: variable dimension /= file variable dimension."
     732             :         else
     733           0 :           if (trim(name) /= 'time') stop "dump_netcdf_2d_sp: time name problem."
     734             :         end if
     735             :       enddo
     736             : 
     737             :       ! append
     738           0 :       start(:) = 1
     739           0 :       counter(:) = dims
     740           0 :       counter(ndim + 1) = 1
     741           0 :       do i = 1, 1
     742           0 :         start(ndim + 1) = dims(ndim + 1) + i
     743           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/dims(ndim + 1) + i/), (/dims(ndim + 1) + i/)))
     744           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
     745             :       end do
     746             :     else
     747             :       ! open file
     748           0 :       if (inetcdf4) then
     749           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
     750             :       else
     751           0 :         if (LargeFile) then
     752           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
     753             :         else
     754           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
     755             :         end if
     756             :       end if
     757             : 
     758             :       ! define dims
     759           0 :       dims(1 : ndim) = shape(arr)
     760           0 :       do i = 1, ndim
     761           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
     762             :       end do
     763             :       ! define dim time
     764           0 :       dims(ndim + 1) = 1
     765           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim + 1)))
     766             : 
     767             :       ! define dim variables
     768           0 :       do i = 1, ndim
     769           0 :         if (inetcdf4) then
     770           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
     771             :         else
     772           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
     773             :         end if
     774             :       end do
     775             :       ! define time variable
     776           0 :       if (inetcdf4) then
     777           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
     778             :       else
     779           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
     780             :       end if
     781             : 
     782             :       ! define variable
     783           0 :       if (inetcdf4) then
     784           0 :         chunksizes(1 : ndim) = dims(1 : ndim)
     785           0 :         chunksizes(ndim + 1) = 1
     786             :         call check(nf90_def_var(ncid, 'var', NF90_FLOAT, dimid, varid(ndim + 2), &
     787           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
     788             :       else
     789           0 :         call check(nf90_def_var(ncid, 'var', NF90_FLOAT, dimid, varid(ndim + 2)))
     790             :       end if
     791             : 
     792             :       ! end define mode
     793           0 :       call check(nf90_enddef(ncid))
     794             : 
     795             :       ! write dimensions
     796           0 :       do i = 1, ndim
     797           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
     798             :       end do
     799             : 
     800             :       ! write time and variable
     801           0 :       start(:) = 1
     802           0 :       counter(:) = dims
     803           0 :       counter(ndim + 1) = 1
     804           0 :       do i = 1, 1
     805           0 :         start(ndim + 1) = i
     806           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/i/), (/i/)))
     807           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
     808             :       end do
     809             :     end if
     810             : 
     811             :     ! close netcdf file
     812           0 :     call check(nf90_close(ncid))
     813             : 
     814           0 :   end subroutine dump_netcdf_2d_sp
     815             : 
     816             : 
     817           0 :   subroutine dump_netcdf_3d_sp(filename, arr, append, lfs, netcdf4, deflate_level)
     818             : 
     819             :     implicit none
     820             : 
     821             :     character(len = *), intent(in) :: filename ! netcdf file name
     822             :     real(sp), dimension(:, :, :), intent(in) :: arr      ! input array
     823             :     logical, optional, intent(in) :: append   ! append to existing file
     824             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
     825             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
     826             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
     827             : 
     828             :     integer(i4), parameter :: ndim = 3 ! Routine for ndim dimensional array
     829             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
     830             :     integer(i4), dimension(ndim) :: dims     ! Size of each dimension
     831             :     integer(i4), dimension(ndim) :: dimid    ! netcdf IDs of each dimension
     832             :     integer(i4), dimension(ndim + 1) :: varid    ! dimension variables and var id
     833             :     integer(i4), dimension(ndim) :: start    ! start array for write of each time step
     834             :     integer(i4), dimension(ndim) :: counter  ! length array for write of each time step
     835             :     integer(i4), dimension(ndim) :: chunksizes ! Size of chunks in netcdf4 writing
     836             :     integer(i4) :: ncid                             ! netcdf file id
     837             :     integer(i4) :: i, j
     838             :     logical :: iappend
     839             :     integer(i4) :: idim    ! read dimension on append
     840             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
     841             :     logical :: LargeFile
     842             :     logical :: inetcdf4
     843             :     integer(i4) :: deflate
     844             :     integer(i4) :: buffersize
     845             : 
     846             :     ! append or not
     847           0 :     if (present(append)) then
     848           0 :       if (append) then
     849             :         iappend = .true.
     850             :       else
     851           0 :         iappend = .false.
     852             :       end if
     853             :     else
     854             :       iappend = .false.
     855             :     end if
     856           0 :     LargeFile = .false.
     857           0 :     if (present(lfs)) LargeFile = lfs
     858           0 :     inetcdf4 = .false.
     859           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
     860           0 :     deflate = 1
     861           0 :     if (present(deflate_level)) deflate = deflate_level
     862             : 
     863             :     ! dimension names
     864           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
     865             : 
     866           0 :     if (iappend) then
     867             :       ! open file
     868           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
     869             : 
     870             :       ! inquire variables time and var
     871           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim)))
     872           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 1)))
     873           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 1), ndims = idim, dimids = dimid))
     874           0 :       if (idim /= ndim) stop "dump_netcdf_3d_sp: number of variable dimensions /= number of file variable dimensions."
     875             : 
     876             :       ! inquire dimensions
     877           0 :       do i = 1, ndim
     878           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
     879           0 :         if (i < ndim) then
     880           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_3d_sp: dimension name problem."
     881           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_3d_sp: variable dimension /= file variable dimension."
     882             :         else
     883           0 :           if (trim(name) /= 'time') stop "dump_netcdf_3d_sp: time name problem."
     884             :         end if
     885             :       enddo
     886             : 
     887             :       ! append
     888           0 :       start(:) = 1
     889           0 :       counter(:) = dims
     890           0 :       counter(ndim) = 1
     891           0 :       do i = 1, size(arr, ndim)
     892           0 :         start(ndim) = dims(ndim) + i
     893           0 :         call check(nf90_put_var(ncid, varid(ndim), (/dims(ndim) + i/), (/dims(ndim) + i/)))
     894           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, i), start, counter))
     895             :       end do
     896             :     else
     897             :       ! open file
     898           0 :       if (inetcdf4) then
     899           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
     900             :       else
     901           0 :         if (LargeFile) then
     902           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
     903             :         else
     904           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
     905             :         end if
     906             :       end if
     907             : 
     908             :       ! define dims
     909           0 :       dims = shape(arr)
     910           0 :       do i = 1, ndim - 1
     911           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
     912             :       end do
     913             :       ! define dim time
     914           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim)))
     915             : 
     916             :       ! define dim variables
     917           0 :       do i = 1, ndim - 1
     918           0 :         if (inetcdf4) then
     919           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
     920             :         else
     921           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
     922             :         end if
     923             :       end do
     924             :       ! define time variable
     925           0 :       if (inetcdf4) then
     926           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
     927             :       else
     928           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
     929             :       end if
     930             : 
     931             :       ! define variable
     932           0 :       if (inetcdf4) then
     933           0 :         chunksizes(1 : ndim - 1) = dims(1 : ndim - 1)
     934           0 :         chunksizes(ndim) = 1
     935             :         call check(nf90_def_var(ncid, 'var', NF90_FLOAT, dimid, varid(ndim + 1), &
     936           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
     937             :       else
     938           0 :         call check(nf90_def_var(ncid, 'var', NF90_FLOAT, dimid, varid(ndim + 1)))
     939             :       end if
     940             : 
     941             :       ! end define mode
     942           0 :       call check(nf90_enddef(ncid))
     943             : 
     944             :       ! write dimensions
     945           0 :       do i = 1, ndim - 1
     946           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
     947             :       end do
     948             : 
     949             :       ! write time and variable
     950           0 :       start(:) = 1
     951           0 :       counter(:) = dims
     952           0 :       counter(ndim) = 1
     953           0 :       do i = 1, dims(ndim)
     954           0 :         start(ndim) = i
     955           0 :         call check(nf90_put_var(ncid, varid(ndim), (/i/), (/i/)))
     956           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, i), start, counter))
     957             :       end do
     958             :     end if
     959             : 
     960             :     ! close netcdf file
     961           0 :     call check(nf90_close(ncid))
     962             : 
     963           0 :   end subroutine dump_netcdf_3d_sp
     964             : 
     965             : 
     966           0 :   subroutine dump_netcdf_4d_sp(filename, arr, append, lfs, netcdf4, deflate_level)
     967             : 
     968             :     implicit none
     969             : 
     970             :     character(len = *), intent(in) :: filename ! netcdf file name
     971             :     real(sp), dimension(:, :, :, :), intent(in) :: arr      ! input array
     972             :     logical, optional, intent(in) :: append   ! append to existing file
     973             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
     974             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
     975             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
     976             : 
     977             :     integer(i4), parameter :: ndim = 4 ! Routine for ndim dimensional array
     978             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
     979             :     integer(i4), dimension(ndim) :: dims     ! Size of each dimension
     980             :     integer(i4), dimension(ndim) :: dimid    ! netcdf IDs of each dimension
     981             :     integer(i4), dimension(ndim + 1) :: varid    ! dimension variables and var id
     982             :     integer(i4), dimension(ndim) :: start    ! start array for write of each time step
     983             :     integer(i4), dimension(ndim) :: counter  ! length array for write of each time step
     984             :     integer(i4), dimension(ndim) :: chunksizes ! Size of chunks in netcdf4 writing
     985             :     integer(i4) :: ncid                             ! netcdf file id
     986             :     integer(i4) :: i, j
     987             :     logical :: iappend
     988             :     integer(i4) :: idim    ! read dimension on append
     989             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
     990             :     logical :: LargeFile
     991             :     logical :: inetcdf4
     992             :     integer(i4) :: deflate
     993             :     integer(i4) :: buffersize
     994             : 
     995             :     ! append or not
     996           0 :     if (present(append)) then
     997           0 :       if (append) then
     998             :         iappend = .true.
     999             :       else
    1000           0 :         iappend = .false.
    1001             :       end if
    1002             :     else
    1003             :       iappend = .false.
    1004             :     end if
    1005           0 :     LargeFile = .false.
    1006           0 :     if (present(lfs)) LargeFile = lfs
    1007           0 :     inetcdf4 = .false.
    1008           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
    1009           0 :     deflate = 1
    1010           0 :     if (present(deflate_level)) deflate = deflate_level
    1011             : 
    1012             :     ! dimension names
    1013           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    1014             : 
    1015           0 :     if (iappend) then
    1016             :       ! open file
    1017           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    1018             : 
    1019             :       ! inquire variables time and var
    1020           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim)))
    1021           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 1)))
    1022           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 1), ndims = idim, dimids = dimid))
    1023           0 :       if (idim /= ndim) stop "dump_netcdf_4d_sp: number of variable dimensions /= number of file variable dimensions."
    1024             : 
    1025             :       ! inquire dimensions
    1026           0 :       do i = 1, ndim
    1027           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    1028           0 :         if (i < ndim) then
    1029           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_4d_sp: dimension name problem."
    1030           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_4d_sp: variable dimension /= file variable dimension."
    1031             :         else
    1032           0 :           if (trim(name) /= 'time') stop "dump_netcdf_4d_sp: time name problem."
    1033             :         end if
    1034             :       enddo
    1035             : 
    1036             :       ! append
    1037           0 :       start(:) = 1
    1038           0 :       counter(:) = dims
    1039           0 :       counter(ndim) = 1
    1040           0 :       do i = 1, size(arr, ndim)
    1041           0 :         start(ndim) = dims(ndim) + i
    1042           0 :         call check(nf90_put_var(ncid, varid(ndim), (/dims(ndim) + i/), (/dims(ndim) + i/)))
    1043           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, i), start, counter))
    1044             :       end do
    1045             :     else
    1046             :       ! open file
    1047           0 :       if (inetcdf4) then
    1048           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    1049             :       else
    1050           0 :         if (LargeFile) then
    1051           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    1052             :         else
    1053           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    1054             :         end if
    1055             :       end if
    1056             : 
    1057             :       ! define dims
    1058           0 :       dims = shape(arr)
    1059           0 :       do i = 1, ndim - 1
    1060           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    1061             :       end do
    1062             :       ! define dim time
    1063           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim)))
    1064             : 
    1065             :       ! define dim variables
    1066           0 :       do i = 1, ndim - 1
    1067           0 :         if (inetcdf4) then
    1068           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1069             :         else
    1070           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1071             :         end if
    1072             :       end do
    1073             :       ! define time variable
    1074           0 :       if (inetcdf4) then
    1075           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    1076             :       else
    1077           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    1078             :       end if
    1079             : 
    1080             :       ! define variable
    1081           0 :       if (inetcdf4) then
    1082           0 :         chunksizes(1 : ndim - 1) = dims(1 : ndim - 1)
    1083           0 :         chunksizes(ndim) = 1
    1084             :         call check(nf90_def_var(ncid, 'var', NF90_FLOAT, dimid, varid(ndim + 1), &
    1085           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    1086             :       else
    1087           0 :         call check(nf90_def_var(ncid, 'var', NF90_FLOAT, dimid, varid(ndim + 1)))
    1088             :       end if
    1089             : 
    1090             :       ! end define mode
    1091           0 :       call check(nf90_enddef(ncid))
    1092             : 
    1093             :       ! write dimensions
    1094           0 :       do i = 1, ndim - 1
    1095           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    1096             :       end do
    1097             : 
    1098             :       ! write time and variable
    1099           0 :       start(:) = 1
    1100           0 :       counter(:) = dims
    1101           0 :       counter(ndim) = 1
    1102           0 :       do i = 1, dims(ndim)
    1103           0 :         start(ndim) = i
    1104           0 :         call check(nf90_put_var(ncid, varid(ndim), (/i/), (/i/)))
    1105           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, i), start, counter))
    1106             :       end do
    1107             :     end if
    1108             : 
    1109             :     ! close netcdf file
    1110           0 :     call check(nf90_close(ncid))
    1111             : 
    1112           0 :   end subroutine dump_netcdf_4d_sp
    1113             : 
    1114             : 
    1115           0 :   subroutine dump_netcdf_5d_sp(filename, arr, append, lfs, netcdf4, deflate_level)
    1116             : 
    1117             :     implicit none
    1118             : 
    1119             :     character(len = *), intent(in) :: filename ! netcdf file name
    1120             :     real(sp), dimension(:, :, :, :, :), intent(in) :: arr      ! input array
    1121             :     logical, optional, intent(in) :: append   ! append to existing file
    1122             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
    1123             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
    1124             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
    1125             : 
    1126             :     integer(i4), parameter :: ndim = 5 ! Routine for ndim dimensional array
    1127             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
    1128             :     integer(i4), dimension(ndim) :: dims     ! Size of each dimension
    1129             :     integer(i4), dimension(ndim) :: dimid    ! netcdf IDs of each dimension
    1130             :     integer(i4), dimension(ndim + 1) :: varid    ! dimension variables and var id
    1131             :     integer(i4), dimension(ndim) :: start    ! start array for write of each time step
    1132             :     integer(i4), dimension(ndim) :: counter  ! length array for write of each time step
    1133             :     integer(i4), dimension(ndim) :: chunksizes ! Size of chunks in netcdf4 writing
    1134             :     integer(i4) :: ncid                             ! netcdf file id
    1135             :     integer(i4) :: i, j
    1136             :     logical :: iappend
    1137             :     integer(i4) :: idim    ! read dimension on append
    1138             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
    1139             :     logical :: LargeFile
    1140             :     logical :: inetcdf4
    1141             :     integer(i4) :: deflate
    1142             :     integer(i4) :: buffersize
    1143             : 
    1144             :     ! append or not
    1145           0 :     if (present(append)) then
    1146           0 :       if (append) then
    1147             :         iappend = .true.
    1148             :       else
    1149           0 :         iappend = .false.
    1150             :       end if
    1151             :     else
    1152             :       iappend = .false.
    1153             :     end if
    1154           0 :     LargeFile = .false.
    1155           0 :     if (present(lfs)) LargeFile = lfs
    1156           0 :     inetcdf4 = .false.
    1157           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
    1158           0 :     deflate = 1
    1159           0 :     if (present(deflate_level)) deflate = deflate_level
    1160             : 
    1161             :     ! dimension names
    1162           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    1163             : 
    1164           0 :     if (iappend) then
    1165             :       ! open file
    1166           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    1167             : 
    1168             :       ! inquire variables time and var
    1169           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim)))
    1170           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 1)))
    1171           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 1), ndims = idim, dimids = dimid))
    1172           0 :       if (idim /= ndim) stop "dump_netcdf_5d_sp: number of variable dimensions /= number of file variable dimensions."
    1173             : 
    1174             :       ! inquire dimensions
    1175           0 :       do i = 1, ndim
    1176           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    1177           0 :         if (i < ndim) then
    1178           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_5d_sp: dimension name problem."
    1179           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_5d_sp: variable dimension /= file variable dimension."
    1180             :         else
    1181           0 :           if (trim(name) /= 'time') stop "dump_netcdf_5d_sp: time name problem."
    1182             :         end if
    1183             :       enddo
    1184             : 
    1185             :       ! append
    1186           0 :       start(:) = 1
    1187           0 :       counter(:) = dims
    1188           0 :       counter(ndim) = 1
    1189           0 :       do i = 1, size(arr, ndim)
    1190           0 :         start(ndim) = dims(ndim) + i
    1191           0 :         call check(nf90_put_var(ncid, varid(ndim), (/dims(ndim) + i/), (/dims(ndim) + i/)))
    1192           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, :, i), start, counter))
    1193             :       end do
    1194             :     else
    1195             :       ! open file
    1196           0 :       if (inetcdf4) then
    1197           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    1198             :       else
    1199           0 :         if (LargeFile) then
    1200           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    1201             :         else
    1202           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    1203             :         end if
    1204             :       end if
    1205             : 
    1206             :       ! define dims
    1207           0 :       dims = shape(arr)
    1208           0 :       do i = 1, ndim - 1
    1209           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    1210             :       end do
    1211             :       ! define dim time
    1212           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim)))
    1213             : 
    1214             :       ! define dim variables
    1215           0 :       do i = 1, ndim - 1
    1216           0 :         if (inetcdf4) then
    1217           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1218             :         else
    1219           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1220             :         end if
    1221             :       end do
    1222             :       ! define time variable
    1223           0 :       if (inetcdf4) then
    1224           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    1225             :       else
    1226           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    1227             :       end if
    1228             : 
    1229             :       ! define variable
    1230           0 :       if (inetcdf4) then
    1231           0 :         chunksizes(1 : ndim - 1) = dims(1 : ndim - 1)
    1232           0 :         chunksizes(ndim) = 1
    1233             :         call check(nf90_def_var(ncid, 'var', NF90_FLOAT, dimid, varid(ndim + 1), &
    1234           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    1235             :       else
    1236           0 :         call check(nf90_def_var(ncid, 'var', NF90_FLOAT, dimid, varid(ndim + 1)))
    1237             :       end if
    1238             : 
    1239             :       ! end define mode
    1240           0 :       call check(nf90_enddef(ncid))
    1241             : 
    1242             :       ! write dimensions
    1243           0 :       do i = 1, ndim - 1
    1244           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    1245             :       end do
    1246             : 
    1247             :       ! write time and variable
    1248           0 :       start(:) = 1
    1249           0 :       counter(:) = dims
    1250           0 :       counter(ndim) = 1
    1251           0 :       do i = 1, dims(ndim)
    1252           0 :         start(ndim) = i
    1253           0 :         call check(nf90_put_var(ncid, varid(ndim), (/i/), (/i/)))
    1254           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, :, i), start, counter))
    1255             :       end do
    1256             :     end if
    1257             : 
    1258             :     ! close netcdf file
    1259           0 :     call check(nf90_close(ncid))
    1260             : 
    1261           0 :   end subroutine dump_netcdf_5d_sp
    1262             : 
    1263             : 
    1264           0 :   subroutine dump_netcdf_1d_dp(filename, arr, append, lfs, netcdf4, deflate_level)
    1265             : 
    1266             :     implicit none
    1267             : 
    1268             :     character(len = *), intent(in) :: filename ! netcdf file name
    1269             :     real(dp), dimension(:), intent(in) :: arr      ! input array
    1270             :     logical, optional, intent(in) :: append   ! append to existing file
    1271             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
    1272             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
    1273             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
    1274             : 
    1275             :     integer(i4), parameter :: ndim = 1 ! Routine for ndim dimensional array
    1276             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
    1277             :     integer(i4), dimension(ndim + 1) :: dims     ! Size of each dimension
    1278             :     integer(i4), dimension(ndim + 1) :: dimid    ! netcdf IDs of each dimension
    1279             :     integer(i4), dimension(ndim + 2) :: varid    ! dimension variables and var id
    1280             :     integer(i4), dimension(ndim + 1) :: start    ! start array for write of each time step
    1281             :     integer(i4), dimension(ndim + 1) :: counter  ! length array for write of each time step
    1282             :     integer(i4), dimension(ndim + 1) :: chunksizes ! Size of chunks in netcdf4 writing
    1283             :     integer(i4) :: ncid                             ! netcdf file id
    1284             :     integer(i4) :: i, j
    1285             :     logical :: iappend
    1286             :     integer(i4) :: idim    ! read dimension on append
    1287             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
    1288             :     logical :: LargeFile
    1289             :     logical :: inetcdf4
    1290             :     integer(i4) :: deflate
    1291             :     integer(i4) :: buffersize
    1292             : 
    1293             :     ! append or not
    1294           0 :     if (present(append)) then
    1295           0 :       if (append) then
    1296             :         iappend = .true.
    1297             :       else
    1298           0 :         iappend = .false.
    1299             :       end if
    1300             :     else
    1301             :       iappend = .false.
    1302             :     end if
    1303           0 :     LargeFile = .false.
    1304           0 :     if (present(lfs)) LargeFile = lfs
    1305           0 :     inetcdf4 = .false.
    1306           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
    1307           0 :     deflate = 1
    1308           0 :     if (present(deflate_level)) deflate = deflate_level
    1309             : 
    1310             :     ! dimension names
    1311           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    1312             : 
    1313           0 :     if (iappend) then
    1314             :       ! open file
    1315           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    1316             : 
    1317             :       ! inquire variables time and var
    1318           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim + 1)))
    1319           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 2)))
    1320           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 2), ndims = idim, dimids = dimid))
    1321           0 :       if (idim /= ndim + 1) stop "dump_netcdf_1d_dp: number of variable dimensions /= number of file variable dimensions."
    1322             : 
    1323             :       ! inquire dimensions
    1324           0 :       do i = 1, ndim + 1
    1325           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    1326           0 :         if (i < ndim + 1) then
    1327           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_1d_dp: dimension name problem."
    1328           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_1d_dp: variable dimension /= file variable dimension."
    1329             :         else
    1330           0 :           if (trim(name) /= 'time') stop "dump_netcdf_1d_dp: time name problem."
    1331             :         end if
    1332             :       enddo
    1333             : 
    1334             :       ! append
    1335           0 :       start(:) = 1
    1336           0 :       counter(:) = dims
    1337           0 :       counter(ndim + 1) = 1
    1338           0 :       do i = 1, 1
    1339           0 :         start(ndim + 1) = dims(ndim + 1) + i
    1340           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/dims(ndim + 1) + i/), (/dims(ndim + 1) + i/)))
    1341           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
    1342             :       end do
    1343             :     else
    1344             :       ! open file
    1345           0 :       if (inetcdf4) then
    1346           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    1347             :       else
    1348           0 :         if (LargeFile) then
    1349           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    1350             :         else
    1351           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    1352             :         end if
    1353             :       end if
    1354             : 
    1355             :       ! define dims
    1356           0 :       dims(1 : ndim) = shape(arr)
    1357           0 :       do i = 1, ndim
    1358           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    1359             :       end do
    1360             :       ! define dim time
    1361           0 :       dims(ndim + 1) = 1
    1362           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim + 1)))
    1363             : 
    1364             :       ! define dim variables
    1365           0 :       do i = 1, ndim
    1366           0 :         if (inetcdf4) then
    1367           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1368             :         else
    1369           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1370             :         end if
    1371             :       end do
    1372             :       ! define time variable
    1373           0 :       if (inetcdf4) then
    1374           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
    1375             :       else
    1376           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
    1377             :       end if
    1378             : 
    1379             :       ! define variable
    1380           0 :       if (inetcdf4) then
    1381           0 :         chunksizes(1 : ndim) = dims(1 : ndim)
    1382           0 :         chunksizes(ndim + 1) = 1
    1383             :         call check(nf90_def_var(ncid, 'var', NF90_DOUBLE, dimid, varid(ndim + 2), &
    1384           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    1385             :       else
    1386           0 :         call check(nf90_def_var(ncid, 'var', NF90_DOUBLE, dimid, varid(ndim + 2)))
    1387             :       end if
    1388             : 
    1389             :       ! end define mode
    1390           0 :       call check(nf90_enddef(ncid))
    1391             : 
    1392             :       ! write dimensions
    1393           0 :       do i = 1, ndim
    1394           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    1395             :       end do
    1396             : 
    1397             :       ! write time and variable
    1398           0 :       start(:) = 1
    1399           0 :       counter(:) = dims
    1400           0 :       counter(ndim + 1) = 1
    1401           0 :       do i = 1, 1
    1402           0 :         start(ndim + 1) = i
    1403           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/i/), (/i/)))
    1404           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
    1405             :       end do
    1406             :     end if
    1407             : 
    1408             :     ! close netcdf file
    1409           0 :     call check(nf90_close(ncid))
    1410             : 
    1411           0 :   end subroutine dump_netcdf_1d_dp
    1412             : 
    1413             : 
    1414           0 :   subroutine dump_netcdf_2d_dp(filename, arr, append, lfs, netcdf4, deflate_level)
    1415             : 
    1416             :     implicit none
    1417             : 
    1418             :     character(len = *), intent(in) :: filename ! netcdf file name
    1419             :     real(dp), dimension(:, :), intent(in) :: arr      ! input array
    1420             :     logical, optional, intent(in) :: append   ! append to existing file
    1421             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
    1422             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
    1423             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
    1424             : 
    1425             :     integer(i4), parameter :: ndim = 2 ! Routine for ndim dimensional array
    1426             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
    1427             :     integer(i4), dimension(ndim + 1) :: dims     ! Size of each dimension
    1428             :     integer(i4), dimension(ndim + 1) :: dimid    ! netcdf IDs of each dimension
    1429             :     integer(i4), dimension(ndim + 2) :: varid    ! dimension variables and var id
    1430             :     integer(i4), dimension(ndim + 1) :: start    ! start array for write of each time step
    1431             :     integer(i4), dimension(ndim + 1) :: counter  ! length array for write of each time step
    1432             :     integer(i4), dimension(ndim + 1) :: chunksizes ! Size of chunks in netcdf4 writing
    1433             :     integer(i4) :: ncid                             ! netcdf file id
    1434             :     integer(i4) :: i, j
    1435             :     logical :: iappend
    1436             :     integer(i4) :: idim    ! read dimension on append
    1437             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
    1438             :     logical :: LargeFile
    1439             :     logical :: inetcdf4
    1440             :     integer(i4) :: deflate
    1441             :     integer(i4) :: buffersize
    1442             : 
    1443             :     ! append or not
    1444           0 :     if (present(append)) then
    1445           0 :       if (append) then
    1446             :         iappend = .true.
    1447             :       else
    1448           0 :         iappend = .false.
    1449             :       end if
    1450             :     else
    1451             :       iappend = .false.
    1452             :     end if
    1453           0 :     LargeFile = .false.
    1454           0 :     if (present(lfs)) LargeFile = lfs
    1455           0 :     inetcdf4 = .false.
    1456           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
    1457           0 :     deflate = 1
    1458           0 :     if (present(deflate_level)) deflate = deflate_level
    1459             : 
    1460             :     ! dimension names
    1461           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    1462             : 
    1463           0 :     if (iappend) then
    1464             :       ! open file
    1465           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    1466             : 
    1467             :       ! inquire variables time and var
    1468           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim + 1)))
    1469           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 2)))
    1470           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 2), ndims = idim, dimids = dimid))
    1471           0 :       if (idim /= ndim + 1) stop "dump_netcdf_2d_dp: number of variable dimensions /= number of file variable dimensions."
    1472             : 
    1473             :       ! inquire dimensions
    1474           0 :       do i = 1, ndim + 1
    1475           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    1476           0 :         if (i < ndim + 1) then
    1477           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_2d_dp: dimension name problem."
    1478           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_2d_dp: variable dimension /= file variable dimension."
    1479             :         else
    1480           0 :           if (trim(name) /= 'time') stop "dump_netcdf_2d_dp: time name problem."
    1481             :         end if
    1482             :       enddo
    1483             : 
    1484             :       ! append
    1485           0 :       start(:) = 1
    1486           0 :       counter(:) = dims
    1487           0 :       counter(ndim + 1) = 1
    1488           0 :       do i = 1, 1
    1489           0 :         start(ndim + 1) = dims(ndim + 1) + i
    1490           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/dims(ndim + 1) + i/), (/dims(ndim + 1) + i/)))
    1491           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
    1492             :       end do
    1493             :     else
    1494             :       ! open file
    1495           0 :       if (inetcdf4) then
    1496           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    1497             :       else
    1498           0 :         if (LargeFile) then
    1499           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    1500             :         else
    1501           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    1502             :         end if
    1503             :       end if
    1504             : 
    1505             :       ! define dims
    1506           0 :       dims(1 : ndim) = shape(arr)
    1507           0 :       do i = 1, ndim
    1508           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    1509             :       end do
    1510             :       ! define dim time
    1511           0 :       dims(ndim + 1) = 1
    1512           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim + 1)))
    1513             : 
    1514             :       ! define dim variables
    1515           0 :       do i = 1, ndim
    1516           0 :         if (inetcdf4) then
    1517           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1518             :         else
    1519           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1520             :         end if
    1521             :       end do
    1522             :       ! define time variable
    1523           0 :       if (inetcdf4) then
    1524           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
    1525             :       else
    1526           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
    1527             :       end if
    1528             : 
    1529             :       ! define variable
    1530           0 :       if (inetcdf4) then
    1531           0 :         chunksizes(1 : ndim) = dims(1 : ndim)
    1532           0 :         chunksizes(ndim + 1) = 1
    1533             :         call check(nf90_def_var(ncid, 'var', NF90_DOUBLE, dimid, varid(ndim + 2), &
    1534           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    1535             :       else
    1536           0 :         call check(nf90_def_var(ncid, 'var', NF90_DOUBLE, dimid, varid(ndim + 2)))
    1537             :       end if
    1538             : 
    1539             :       ! end define mode
    1540           0 :       call check(nf90_enddef(ncid))
    1541             : 
    1542             :       ! write dimensions
    1543           0 :       do i = 1, ndim
    1544           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    1545             :       end do
    1546             : 
    1547             :       ! write time and variable
    1548           0 :       start(:) = 1
    1549           0 :       counter(:) = dims
    1550           0 :       counter(ndim + 1) = 1
    1551           0 :       do i = 1, 1
    1552           0 :         start(ndim + 1) = i
    1553           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/i/), (/i/)))
    1554           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
    1555             :       end do
    1556             :     end if
    1557             : 
    1558             :     ! close netcdf file
    1559           0 :     call check(nf90_close(ncid))
    1560             : 
    1561           0 :   end subroutine dump_netcdf_2d_dp
    1562             : 
    1563             : 
    1564          20 :   subroutine dump_netcdf_3d_dp(filename, arr, append, lfs, netcdf4, deflate_level)
    1565             : 
    1566             :     implicit none
    1567             : 
    1568             :     character(len = *), intent(in) :: filename ! netcdf file name
    1569             :     real(dp), dimension(:, :, :), intent(in) :: arr      ! input array
    1570             :     logical, optional, intent(in) :: append   ! append to existing file
    1571             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
    1572             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
    1573             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
    1574             : 
    1575             :     integer(i4), parameter :: ndim = 3 ! Routine for ndim dimensional array
    1576             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
    1577             :     integer(i4), dimension(ndim) :: dims     ! Size of each dimension
    1578             :     integer(i4), dimension(ndim) :: dimid    ! netcdf IDs of each dimension
    1579             :     integer(i4), dimension(ndim + 1) :: varid    ! dimension variables and var id
    1580             :     integer(i4), dimension(ndim) :: start    ! start array for write of each time step
    1581             :     integer(i4), dimension(ndim) :: counter  ! length array for write of each time step
    1582             :     integer(i4), dimension(ndim) :: chunksizes ! Size of chunks in netcdf4 writing
    1583             :     integer(i4) :: ncid                             ! netcdf file id
    1584             :     integer(i4) :: i, j
    1585             :     logical :: iappend
    1586             :     integer(i4) :: idim    ! read dimension on append
    1587             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
    1588             :     logical :: LargeFile
    1589             :     logical :: inetcdf4
    1590             :     integer(i4) :: deflate
    1591             :     integer(i4) :: buffersize
    1592             : 
    1593             :     ! append or not
    1594          20 :     if (present(append)) then
    1595          10 :       if (append) then
    1596             :         iappend = .true.
    1597             :       else
    1598           0 :         iappend = .false.
    1599             :       end if
    1600             :     else
    1601             :       iappend = .false.
    1602             :     end if
    1603          20 :     LargeFile = .false.
    1604          20 :     if (present(lfs)) LargeFile = lfs
    1605          20 :     inetcdf4 = .false.
    1606          20 :     if (present(netcdf4)) inetcdf4 = netcdf4
    1607          20 :     deflate = 1
    1608          20 :     if (present(deflate_level)) deflate = deflate_level
    1609             : 
    1610             :     ! dimension names
    1611         100 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    1612             : 
    1613          20 :     if (iappend) then
    1614             :       ! open file
    1615          10 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    1616             : 
    1617             :       ! inquire variables time and var
    1618          10 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim)))
    1619          10 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 1)))
    1620          10 :       call check(nf90_inquire_variable(ncid, varid(ndim + 1), ndims = idim, dimids = dimid))
    1621          10 :       if (idim /= ndim) stop "dump_netcdf_3d_dp: number of variable dimensions /= number of file variable dimensions."
    1622             : 
    1623             :       ! inquire dimensions
    1624          40 :       do i = 1, ndim
    1625          30 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    1626          40 :         if (i < ndim) then
    1627          20 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_3d_dp: dimension name problem."
    1628          20 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_3d_dp: variable dimension /= file variable dimension."
    1629             :         else
    1630          10 :           if (trim(name) /= 'time') stop "dump_netcdf_3d_dp: time name problem."
    1631             :         end if
    1632             :       enddo
    1633             : 
    1634             :       ! append
    1635          40 :       start(:) = 1
    1636          10 :       counter(:) = dims
    1637          10 :       counter(ndim) = 1
    1638          20 :       do i = 1, size(arr, ndim)
    1639          10 :         start(ndim) = dims(ndim) + i
    1640          30 :         call check(nf90_put_var(ncid, varid(ndim), (/dims(ndim) + i/), (/dims(ndim) + i/)))
    1641          20 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, i), start, counter))
    1642             :       end do
    1643             :     else
    1644             :       ! open file
    1645          10 :       if (inetcdf4) then
    1646           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    1647             :         ! call check(nf90_set_fill(ncid, NF90_NOFILL, old_fill_mode))
    1648             :       else
    1649          10 :         if (LargeFile) then
    1650           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    1651             :         else
    1652          10 :           call check(nf90_create(trim(Filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    1653             :         end if
    1654             :       end if
    1655             : 
    1656             :       ! define dims
    1657          40 :       dims = shape(arr)
    1658          30 :       do i = 1, ndim - 1
    1659          30 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    1660             :       end do
    1661             :       ! define dim time
    1662          10 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim)))
    1663             : 
    1664             :       ! define dim variables
    1665          30 :       do i = 1, ndim - 1
    1666          30 :         if (inetcdf4) then
    1667           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1668             :         else
    1669          20 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1670             :         end if
    1671             :       end do
    1672             :       ! define time variable
    1673          10 :       if (inetcdf4) then
    1674           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    1675             :       else
    1676          10 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    1677             :       end if
    1678             : 
    1679             :       ! define variable
    1680          10 :       if (inetcdf4) then
    1681           0 :         chunksizes(1 : ndim - 1) = dims(1 : ndim - 1)
    1682           0 :         chunksizes(ndim) = 1
    1683             :         call check(nf90_def_var(ncid, 'var', NF90_DOUBLE, dimid, varid(ndim + 1), &
    1684           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    1685             :       else
    1686          10 :         call check(nf90_def_var(ncid, 'var', NF90_DOUBLE, dimid, varid(ndim + 1)))
    1687             :       end if
    1688             : 
    1689             :       ! end define mode
    1690          10 :       call check(nf90_enddef(ncid))
    1691             : 
    1692             :       ! write dimensions
    1693          30 :       do i = 1, ndim - 1
    1694       60090 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    1695             :       end do
    1696             : 
    1697             :       ! write time and variable
    1698          40 :       start(:) = 1
    1699          10 :       counter(:) = dims
    1700          10 :       counter(ndim) = 1
    1701          20 :       do i = 1, dims(ndim)
    1702          10 :         start(ndim) = i
    1703          30 :         call check(nf90_put_var(ncid, varid(ndim), (/i/), (/i/)))
    1704          20 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, i), start, counter))
    1705             :       end do
    1706             :     end if
    1707             : 
    1708             :     ! close netcdf file
    1709          20 :     call check(nf90_close(ncid))
    1710             : 
    1711           0 :   end subroutine dump_netcdf_3d_dp
    1712             : 
    1713             : 
    1714           0 :   subroutine dump_netcdf_4d_dp(filename, arr, append, lfs, netcdf4, deflate_level)
    1715             : 
    1716             :     implicit none
    1717             : 
    1718             :     character(len = *), intent(in) :: filename ! netcdf file name
    1719             :     real(dp), dimension(:, :, :, :), intent(in) :: arr      ! input array
    1720             :     logical, optional, intent(in) :: append   ! append to existing file
    1721             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
    1722             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
    1723             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
    1724             : 
    1725             :     integer(i4), parameter :: ndim = 4 ! Routine for ndim dimensional array
    1726             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
    1727             :     integer(i4), dimension(ndim) :: dims     ! Size of each dimension
    1728             :     integer(i4), dimension(ndim) :: dimid    ! netcdf IDs of each dimension
    1729             :     integer(i4), dimension(ndim + 1) :: varid    ! dimension variables and var id
    1730             :     integer(i4), dimension(ndim) :: start    ! start array for write of each time step
    1731             :     integer(i4), dimension(ndim) :: counter  ! length array for write of each time step
    1732             :     integer(i4), dimension(ndim) :: chunksizes ! Size of chunks in netcdf4 writing
    1733             :     integer(i4) :: ncid                             ! netcdf file id
    1734             :     integer(i4) :: i, j
    1735             :     logical :: iappend
    1736             :     integer(i4) :: idim    ! read dimension on append
    1737             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
    1738             :     logical :: LargeFile
    1739             :     logical :: inetcdf4
    1740             :     integer(i4) :: deflate
    1741             :     integer(i4) :: buffersize
    1742             : 
    1743             :     ! append or not
    1744           0 :     if (present(append)) then
    1745           0 :       if (append) then
    1746             :         iappend = .true.
    1747             :       else
    1748           0 :         iappend = .false.
    1749             :       end if
    1750             :     else
    1751             :       iappend = .false.
    1752             :     end if
    1753           0 :     LargeFile = .false.
    1754           0 :     if (present(lfs)) LargeFile = lfs
    1755           0 :     inetcdf4 = .false.
    1756           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
    1757           0 :     deflate = 1
    1758           0 :     if (present(deflate_level)) deflate = deflate_level
    1759             : 
    1760             :     ! dimension names
    1761           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    1762             : 
    1763           0 :     if (iappend) then
    1764             :       ! open file
    1765           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    1766             : 
    1767             :       ! inquire variables time and var
    1768           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim)))
    1769           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 1)))
    1770           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 1), ndims = idim, dimids = dimid))
    1771           0 :       if (idim /= ndim) stop "dump_netcdf_4d_dp: number of variable dimensions /= number of file variable dimensions."
    1772             : 
    1773             :       ! inquire dimensions
    1774           0 :       do i = 1, ndim
    1775           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    1776           0 :         if (i < ndim) then
    1777           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_4d_dp: dimension name problem."
    1778           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_4d_dp: variable dimension /= file variable dimension."
    1779             :         else
    1780           0 :           if (trim(name) /= 'time') stop "dump_netcdf_4d_dp: time name problem."
    1781             :         end if
    1782             :       enddo
    1783             : 
    1784             :       ! append
    1785           0 :       start(:) = 1
    1786           0 :       counter(:) = dims
    1787           0 :       counter(ndim) = 1
    1788           0 :       do i = 1, size(arr, ndim)
    1789           0 :         start(ndim) = dims(ndim) + i
    1790           0 :         call check(nf90_put_var(ncid, varid(ndim), (/dims(ndim) + i/), (/dims(ndim) + i/)))
    1791           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, i), start, counter))
    1792             :       end do
    1793             :     else
    1794             :       ! open file
    1795           0 :       if (inetcdf4) then
    1796           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    1797             :       else
    1798           0 :         if (LargeFile) then
    1799           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    1800             :         else
    1801           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    1802             :         end if
    1803             :       end if
    1804             : 
    1805             :       ! define dims
    1806           0 :       dims = shape(arr)
    1807           0 :       do i = 1, ndim - 1
    1808           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    1809             :       end do
    1810             :       ! define dim time
    1811           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim)))
    1812             : 
    1813             :       ! define dim variables
    1814           0 :       do i = 1, ndim - 1
    1815           0 :         if (inetcdf4) then
    1816           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1817             :         else
    1818           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1819             :         end if
    1820             :       end do
    1821             :       ! define time variable
    1822           0 :       if (inetcdf4) then
    1823           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    1824             :       else
    1825           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    1826             :       end if
    1827             : 
    1828             :       ! define variable
    1829           0 :       if (inetcdf4) then
    1830           0 :         chunksizes(1 : ndim - 1) = dims(1 : ndim - 1)
    1831           0 :         chunksizes(ndim) = 1
    1832             :         call check(nf90_def_var(ncid, 'var', NF90_DOUBLE, dimid, varid(ndim + 1), &
    1833           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    1834             :       else
    1835           0 :         call check(nf90_def_var(ncid, 'var', NF90_DOUBLE, dimid, varid(ndim + 1)))
    1836             :       end if
    1837             : 
    1838             :       ! end define mode
    1839           0 :       call check(nf90_enddef(ncid))
    1840             : 
    1841             :       ! write dimensions
    1842           0 :       do i = 1, ndim - 1
    1843           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    1844             :       end do
    1845             : 
    1846             :       ! write time and variable
    1847           0 :       start(:) = 1
    1848           0 :       counter(:) = dims
    1849           0 :       counter(ndim) = 1
    1850           0 :       do i = 1, dims(ndim)
    1851           0 :         start(ndim) = i
    1852           0 :         call check(nf90_put_var(ncid, varid(ndim), (/i/), (/i/)))
    1853           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, i), start, counter))
    1854             :       end do
    1855             :     end if
    1856             : 
    1857             :     ! close netcdf file
    1858           0 :     call check(nf90_close(ncid))
    1859             : 
    1860          20 :   end subroutine dump_netcdf_4d_dp
    1861             : 
    1862             : 
    1863           0 :   subroutine dump_netcdf_5d_dp(filename, arr, append, lfs, netcdf4, deflate_level)
    1864             : 
    1865             :     implicit none
    1866             : 
    1867             :     character(len = *), intent(in) :: filename ! netcdf file name
    1868             :     real(dp), dimension(:, :, :, :, :), intent(in) :: arr      ! input array
    1869             :     logical, optional, intent(in) :: append   ! append to existing file
    1870             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
    1871             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
    1872             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
    1873             : 
    1874             :     integer(i4), parameter :: ndim = 5 ! Routine for ndim dimensional array
    1875             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
    1876             :     integer(i4), dimension(ndim) :: dims     ! Size of each dimension
    1877             :     integer(i4), dimension(ndim) :: dimid    ! netcdf IDs of each dimension
    1878             :     integer(i4), dimension(ndim + 1) :: varid    ! dimension variables and var id
    1879             :     integer(i4), dimension(ndim) :: start    ! start array for write of each time step
    1880             :     integer(i4), dimension(ndim) :: counter  ! length array for write of each time step
    1881             :     integer(i4), dimension(ndim) :: chunksizes ! Size of chunks in netcdf4 writing
    1882             :     integer(i4) :: ncid                             ! netcdf file id
    1883             :     integer(i4) :: i, j
    1884             :     logical :: iappend
    1885             :     integer(i4) :: idim    ! read dimension on append
    1886             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
    1887             :     logical :: LargeFile
    1888             :     logical :: inetcdf4
    1889             :     integer(i4) :: deflate
    1890             :     integer(i4) :: buffersize
    1891             : 
    1892             :     ! append or not
    1893           0 :     if (present(append)) then
    1894           0 :       if (append) then
    1895             :         iappend = .true.
    1896             :       else
    1897           0 :         iappend = .false.
    1898             :       end if
    1899             :     else
    1900             :       iappend = .false.
    1901             :     end if
    1902           0 :     LargeFile = .false.
    1903           0 :     if (present(lfs)) LargeFile = lfs
    1904           0 :     inetcdf4 = .false.
    1905           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
    1906           0 :     deflate = 1
    1907           0 :     if (present(deflate_level)) deflate = deflate_level
    1908             : 
    1909             :     ! dimension names
    1910           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    1911             : 
    1912           0 :     if (iappend) then
    1913             :       ! open file
    1914           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    1915             : 
    1916             :       ! inquire variables time and var
    1917           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim)))
    1918           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 1)))
    1919           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 1), ndims = idim, dimids = dimid))
    1920           0 :       if (idim /= ndim) stop "dump_netcdf_5d_dp: number of variable dimensions /= number of file variable dimensions."
    1921             : 
    1922             :       ! inquire dimensions
    1923           0 :       do i = 1, ndim
    1924           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    1925           0 :         if (i < ndim) then
    1926           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_5d_dp: dimension name problem."
    1927           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_5d_dp: variable dimension /= file variable dimension."
    1928             :         else
    1929           0 :           if (trim(name) /= 'time') stop "dump_netcdf_5d_dp: time name problem."
    1930             :         end if
    1931             :       enddo
    1932             : 
    1933             :       ! append
    1934           0 :       start(:) = 1
    1935           0 :       counter(:) = dims
    1936           0 :       counter(ndim) = 1
    1937           0 :       do i = 1, size(arr, ndim)
    1938           0 :         start(ndim) = dims(ndim) + i
    1939           0 :         call check(nf90_put_var(ncid, varid(ndim), (/dims(ndim) + i/), (/dims(ndim) + i/)))
    1940           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, :, i), start, counter))
    1941             :       end do
    1942             :     else
    1943             :       ! open file
    1944           0 :       if (inetcdf4) then
    1945           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    1946             :       else
    1947           0 :         if (LargeFile) then
    1948           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    1949             :         else
    1950           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    1951             :         end if
    1952             :       end if
    1953             : 
    1954             :       ! define dims
    1955           0 :       dims = shape(arr)
    1956           0 :       do i = 1, ndim - 1
    1957           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    1958             :       end do
    1959             :       ! define dim time
    1960           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim)))
    1961             : 
    1962             :       ! define dim variables
    1963           0 :       do i = 1, ndim - 1
    1964           0 :         if (inetcdf4) then
    1965           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1966             :         else
    1967           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    1968             :         end if
    1969             :       end do
    1970             :       ! define time variable
    1971           0 :       if (inetcdf4) then
    1972           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    1973             :       else
    1974           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    1975             :       end if
    1976             : 
    1977             :       ! define variable
    1978           0 :       if (inetcdf4) then
    1979           0 :         chunksizes(1 : ndim - 1) = dims(1 : ndim - 1)
    1980           0 :         chunksizes(ndim) = 1
    1981             :         call check(nf90_def_var(ncid, 'var', NF90_DOUBLE, dimid, varid(ndim + 1), &
    1982           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    1983             :       else
    1984           0 :         call check(nf90_def_var(ncid, 'var', NF90_DOUBLE, dimid, varid(ndim + 1)))
    1985             :       end if
    1986             : 
    1987             :       ! end define mode
    1988           0 :       call check(nf90_enddef(ncid))
    1989             : 
    1990             :       ! write dimensions
    1991           0 :       do i = 1, ndim - 1
    1992           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    1993             :       end do
    1994             : 
    1995             :       ! write time and variable
    1996           0 :       start(:) = 1
    1997           0 :       counter(:) = dims
    1998           0 :       counter(ndim) = 1
    1999           0 :       do i = 1, dims(ndim)
    2000           0 :         start(ndim) = i
    2001           0 :         call check(nf90_put_var(ncid, varid(ndim), (/i/), (/i/)))
    2002           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, :, i), start, counter))
    2003             :       end do
    2004             :     end if
    2005             : 
    2006             :     ! close netcdf file
    2007           0 :     call check(nf90_close(ncid))
    2008             : 
    2009           0 :   end subroutine dump_netcdf_5d_dp
    2010             : 
    2011             : 
    2012           0 :   subroutine dump_netcdf_1d_i4(filename, arr, append, lfs, netcdf4, deflate_level)
    2013             : 
    2014             :     implicit none
    2015             : 
    2016             :     character(len = *), intent(in) :: filename ! netcdf file name
    2017             :     integer(i4), dimension(:), intent(in) :: arr      ! input array
    2018             :     logical, optional, intent(in) :: append   ! append to existing file
    2019             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
    2020             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
    2021             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
    2022             : 
    2023             :     integer(i4), parameter :: ndim = 1 ! Routine for ndim dimensional array
    2024             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
    2025             :     integer(i4), dimension(ndim + 1) :: dims     ! Size of each dimension
    2026             :     integer(i4), dimension(ndim + 1) :: dimid    ! netcdf IDs of each dimension
    2027             :     integer(i4), dimension(ndim + 2) :: varid    ! dimension variables and var id
    2028             :     integer(i4), dimension(ndim + 1) :: start    ! start array for write of each time step
    2029             :     integer(i4), dimension(ndim + 1) :: counter  ! length array for write of each time step
    2030             :     integer(i4), dimension(ndim + 1) :: chunksizes ! Size of chunks in netcdf4 writing
    2031             :     integer(i4) :: ncid                             ! netcdf file id
    2032             :     integer(i4) :: i, j
    2033             :     logical :: iappend
    2034             :     integer(i4) :: idim    ! read dimension on append
    2035             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
    2036             :     logical :: LargeFile
    2037             :     logical :: inetcdf4
    2038             :     integer(i4) :: deflate
    2039             :     integer(i4) :: buffersize
    2040             : 
    2041             :     ! append or not
    2042           0 :     if (present(append)) then
    2043           0 :       if (append) then
    2044             :         iappend = .true.
    2045             :       else
    2046           0 :         iappend = .false.
    2047             :       end if
    2048             :     else
    2049             :       iappend = .false.
    2050             :     end if
    2051           0 :     LargeFile = .false.
    2052           0 :     if (present(lfs)) LargeFile = lfs
    2053           0 :     inetcdf4 = .false.
    2054           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
    2055           0 :     deflate = 1
    2056           0 :     if (present(deflate_level)) deflate = deflate_level
    2057             : 
    2058             :     ! dimension names
    2059           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    2060             : 
    2061           0 :     if (iappend) then
    2062             :       ! open file
    2063           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    2064             : 
    2065             :       ! inquire variables time and var
    2066           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim + 1)))
    2067           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 2)))
    2068           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 2), ndims = idim, dimids = dimid))
    2069           0 :       if (idim /= ndim + 1) stop "dump_netcdf_1d_i4: number of variable dimensions /= number of file variable dimensions."
    2070             : 
    2071             :       ! inquire dimensions
    2072           0 :       do i = 1, ndim + 1
    2073           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    2074           0 :         if (i < ndim + 1) then
    2075           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_1d_i4: dimension name problem."
    2076           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_1d_i4: variable dimension /= file variable dimension."
    2077             :         else
    2078           0 :           if (trim(name) /= 'time') stop "dump_netcdf_1d_i4: time name problem."
    2079             :         end if
    2080             :       enddo
    2081             : 
    2082             :       ! append
    2083           0 :       start(:) = 1
    2084           0 :       counter(:) = dims
    2085           0 :       counter(ndim + 1) = 1
    2086           0 :       do i = 1, 1
    2087           0 :         start(ndim + 1) = dims(ndim + 1) + i
    2088           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/dims(ndim + 1) + i/), (/dims(ndim + 1) + i/)))
    2089           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
    2090             :       end do
    2091             :     else
    2092             :       ! open file
    2093           0 :       if (inetcdf4) then
    2094           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    2095             :       else
    2096           0 :         if (LargeFile) then
    2097           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    2098             :         else
    2099           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    2100             :         end if
    2101             :       end if
    2102             : 
    2103             :       ! define dims
    2104           0 :       dims(1 : ndim) = shape(arr)
    2105           0 :       do i = 1, ndim
    2106           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    2107             :       end do
    2108             :       ! define dim time
    2109           0 :       dims(ndim + 1) = 1
    2110           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim + 1)))
    2111             : 
    2112             :       ! define dim variables
    2113           0 :       do i = 1, ndim
    2114           0 :         if (inetcdf4) then
    2115           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    2116             :         else
    2117           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    2118             :         end if
    2119             :       end do
    2120             :       ! define time variable
    2121           0 :       if (inetcdf4) then
    2122           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
    2123             :       else
    2124           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
    2125             :       end if
    2126             : 
    2127             :       ! define variable
    2128           0 :       if (inetcdf4) then
    2129           0 :         chunksizes(1 : ndim) = dims(1 : ndim)
    2130           0 :         chunksizes(ndim + 1) = 1
    2131             :         call check(nf90_def_var(ncid, 'var', NF90_INT, dimid, varid(ndim + 2), &
    2132           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    2133             :       else
    2134           0 :         call check(nf90_def_var(ncid, 'var', NF90_INT, dimid, varid(ndim + 2)))
    2135             :       end if
    2136             : 
    2137             :       ! end define mode
    2138           0 :       call check(nf90_enddef(ncid))
    2139             : 
    2140             :       ! write dimensions
    2141           0 :       do i = 1, ndim
    2142           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    2143             :       end do
    2144             : 
    2145             :       ! write time and variable
    2146           0 :       start(:) = 1
    2147           0 :       counter(:) = dims
    2148           0 :       counter(ndim + 1) = 1
    2149           0 :       do i = 1, 1
    2150           0 :         start(ndim + 1) = i
    2151           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/i/), (/i/)))
    2152           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
    2153             :       end do
    2154             :     end if
    2155             : 
    2156             :     ! close netcdf file
    2157           0 :     call check(nf90_close(ncid))
    2158             : 
    2159           0 :   end subroutine dump_netcdf_1d_i4
    2160             : 
    2161             : 
    2162           0 :   subroutine dump_netcdf_2d_i4(filename, arr, append, lfs, netcdf4, deflate_level)
    2163             : 
    2164             :     implicit none
    2165             : 
    2166             :     character(len = *), intent(in) :: filename ! netcdf file name
    2167             :     integer(i4), dimension(:, :), intent(in) :: arr      ! input array
    2168             :     logical, optional, intent(in) :: append   ! append to existing file
    2169             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
    2170             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
    2171             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
    2172             : 
    2173             :     integer(i4), parameter :: ndim = 2 ! Routine for ndim dimensional array
    2174             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
    2175             :     integer(i4), dimension(ndim + 1) :: dims     ! Size of each dimension
    2176             :     integer(i4), dimension(ndim + 1) :: dimid    ! netcdf IDs of each dimension
    2177             :     integer(i4), dimension(ndim + 2) :: varid    ! dimension variables and var id
    2178             :     integer(i4), dimension(ndim + 1) :: start    ! start array for write of each time step
    2179             :     integer(i4), dimension(ndim + 1) :: counter  ! length array for write of each time step
    2180             :     integer(i4), dimension(ndim + 1) :: chunksizes ! Size of chunks in netcdf4 writing
    2181             :     integer(i4) :: ncid                             ! netcdf file id
    2182             :     integer(i4) :: i, j
    2183             :     logical :: iappend
    2184             :     integer(i4) :: idim    ! read dimension on append
    2185             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
    2186             :     logical :: LargeFile
    2187             :     logical :: inetcdf4
    2188             :     integer(i4) :: deflate
    2189             :     integer(i4) :: buffersize
    2190             : 
    2191             :     ! append or not
    2192           0 :     if (present(append)) then
    2193           0 :       if (append) then
    2194             :         iappend = .true.
    2195             :       else
    2196           0 :         iappend = .false.
    2197             :       end if
    2198             :     else
    2199             :       iappend = .false.
    2200             :     end if
    2201           0 :     LargeFile = .false.
    2202           0 :     if (present(lfs)) LargeFile = lfs
    2203           0 :     inetcdf4 = .false.
    2204           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
    2205           0 :     deflate = 1
    2206           0 :     if (present(deflate_level)) deflate = deflate_level
    2207             : 
    2208             :     ! dimension names
    2209           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    2210             : 
    2211           0 :     if (iappend) then
    2212             :       ! open file
    2213           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    2214             : 
    2215             :       ! inquire variables time and var
    2216           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim + 1)))
    2217           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 2)))
    2218           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 2), ndims = idim, dimids = dimid))
    2219           0 :       if (idim /= ndim + 1) stop "dump_netcdf_2d_i4: number of variable dimensions /= number of file variable dimensions."
    2220             : 
    2221             :       ! inquire dimensions
    2222           0 :       do i = 1, ndim + 1
    2223           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    2224           0 :         if (i < ndim + 1) then
    2225           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_2d_i4: dimension name problem."
    2226           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_2d_i4: variable dimension /= file variable dimension."
    2227             :         else
    2228           0 :           if (trim(name) /= 'time') stop "dump_netcdf_2d_i4: time name problem."
    2229             :         end if
    2230             :       enddo
    2231             : 
    2232             :       ! append
    2233           0 :       start(:) = 1
    2234           0 :       counter(:) = dims
    2235           0 :       counter(ndim + 1) = 1
    2236           0 :       do i = 1, 1
    2237           0 :         start(ndim + 1) = dims(ndim + 1) + i
    2238           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/dims(ndim + 1) + i/), (/dims(ndim + 1) + i/)))
    2239           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
    2240             :       end do
    2241             :     else
    2242             :       ! open file
    2243           0 :       if (inetcdf4) then
    2244           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    2245             :       else
    2246           0 :         if (LargeFile) then
    2247           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    2248             :         else
    2249           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    2250             :         end if
    2251             :       end if
    2252             : 
    2253             :       ! define dims
    2254           0 :       dims(1 : ndim) = shape(arr)
    2255           0 :       do i = 1, ndim
    2256           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    2257             :       end do
    2258             :       ! define dim time
    2259           0 :       dims(ndim + 1) = 1
    2260           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim + 1)))
    2261             : 
    2262             :       ! define dim variables
    2263           0 :       do i = 1, ndim
    2264           0 :         if (inetcdf4) then
    2265           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    2266             :         else
    2267           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    2268             :         end if
    2269             :       end do
    2270             :       ! define time variable
    2271           0 :       if (inetcdf4) then
    2272           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
    2273             :       else
    2274           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim + 1), varid(ndim + 1)))
    2275             :       end if
    2276             : 
    2277             :       ! define variable
    2278           0 :       if (inetcdf4) then
    2279           0 :         chunksizes(1 : ndim) = dims(1 : ndim)
    2280           0 :         chunksizes(ndim + 1) = 1
    2281             :         call check(nf90_def_var(ncid, 'var', NF90_INT, dimid, varid(ndim + 2), &
    2282           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    2283             :       else
    2284           0 :         call check(nf90_def_var(ncid, 'var', NF90_INT, dimid, varid(ndim + 2)))
    2285             :       end if
    2286             : 
    2287             :       ! end define mode
    2288           0 :       call check(nf90_enddef(ncid))
    2289             : 
    2290             :       ! write dimensions
    2291           0 :       do i = 1, ndim
    2292           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    2293             :       end do
    2294             : 
    2295             :       ! write time and variable
    2296           0 :       start(:) = 1
    2297           0 :       counter(:) = dims
    2298           0 :       counter(ndim + 1) = 1
    2299           0 :       do i = 1, 1
    2300           0 :         start(ndim + 1) = i
    2301           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), (/i/), (/i/)))
    2302           0 :         call check(nf90_put_var(ncid, varid(ndim + 2), arr, start, counter))
    2303             :       end do
    2304             :     end if
    2305             : 
    2306             :     ! close netcdf file
    2307           0 :     call check(nf90_close(ncid))
    2308             : 
    2309           0 :   end subroutine dump_netcdf_2d_i4
    2310             : 
    2311             : 
    2312           0 :   subroutine dump_netcdf_3d_i4(filename, arr, append, lfs, netcdf4, deflate_level)
    2313             : 
    2314             :     implicit none
    2315             : 
    2316             :     character(len = *), intent(in) :: filename ! netcdf file name
    2317             :     integer(i4), dimension(:, :, :), intent(in) :: arr      ! input array
    2318             :     logical, optional, intent(in) :: append   ! append to existing file
    2319             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
    2320             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
    2321             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
    2322             : 
    2323             :     integer(i4), parameter :: ndim = 3 ! Routine for ndim dimensional array
    2324             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
    2325             :     integer(i4), dimension(ndim) :: dims     ! Size of each dimension
    2326             :     integer(i4), dimension(ndim) :: dimid    ! netcdf IDs of each dimension
    2327             :     integer(i4), dimension(ndim + 1) :: varid    ! dimension variables and var id
    2328             :     integer(i4), dimension(ndim) :: start    ! start array for write of each time step
    2329             :     integer(i4), dimension(ndim) :: counter  ! length array for write of each time step
    2330             :     integer(i4), dimension(ndim) :: chunksizes ! Size of chunks in netcdf4 writing
    2331             :     integer(i4) :: ncid                             ! netcdf file id
    2332             :     integer(i4) :: i, j
    2333             :     logical :: iappend
    2334             :     integer(i4) :: idim    ! read dimension on append
    2335             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
    2336             :     logical :: LargeFile
    2337             :     logical :: inetcdf4
    2338             :     integer(i4) :: deflate
    2339             :     integer(i4) :: buffersize
    2340             : 
    2341             :     ! append or not
    2342           0 :     if (present(append)) then
    2343           0 :       if (append) then
    2344             :         iappend = .true.
    2345             :       else
    2346           0 :         iappend = .false.
    2347             :       end if
    2348             :     else
    2349             :       iappend = .false.
    2350             :     end if
    2351           0 :     LargeFile = .false.
    2352           0 :     if (present(lfs)) LargeFile = lfs
    2353           0 :     inetcdf4 = .false.
    2354           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
    2355           0 :     deflate = 1
    2356           0 :     if (present(deflate_level)) deflate = deflate_level
    2357             : 
    2358             :     ! dimension names
    2359           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    2360             : 
    2361           0 :     if (iappend) then
    2362             :       ! open file
    2363           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    2364             : 
    2365             :       ! inquire variables time and var
    2366           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim)))
    2367           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 1)))
    2368           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 1), ndims = idim, dimids = dimid))
    2369           0 :       if (idim /= ndim) stop "dump_netcdf_3d_i4: number of variable dimensions /= number of file variable dimensions."
    2370             : 
    2371             :       ! inquire dimensions
    2372           0 :       do i = 1, ndim
    2373           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    2374           0 :         if (i < ndim) then
    2375           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_3d_i4: dimension name problem."
    2376           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_3d_i4: variable dimension /= file variable dimension."
    2377             :         else
    2378           0 :           if (trim(name) /= 'time') stop "dump_netcdf_3d_i4: time name problem."
    2379             :         end if
    2380             :       enddo
    2381             : 
    2382             :       ! append
    2383           0 :       start(:) = 1
    2384           0 :       counter(:) = dims
    2385           0 :       counter(ndim) = 1
    2386           0 :       do i = 1, size(arr, ndim)
    2387           0 :         start(ndim) = dims(ndim) + i
    2388           0 :         call check(nf90_put_var(ncid, varid(ndim), (/dims(ndim) + i/), (/dims(ndim) + i/)))
    2389           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, i), start, counter))
    2390             :       end do
    2391             :     else
    2392             :       ! open file
    2393           0 :       if (inetcdf4) then
    2394           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    2395             :       else
    2396           0 :         if (LargeFile) then
    2397           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    2398             :         else
    2399           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    2400             :         end if
    2401             :       end if
    2402             : 
    2403             :       ! define dims
    2404           0 :       dims = shape(arr)
    2405           0 :       do i = 1, ndim - 1
    2406           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    2407             :       end do
    2408             :       ! define dim time
    2409           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim)))
    2410             : 
    2411             :       ! define dim variables
    2412           0 :       do i = 1, ndim - 1
    2413           0 :         if (inetcdf4) then
    2414           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    2415             :         else
    2416           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    2417             :         end if
    2418             :       end do
    2419             :       ! define time variable
    2420           0 :       if (inetcdf4) then
    2421           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    2422             :       else
    2423           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    2424             :       end if
    2425             : 
    2426             :       ! define variable
    2427           0 :       if (inetcdf4) then
    2428           0 :         chunksizes(1 : ndim - 1) = dims(1 : ndim - 1)
    2429           0 :         chunksizes(ndim) = 1
    2430             :         call check(nf90_def_var(ncid, 'var', NF90_INT, dimid, varid(ndim + 1), &
    2431           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    2432             :       else
    2433           0 :         call check(nf90_def_var(ncid, 'var', NF90_INT, dimid, varid(ndim + 1)))
    2434             :       end if
    2435             : 
    2436             :       ! end define mode
    2437           0 :       call check(nf90_enddef(ncid))
    2438             : 
    2439             :       ! write dimensions
    2440           0 :       do i = 1, ndim - 1
    2441           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    2442             :       end do
    2443             : 
    2444             :       ! write time and variable
    2445           0 :       start(:) = 1
    2446           0 :       counter(:) = dims
    2447           0 :       counter(ndim) = 1
    2448           0 :       do i = 1, dims(ndim)
    2449           0 :         start(ndim) = i
    2450           0 :         call check(nf90_put_var(ncid, varid(ndim), (/i/), (/i/)))
    2451           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, i), start, counter))
    2452             :       end do
    2453             :     end if
    2454             : 
    2455             :     ! close netcdf file
    2456           0 :     call check(nf90_close(ncid))
    2457             : 
    2458           0 :   end subroutine dump_netcdf_3d_i4
    2459             : 
    2460             : 
    2461           0 :   subroutine dump_netcdf_4d_i4(filename, arr, append, lfs, netcdf4, deflate_level)
    2462             : 
    2463             :     implicit none
    2464             : 
    2465             :     character(len = *), intent(in) :: filename ! netcdf file name
    2466             :     integer(i4), dimension(:, :, :, :), intent(in) :: arr      ! input array
    2467             :     logical, optional, intent(in) :: append   ! append to existing file
    2468             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
    2469             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
    2470             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
    2471             : 
    2472             :     integer(i4), parameter :: ndim = 4 ! Routine for ndim dimensional array
    2473             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
    2474             :     integer(i4), dimension(ndim) :: dims     ! Size of each dimension
    2475             :     integer(i4), dimension(ndim) :: dimid    ! netcdf IDs of each dimension
    2476             :     integer(i4), dimension(ndim + 1) :: varid    ! dimension variables and var id
    2477             :     integer(i4), dimension(ndim) :: start    ! start array for write of each time step
    2478             :     integer(i4), dimension(ndim) :: counter  ! length array for write of each time step
    2479             :     integer(i4), dimension(ndim) :: chunksizes ! Size of chunks in netcdf4 writing
    2480             :     integer(i4) :: ncid                             ! netcdf file id
    2481             :     integer(i4) :: i, j
    2482             :     logical :: iappend
    2483             :     integer(i4) :: idim    ! read dimension on append
    2484             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
    2485             :     logical :: LargeFile
    2486             :     logical :: inetcdf4
    2487             :     integer(i4) :: deflate
    2488             :     integer(i4) :: buffersize
    2489             : 
    2490             :     ! append or not
    2491           0 :     if (present(append)) then
    2492           0 :       if (append) then
    2493             :         iappend = .true.
    2494             :       else
    2495           0 :         iappend = .false.
    2496             :       end if
    2497             :     else
    2498             :       iappend = .false.
    2499             :     end if
    2500           0 :     LargeFile = .false.
    2501           0 :     if (present(lfs)) LargeFile = lfs
    2502           0 :     inetcdf4 = .false.
    2503           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
    2504           0 :     deflate = 1
    2505           0 :     if (present(deflate_level)) deflate = deflate_level
    2506             : 
    2507             :     ! dimension names
    2508           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    2509             : 
    2510           0 :     if (iappend) then
    2511             :       ! open file
    2512           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    2513             : 
    2514             :       ! inquire variables time and var
    2515           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim)))
    2516           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 1)))
    2517           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 1), ndims = idim, dimids = dimid))
    2518           0 :       if (idim /= ndim) stop "dump_netcdf_4d_i4: number of variable dimensions /= number of file variable dimensions."
    2519             : 
    2520             :       ! inquire dimensions
    2521           0 :       do i = 1, ndim
    2522           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    2523           0 :         if (i < ndim) then
    2524           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_4d_i4: dimension name problem."
    2525           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_4d_i4: variable dimension /= file variable dimension."
    2526             :         else
    2527           0 :           if (trim(name) /= 'time') stop "dump_netcdf_4d_i4: time name problem."
    2528             :         end if
    2529             :       enddo
    2530             : 
    2531             :       ! append
    2532           0 :       start(:) = 1
    2533           0 :       counter(:) = dims
    2534           0 :       counter(ndim) = 1
    2535           0 :       do i = 1, size(arr, ndim)
    2536           0 :         start(ndim) = dims(ndim) + i
    2537           0 :         call check(nf90_put_var(ncid, varid(ndim), (/dims(ndim) + i/), (/dims(ndim) + i/)))
    2538           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, i), start, counter))
    2539             :       end do
    2540             :     else
    2541             :       ! open file
    2542           0 :       if (inetcdf4) then
    2543           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    2544             :       else
    2545           0 :         if (LargeFile) then
    2546           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    2547             :         else
    2548           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    2549             :         end if
    2550             :       end if
    2551             : 
    2552             :       ! define dims
    2553           0 :       dims = shape(arr)
    2554           0 :       do i = 1, ndim - 1
    2555           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    2556             :       end do
    2557             :       ! define dim time
    2558           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim)))
    2559             : 
    2560             :       ! define dim variables
    2561           0 :       do i = 1, ndim - 1
    2562           0 :         if (inetcdf4) then
    2563           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    2564             :         else
    2565           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    2566             :         end if
    2567             :       end do
    2568             :       ! define time variable
    2569           0 :       if (inetcdf4) then
    2570           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    2571             :       else
    2572           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    2573             :       end if
    2574             : 
    2575             :       ! define variable
    2576           0 :       if (inetcdf4) then
    2577           0 :         chunksizes(1 : ndim - 1) = dims(1 : ndim - 1)
    2578           0 :         chunksizes(ndim) = 1
    2579             :         call check(nf90_def_var(ncid, 'var', NF90_INT, dimid, varid(ndim + 1), &
    2580           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    2581             :       else
    2582           0 :         call check(nf90_def_var(ncid, 'var', NF90_INT, dimid, varid(ndim + 1)))
    2583             :       end if
    2584             : 
    2585             :       ! end define mode
    2586           0 :       call check(nf90_enddef(ncid))
    2587             : 
    2588             :       ! write dimensions
    2589           0 :       do i = 1, ndim - 1
    2590           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    2591             :       end do
    2592             : 
    2593             :       ! write time and variable
    2594           0 :       start(:) = 1
    2595           0 :       counter(:) = dims
    2596           0 :       counter(ndim) = 1
    2597           0 :       do i = 1, dims(ndim)
    2598           0 :         start(ndim) = i
    2599           0 :         call check(nf90_put_var(ncid, varid(ndim), (/i/), (/i/)))
    2600           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, i), start, counter))
    2601             :       end do
    2602             :     end if
    2603             : 
    2604             :     ! close netcdf file
    2605           0 :     call check(nf90_close(ncid))
    2606             : 
    2607           0 :   end subroutine dump_netcdf_4d_i4
    2608             : 
    2609             : 
    2610           0 :   subroutine dump_netcdf_5d_i4(filename, arr, append, lfs, netcdf4, deflate_level)
    2611             : 
    2612             :     implicit none
    2613             : 
    2614             :     character(len = *), intent(in) :: filename ! netcdf file name
    2615             :     integer(i4), dimension(:, :, :, :, :), intent(in) :: arr      ! input array
    2616             :     logical, optional, intent(in) :: append   ! append to existing file
    2617             :     logical, optional, intent(in) :: lfs           ! netcdf3 Large File Support
    2618             :     logical, optional, intent(in) :: netcdf4       ! netcdf4
    2619             :     integer(i4), optional, intent(in) :: deflate_level ! compression level in netcdf4
    2620             : 
    2621             :     integer(i4), parameter :: ndim = 5 ! Routine for ndim dimensional array
    2622             :     character(len = 1), dimension(4) :: dnames   ! Common dimension names
    2623             :     integer(i4), dimension(ndim) :: dims     ! Size of each dimension
    2624             :     integer(i4), dimension(ndim) :: dimid    ! netcdf IDs of each dimension
    2625             :     integer(i4), dimension(ndim + 1) :: varid    ! dimension variables and var id
    2626             :     integer(i4), dimension(ndim) :: start    ! start array for write of each time step
    2627             :     integer(i4), dimension(ndim) :: counter  ! length array for write of each time step
    2628             :     integer(i4), dimension(ndim) :: chunksizes ! Size of chunks in netcdf4 writing
    2629             :     integer(i4) :: ncid                             ! netcdf file id
    2630             :     integer(i4) :: i, j
    2631             :     logical :: iappend
    2632             :     integer(i4) :: idim    ! read dimension on append
    2633             :     character(NF90_MAX_NAME) :: name    ! name of dimensions from nf90_inquire_dimension
    2634             :     logical :: LargeFile
    2635             :     logical :: inetcdf4
    2636             :     integer(i4) :: deflate
    2637             :     integer(i4) :: buffersize
    2638             : 
    2639             :     ! append or not
    2640           0 :     if (present(append)) then
    2641           0 :       if (append) then
    2642             :         iappend = .true.
    2643             :       else
    2644           0 :         iappend = .false.
    2645             :       end if
    2646             :     else
    2647             :       iappend = .false.
    2648             :     end if
    2649           0 :     LargeFile = .false.
    2650           0 :     if (present(lfs)) LargeFile = lfs
    2651           0 :     inetcdf4 = .false.
    2652           0 :     if (present(netcdf4)) inetcdf4 = netcdf4
    2653           0 :     deflate = 1
    2654           0 :     if (present(deflate_level)) deflate = deflate_level
    2655             : 
    2656             :     ! dimension names
    2657           0 :     dnames(1 : 4) = (/ 'x', 'y', 'z', 'l' /)
    2658             : 
    2659           0 :     if (iappend) then
    2660             :       ! open file
    2661           0 :       call check(nf90_open(trim(filename), NF90_WRITE, ncid))
    2662             : 
    2663             :       ! inquire variables time and var
    2664           0 :       call check(nf90_inq_varid(ncid, 'time', varid(ndim)))
    2665           0 :       call check(nf90_inq_varid(ncid, 'var', varid(ndim + 1)))
    2666           0 :       call check(nf90_inquire_variable(ncid, varid(ndim + 1), ndims = idim, dimids = dimid))
    2667           0 :       if (idim /= ndim) stop "dump_netcdf_5d_i4: number of variable dimensions /= number of file variable dimensions."
    2668             : 
    2669             :       ! inquire dimensions
    2670           0 :       do i = 1, ndim
    2671           0 :         call check(nf90_inquire_dimension(ncid, dimid(i), name, dims(i)))
    2672           0 :         if (i < ndim) then
    2673           0 :           if (trim(name) /= dnames(i)) stop "dump_netcdf_5d_i4: dimension name problem."
    2674           0 :           if (dims(i) /= size(arr, i)) stop "dump_netcdf_5d_i4: variable dimension /= file variable dimension."
    2675             :         else
    2676           0 :           if (trim(name) /= 'time') stop "dump_netcdf_5d_i4: time name problem."
    2677             :         end if
    2678             :       enddo
    2679             : 
    2680             :       ! append
    2681           0 :       start(:) = 1
    2682           0 :       counter(:) = dims
    2683           0 :       counter(ndim) = 1
    2684           0 :       do i = 1, size(arr, ndim)
    2685           0 :         start(ndim) = dims(ndim) + i
    2686           0 :         call check(nf90_put_var(ncid, varid(ndim), (/dims(ndim) + i/), (/dims(ndim) + i/)))
    2687           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, :, i), start, counter))
    2688             :       end do
    2689             :     else
    2690             :       ! open file
    2691           0 :       if (inetcdf4) then
    2692           0 :         call check(nf90_create(trim(filename), NF90_NETCDF4, ncid))
    2693             :       else
    2694           0 :         if (LargeFile) then
    2695           0 :           call check(nf90_create(trim(filename), NF90_64BIT_OFFSET, ncid, chunksize = buffersize))
    2696             :         else
    2697           0 :           call check(nf90_create(trim(filename), NF90_CLOBBER, ncid, chunksize = buffersize))
    2698             :         end if
    2699             :       end if
    2700             : 
    2701             :       ! define dims
    2702           0 :       dims = shape(arr)
    2703           0 :       do i = 1, ndim - 1
    2704           0 :         call check(nf90_def_dim(ncid, dnames(i), dims(i), dimid(i)))
    2705             :       end do
    2706             :       ! define dim time
    2707           0 :       call check(nf90_def_dim(ncid, 'time', NF90_UNLIMITED, dimid(ndim)))
    2708             : 
    2709             :       ! define dim variables
    2710           0 :       do i = 1, ndim - 1
    2711           0 :         if (inetcdf4) then
    2712           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    2713             :         else
    2714           0 :           call check(nf90_def_var(ncid, dnames(i), NF90_INT, dimid(i), varid(i)))
    2715             :         end if
    2716             :       end do
    2717             :       ! define time variable
    2718           0 :       if (inetcdf4) then
    2719           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    2720             :       else
    2721           0 :         call check(nf90_def_var(ncid, 'time', NF90_INT, dimid(ndim), varid(ndim)))
    2722             :       end if
    2723             : 
    2724             :       ! define variable
    2725           0 :       if (inetcdf4) then
    2726           0 :         chunksizes(1 : ndim - 1) = dims(1 : ndim - 1)
    2727           0 :         chunksizes(ndim) = 1
    2728             :         call check(nf90_def_var(ncid, 'var', NF90_INT, dimid, varid(ndim + 1), &
    2729           0 :                 chunksizes = chunksizes, shuffle = .true., deflate_level = deflate))
    2730             :       else
    2731           0 :         call check(nf90_def_var(ncid, 'var', NF90_INT, dimid, varid(ndim + 1)))
    2732             :       end if
    2733             : 
    2734             :       ! end define mode
    2735           0 :       call check(nf90_enddef(ncid))
    2736             : 
    2737             :       ! write dimensions
    2738           0 :       do i = 1, ndim - 1
    2739           0 :         call check(nf90_put_var(ncid, varid(i), (/ (j, j = 1, dims(i)) /)))
    2740             :       end do
    2741             : 
    2742             :       ! write time and variable
    2743           0 :       start(:) = 1
    2744           0 :       counter(:) = dims
    2745           0 :       counter(ndim) = 1
    2746           0 :       do i = 1, dims(ndim)
    2747           0 :         start(ndim) = i
    2748           0 :         call check(nf90_put_var(ncid, varid(ndim), (/i/), (/i/)))
    2749           0 :         call check(nf90_put_var(ncid, varid(ndim + 1), arr(:, :, :, :, i), start, counter))
    2750             :       end do
    2751             :     end if
    2752             : 
    2753             :     ! close netcdf file
    2754           0 :     call check(nf90_close(ncid))
    2755             : 
    2756           0 :   end subroutine dump_netcdf_5d_i4
    2757             : 
    2758             : 
    2759             :   ! ------------------------------------------------------------------
    2760             : 
    2761             : 
    2762           0 :   subroutine var2nc_1d_i4(f_name, arr, dnames, v_name, dim_unlimited, &
    2763           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    2764             :     !
    2765             :     implicit none
    2766             :     !
    2767             :     integer(i4), parameter :: ndim_const = 1
    2768             :     integer(i4) :: ndim
    2769             :     ! input variables
    2770             :     character(len = *), intent(in) :: f_name
    2771             :     integer(i4), dimension(:), intent(in) :: arr
    2772             :     character(len = *), intent(in) :: v_name
    2773             :     character(len = *), dimension(:), intent(in) :: dnames
    2774             :     ! attributes
    2775             :     integer(i4), optional, intent(in) :: dim_unlimited
    2776             :     character(len = *), optional, intent(in) :: long_name
    2777             :     character(len = *), optional, intent(in) :: units
    2778             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    2779             :     integer(i4), optional, intent(in) :: missing_value
    2780             :     logical, optional, intent(in) :: create
    2781             :     integer(i4), optional, intent(inout) :: ncid
    2782             :     integer(i4), optional, intent(in) :: nrec
    2783             :     ! local variables
    2784             :     logical :: create_loc
    2785             :     character(256) :: dummy_name
    2786             :     integer(i4) :: deflate
    2787           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    2788           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    2789           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    2790             :     integer(i4) :: idim      ! read dimension on append
    2791             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    2792             :     integer(i4) :: u_dimid
    2793             :     integer(i4) :: u_len     ! length of unlimited dimension
    2794             :     integer(i4) :: f_handle
    2795           0 :     integer(i4), dimension(:), allocatable :: dims
    2796           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    2797           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    2798             :     integer(i4) :: i         ! loop indices
    2799           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    2800             :     integer(i4), dimension(1) :: dummy     ! dummy read
    2801             :     logical :: openfile  ! tmp logical
    2802             :     !
    2803           0 :     ndim = size(dnames, 1)
    2804             :     ! consistency checks
    2805           0 :     d_unlimit = 0_i4
    2806           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    2807           0 :     if ((size(dnames, 1) .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    2808           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    2809           0 :       stop '***ERROR see StdOut'
    2810             :     end if
    2811           0 :     if (size(dnames, 1) .gt. ndim_const + 1) then
    2812           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    2813           0 :       stop '***ERROR see StdOut'
    2814             :     end if
    2815           0 :     allocate(chunksizes(ndim))
    2816           0 :     allocate(start(ndim))
    2817           0 :     allocate(counter(ndim))
    2818           0 :     allocate(dims(ndim))
    2819           0 :     allocate(dimid(ndim))
    2820           0 :     allocate(varid(1 + ndim))
    2821           0 :     allocate(dummy_count(ndim))
    2822             :     ! initialize
    2823           0 :     deflate = 1
    2824           0 :     if (ndim .gt. ndim_const) then
    2825           0 :       chunksizes = (/ size(arr, 1), 1 /)
    2826           0 :       dims(1 : ndim - 1) = shape(arr)
    2827           0 :       dims(ndim) = 1
    2828             :     else
    2829           0 :       chunksizes = (/ size(arr, 1) /)
    2830           0 :       dims(1 : ndim_const) = shape(arr)
    2831             :     end if
    2832           0 :     start(:) = 1
    2833           0 :     counter(:) = dims
    2834           0 :     dummy = nf90_fill_int
    2835           0 :     dummy_count = 1
    2836             :     ! open the netcdf file
    2837           0 :     if (present(ncid)) then
    2838           0 :       if (ncid < 0_i4) then
    2839             :         openfile = .true.
    2840             :       else
    2841           0 :         openfile = .false.
    2842           0 :         f_handle = ncid
    2843             :       end if
    2844             :     else
    2845             :       openfile = .true.
    2846             :     end if
    2847             :     if (openfile) then
    2848           0 :       create_loc = .false.
    2849           0 :       if (present(create)) create_loc = create
    2850           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    2851             :     end if
    2852             :     ! check whether variable exists
    2853           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    2854             :       ! append
    2855           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    2856           0 :       if (idim .ne. ndim) stop "var2nc_1d_i4: number of variable dimensions /= number of file variable dimensions."
    2857             :       ! check unlimited dimension
    2858           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    2859           0 :       if (u_dimid .eq. -1) stop 'var2nc_1d_i4: cannot append, no unlimited dimension defined'
    2860             :       ! check for unlimited dimension
    2861           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_1d_i4: unlimited dimension not specified correctly'
    2862           0 :       if (present(nrec)) then
    2863           0 :         start(d_unlimit) = nrec
    2864             :       else
    2865             :         ! get length of unlimited dimension
    2866           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    2867             :         ! adapt start, that is find last written chunk
    2868           0 :         do i = u_len, 1, -1
    2869           0 :           if (dummy(1) /= nf90_fill_int) exit
    2870           0 :           start(d_unlimit) = i
    2871           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    2872             :         end do
    2873           0 :         start(d_unlimit) = start(d_unlimit) + 1
    2874             :       end if
    2875             :     else
    2876             :       ! define dimension
    2877           0 :       do i = 1, ndim
    2878             :         ! check whether dimension exists
    2879           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    2880             :           ! create dimension
    2881           0 :           if (i .eq. d_unlimit) then
    2882             :             ! define unlimited dimension
    2883           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    2884             :           else
    2885             :             ! define limited dimension
    2886           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    2887             :           end if
    2888             :         end if
    2889             :       end do
    2890             :       ! define variable
    2891             :       call check(nf90_def_var(f_handle, v_name, NF90_INT, dimid, varid(ndim + 1), &
    2892           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    2893             :       !
    2894           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    2895           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    2896           0 :       if (present(missing_value)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'missing_value', missing_value))
    2897           0 :       if (present(attributes)) then
    2898           0 :         do i = 1, size(attributes, dim = 1)
    2899           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    2900             :             ! write number
    2901           0 :             read(attributes(i, 2), '(I6)') dummy(1)
    2902             :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    2903           0 :                     trim(attributes(i, 1)), dummy(1)))
    2904             :           else
    2905             :             ! write string
    2906             :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    2907           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    2908             :           end if
    2909             :         end do
    2910             :       end if
    2911             :       ! end definition
    2912           0 :       call check(nf90_enddef(f_handle))
    2913             :     end if
    2914             :     ! inquire dimensions
    2915           0 :     do i = 1, ndim_const
    2916           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    2917           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    2918           0 :               stop "var2nc_1d_i4: dimension name problem."
    2919           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    2920           0 :               stop "var2nc_1d_i4: variable dimension /= file variable dimension."
    2921             :     enddo
    2922             :     ! write time and variable
    2923           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    2924             :     ! close netcdf_dataset
    2925           0 :     if (present(ncid)) then
    2926           0 :       if (ncid < 0_i4) ncid = f_handle
    2927             :     else
    2928           0 :       call close_netcdf(f_handle)
    2929             :     end if
    2930             :     !
    2931           0 :   end subroutine var2nc_1d_i4
    2932             : 
    2933           0 :   subroutine var2nc_1d_sp(f_name, arr, dnames, v_name, dim_unlimited, &
    2934           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    2935             :     !
    2936             :     implicit none
    2937             :     !
    2938             :     integer(i4), parameter :: ndim_const = 1
    2939             :     integer(i4) :: ndim
    2940             :     ! input variables
    2941             :     character(len = *), intent(in) :: f_name
    2942             :     real(sp), dimension(:), intent(in) :: arr
    2943             :     character(len = *), dimension(:), intent(in) :: dnames
    2944             :     character(len = *), intent(in) :: v_name
    2945             :     ! attributes
    2946             :     integer(i4), optional, intent(in) :: dim_unlimited
    2947             :     character(len = *), optional, intent(in) :: long_name
    2948             :     character(len = *), optional, intent(in) :: units
    2949             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    2950             :     real(sp), optional, intent(in) :: missing_value
    2951             :     logical, optional, intent(in) :: create
    2952             :     integer(i4), optional, intent(inout) :: ncid
    2953             :     integer(i4), optional, intent(in) :: nrec
    2954             :     ! local variables
    2955             :     logical :: create_loc
    2956             :     character(256) :: dummy_name
    2957             :     integer(i4) :: deflate
    2958           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    2959           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    2960           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    2961             :     integer(i4) :: idim      ! read dimension on append
    2962             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    2963             :     integer(i4) :: u_dimid
    2964             :     integer(i4) :: u_len     ! length of unlimited dimension
    2965             :     integer(i4) :: f_handle
    2966           0 :     integer(i4), dimension(:), allocatable :: dims
    2967           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    2968           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    2969             :     integer(i4) :: i         ! loop indices
    2970           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    2971           0 :     real(sp), dimension(1) :: dummy     ! dummy read
    2972             :     logical :: openfile  ! tmp logical
    2973             :     !
    2974           0 :     ndim = size(dnames, 1)
    2975             :     ! consistency checks
    2976           0 :     d_unlimit = 0_i4
    2977           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    2978           0 :     if ((size(dnames, 1) .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    2979           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    2980           0 :       stop '***ERROR see StdOut'
    2981             :     end if
    2982           0 :     if (size(dnames, 1) .gt. ndim_const + 1) then
    2983           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    2984           0 :       stop '***ERROR see StdOut'
    2985             :     end if
    2986           0 :     allocate(chunksizes(ndim))
    2987           0 :     allocate(start(ndim))
    2988           0 :     allocate(counter(ndim))
    2989           0 :     allocate(dims(ndim))
    2990           0 :     allocate(dimid(ndim))
    2991           0 :     allocate(varid(1 + ndim))
    2992           0 :     allocate(dummy_count(ndim))
    2993             :     ! initialize
    2994           0 :     deflate = 1
    2995           0 :     if (ndim .gt. ndim_const) then
    2996           0 :       chunksizes = (/ size(arr, 1), 1 /)
    2997           0 :       dims(1 : ndim - 1) = shape(arr)
    2998           0 :       dims(ndim) = 1
    2999             :     else
    3000           0 :       chunksizes = (/ size(arr, 1) /)
    3001           0 :       dims(1 : ndim_const) = shape(arr)
    3002             :     end if
    3003           0 :     start(:) = 1
    3004           0 :     counter(:) = dims
    3005           0 :     dummy_count = 1
    3006           0 :     dummy = nf90_fill_float
    3007             :     ! open the netcdf file
    3008           0 :     if (present(ncid)) then
    3009           0 :       if (ncid < 0_i4) then
    3010             :         openfile = .true.
    3011             :       else
    3012           0 :         openfile = .false.
    3013           0 :         f_handle = ncid
    3014             :       end if
    3015             :     else
    3016             :       openfile = .true.
    3017             :     end if
    3018             :     if (openfile) then
    3019           0 :       create_loc = .false.
    3020           0 :       if (present(create)) create_loc = create
    3021           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    3022             :     end if
    3023             :     ! check whether variable exists
    3024           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    3025             :       ! append
    3026           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    3027           0 :       if (idim .ne. ndim) stop "var2nc_1d_sp: number of variable dimensions /= number of file variable dimensions."
    3028             :       ! check unlimited dimension
    3029           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    3030           0 :       if (u_dimid .eq. -1) stop 'var2nc_1d_sp: cannot append, no unlimited dimension defined'
    3031             :       ! check for unlimited dimension
    3032           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_1d_sp: unlimited dimension not specified correctly'
    3033           0 :       if (present(nrec)) then
    3034           0 :         start(d_unlimit) = nrec
    3035             :       else
    3036             :         ! get length of unlimited dimension
    3037           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    3038             :         ! adapt start, that is find last written chunk
    3039           0 :         do i = u_len, 1, -1
    3040           0 :           if (ne(dummy(1), nf90_fill_float)) exit
    3041           0 :           start(d_unlimit) = i
    3042           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    3043             :         end do
    3044           0 :         start(d_unlimit) = start(d_unlimit) + 1
    3045             :       end if
    3046             :     else
    3047             :       ! define dimension
    3048           0 :       do i = 1, ndim
    3049             :         ! check whether dimension exists
    3050           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    3051             :           ! create dimension
    3052           0 :           if (i .eq. d_unlimit) then
    3053             :             ! define unlimited dimension
    3054           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    3055             :           else
    3056             :             ! define limited dimension
    3057           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    3058             :           end if
    3059             :         end if
    3060             :       end do
    3061             :       ! define variable
    3062             :       call check(nf90_def_var(f_handle, v_name, NF90_FLOAT, dimid, varid(ndim + 1), &
    3063           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    3064           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    3065           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    3066           0 :       if (present(missing_value)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'missing_value', missing_value))
    3067           0 :       if (present(attributes)) then
    3068           0 :         do i = 1, size(attributes, dim = 1)
    3069           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    3070             :             ! write number
    3071           0 :             read(attributes(i, 2), '(F10.2)') dummy(1)
    3072             :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3073           0 :                     trim(attributes(i, 1)), dummy(1)))
    3074             :           else
    3075             :             ! write string
    3076             :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3077           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    3078             :           end if
    3079             :         end do
    3080             :       end if
    3081             :       ! end definition
    3082           0 :       call check(nf90_enddef(f_handle))
    3083             :     end if
    3084             :     ! inquire dimensions
    3085           0 :     do i = 1, ndim_const
    3086           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    3087           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    3088           0 :               stop "var2nc_1d_sp: dimension name problem."
    3089           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    3090           0 :               stop "var2nc_1d_sp: variable dimension /= file variable dimension."
    3091             :     enddo
    3092             :     ! write time and variable
    3093           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    3094             :     ! close netcdf_dataset
    3095           0 :     if (present(ncid)) then
    3096           0 :       if (ncid < 0_i4) ncid = f_handle
    3097             :     else
    3098           0 :       call close_netcdf(f_handle)
    3099             :     end if
    3100             :     !
    3101           0 :   end subroutine var2nc_1d_sp
    3102             : 
    3103           0 :   subroutine var2nc_1d_dp(f_name, arr, dnames, v_name, dim_unlimited, &
    3104           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    3105             :     !
    3106             :     implicit none
    3107             :     !
    3108             :     integer(i4), parameter :: ndim_const = 1
    3109             :     integer(i4) :: ndim
    3110             :     ! input variables
    3111             :     character(len = *), intent(in) :: f_name
    3112             :     real(dp), dimension(:), intent(in) :: arr
    3113             :     character(len = *), intent(in) :: v_name
    3114             :     character(len = *), dimension(:), intent(in) :: dnames
    3115             :     ! attributes
    3116             :     integer(i4), optional, intent(in) :: dim_unlimited
    3117             :     character(len = *), optional, intent(in) :: long_name
    3118             :     character(len = *), optional, intent(in) :: units
    3119             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    3120             :     real(dp), optional, intent(in) :: missing_value
    3121             :     logical, optional, intent(in) :: create
    3122             :     integer(i4), optional, intent(inout) :: ncid
    3123             :     integer(i4), optional, intent(in) :: nrec
    3124             :     ! local variables
    3125             :     logical :: create_loc
    3126             :     character(256) :: dummy_name
    3127             :     integer(i4) :: deflate
    3128           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    3129           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    3130           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    3131             :     integer(i4) :: idim      ! read dimension on append
    3132             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    3133             :     integer(i4) :: u_dimid
    3134             :     integer(i4) :: u_len     ! length of unlimited dimension
    3135             :     integer(i4) :: f_handle
    3136           0 :     integer(i4), dimension(:), allocatable :: dims
    3137           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    3138           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    3139             :     integer(i4) :: i         ! loop indices
    3140           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    3141           0 :     real(dp), dimension(1) :: dummy     ! dummy read
    3142             :     logical :: openfile  ! tmp logical
    3143             :     !
    3144           0 :     ndim = size(dnames, 1)
    3145             :     ! consistency checks
    3146           0 :     d_unlimit = 0_i4
    3147           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    3148           0 :     if ((size(dnames, 1) .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    3149           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    3150           0 :       stop '***ERROR see StdOut'
    3151             :     end if
    3152           0 :     if (size(dnames, 1) .gt. ndim_const + 1) then
    3153           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    3154           0 :       stop '***ERROR see StdOut'
    3155             :     end if
    3156           0 :     allocate(chunksizes(ndim))
    3157           0 :     allocate(start(ndim))
    3158           0 :     allocate(counter(ndim))
    3159           0 :     allocate(dims(ndim))
    3160           0 :     allocate(dimid(ndim))
    3161           0 :     allocate(varid(1 + ndim))
    3162           0 :     allocate(dummy_count(ndim))
    3163             :     ! initialize
    3164           0 :     deflate = 1
    3165           0 :     if (ndim .gt. ndim_const) then
    3166           0 :       chunksizes = (/ size(arr, 1), 1 /)
    3167           0 :       dims(1 : ndim - 1) = shape(arr)
    3168           0 :       dims(ndim) = 1
    3169             :     else
    3170           0 :       chunksizes = (/ size(arr, 1) /)
    3171           0 :       dims(1 : ndim_const) = shape(arr)
    3172             :     end if
    3173           0 :     start(:) = 1
    3174           0 :     counter(:) = dims
    3175           0 :     dummy_count = 1
    3176           0 :     dummy = nf90_fill_double
    3177             :     ! open the netcdf file
    3178           0 :     if (present(ncid)) then
    3179           0 :       if (ncid < 0_i4) then
    3180             :         openfile = .true.
    3181             :       else
    3182           0 :         openfile = .false.
    3183           0 :         f_handle = ncid
    3184             :       end if
    3185             :     else
    3186             :       openfile = .true.
    3187             :     end if
    3188             :     if (openfile) then
    3189           0 :       create_loc = .false.
    3190           0 :       if (present(create)) create_loc = create
    3191           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    3192             :     end if
    3193             :     ! check whether variable exists
    3194           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    3195             :       ! append
    3196           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    3197           0 :       if (idim .ne. ndim) stop "var2nc_1d_dp: number of variable dimensions /= number of file variable dimensions."
    3198             :       ! check unlimited dimension
    3199           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    3200           0 :       if (u_dimid .eq. -1) stop 'var2nc_1d_dp: cannot append, no unlimited dimension defined'
    3201             :       ! check for unlimited dimension
    3202           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_1d_dp: unlimited dimension not specified correctly'
    3203           0 :       if (present(nrec)) then
    3204           0 :         start(d_unlimit) = nrec
    3205             :       else
    3206             :         ! get length of unlimited dimension
    3207           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    3208             :         ! adapt start, that is find last written chunk
    3209           0 :         do i = u_len, 1, -1
    3210           0 :           if (ne(dummy(1), nf90_fill_double)) exit
    3211           0 :           start(d_unlimit) = i
    3212           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    3213             :         end do
    3214           0 :         start(d_unlimit) = start(d_unlimit) + 1
    3215             :       end if
    3216             :     else
    3217             :       ! define dimension
    3218           0 :       do i = 1, ndim
    3219             :         ! check whether dimension exists
    3220           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    3221             :           ! create dimension
    3222           0 :           if (i .eq. d_unlimit) then
    3223             :             ! define unlimited dimension
    3224           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    3225             :           else
    3226             :             ! define limited dimension
    3227           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    3228             :           end if
    3229             :         end if
    3230             :       end do
    3231             :       ! define variable
    3232             :       call check(nf90_def_var(f_handle, v_name, NF90_DOUBLE, dimid, varid(ndim + 1), &
    3233           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    3234           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    3235           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    3236           0 :       if (present(missing_value)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'missing_value', missing_value))
    3237           0 :       if (present(attributes)) then
    3238           0 :         do i = 1, size(attributes, dim = 1)
    3239           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    3240             :             ! write number
    3241           0 :             read(attributes(i, 2), '(F10.2)') dummy(1)
    3242             :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3243           0 :                     trim(attributes(i, 1)), dummy(1)))
    3244             :           else
    3245             :             ! write string
    3246             :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3247           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    3248             :           end if
    3249             :         end do
    3250             :       end if
    3251             :       ! end definition
    3252           0 :       call check(nf90_enddef(f_handle))
    3253             :     end if
    3254             :     ! inquire dimensions
    3255           0 :     do i = 1, ndim_const
    3256           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    3257           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    3258           0 :               stop "var2nc_1d_dp: dimension name problem."
    3259           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    3260           0 :               stop "var2nc_1d_dp: variable dimension /= file variable dimension."
    3261             :     enddo
    3262             :     ! write time and variable
    3263           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    3264             :     ! close netcdf_dataset
    3265           0 :     if (present(ncid)) then
    3266           0 :       if (ncid < 0_i4) ncid = f_handle
    3267             :     else
    3268           0 :       call close_netcdf(f_handle)
    3269             :     end if
    3270             :     !
    3271           0 :   end subroutine var2nc_1d_dp
    3272             : 
    3273           0 :   subroutine var2nc_2d_i4(f_name, arr, dnames, v_name, dim_unlimited, &
    3274           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    3275             :     !
    3276             :     implicit none
    3277             :     !
    3278             :     integer(i4), parameter :: ndim_const = 2
    3279             :     integer(i4) :: ndim
    3280             :     ! input variables
    3281             :     character(len = *), intent(in) :: f_name
    3282             :     integer(i4), dimension(:, :), intent(in) :: arr
    3283             :     character(len = *), intent(in) :: v_name
    3284             :     character(len = *), dimension(:), intent(in) :: dnames
    3285             :     ! optional
    3286             :     integer(i4), optional, intent(in) :: dim_unlimited
    3287             :     character(len = *), optional, intent(in) :: long_name
    3288             :     character(len = *), optional, intent(in) :: units
    3289             :     integer(i4), optional, intent(in) :: missing_value
    3290             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    3291             :     logical, optional, intent(in) :: create
    3292             :     integer(i4), optional, intent(inout) :: ncid
    3293             :     integer(i4), optional, intent(in) :: nrec
    3294             :     ! local variables
    3295             :     logical :: create_loc
    3296             :     character(256) :: dummy_name
    3297             :     integer(i4) :: deflate
    3298           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    3299           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    3300           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    3301             :     integer(i4) :: idim      ! read dimension on append
    3302             :     integer(i4) :: f_handle
    3303             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    3304             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    3305             :     integer(i4) :: u_len     ! length of unlimited dimension
    3306           0 :     integer(i4), dimension(:), allocatable :: dims
    3307           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    3308           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    3309             :     integer(i4) :: i         ! loop indices
    3310           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    3311             :     integer(i4), dimension(1) :: dummy     ! dummy read
    3312             :     logical :: openfile  ! tmp logical
    3313             :     !
    3314           0 :     ndim = size(dnames, 1)
    3315             :     ! consistency checks
    3316           0 :     d_unlimit = 0_i4
    3317           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    3318           0 :     if ((ndim .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    3319           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    3320           0 :       stop '***ERROR see StdOut'
    3321             :     end if
    3322           0 :     if (ndim .gt. ndim_const + 1) then
    3323           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    3324           0 :       stop '***ERROR see StdOut'
    3325             :     end if
    3326           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    3327             :             (d_unlimit .lt. 0_i4)) then
    3328           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    3329           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    3330           0 :       stop '***ERROR see StdOut'
    3331             :     end if
    3332             :     !
    3333           0 :     allocate(chunksizes(ndim))
    3334           0 :     allocate(start(ndim))
    3335           0 :     allocate(counter(ndim))
    3336           0 :     allocate(dims(ndim))
    3337           0 :     allocate(dimid(ndim))
    3338           0 :     allocate(varid(1 + ndim))
    3339           0 :     allocate(dummy_count(ndim))
    3340             :     ! initialize
    3341           0 :     deflate = 1
    3342           0 :     if (ndim .gt. ndim_const) then
    3343           0 :       chunksizes = (/ size(arr, 1), size(arr, 2), 1 /)
    3344           0 :       dims(1 : ndim - 1) = shape(arr)
    3345           0 :       dims(ndim) = 1
    3346             :     else
    3347           0 :       chunksizes = (/ size(arr, 1), size(arr, 2) /)
    3348           0 :       if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    3349           0 :       dims(1 : ndim_const) = shape(arr)
    3350             :     end if
    3351           0 :     start(:) = 1_i4
    3352           0 :     counter(:) = dims
    3353           0 :     dummy_count = 1_i4
    3354           0 :     dummy = nf90_fill_int
    3355             :     ! open the netcdf file
    3356           0 :     if (present(ncid)) then
    3357           0 :       if (ncid < 0_i4) then
    3358             :         openfile = .true.
    3359             :       else
    3360           0 :         openfile = .false.
    3361           0 :         f_handle = ncid
    3362             :       end if
    3363             :     else
    3364             :       openfile = .true.
    3365             :     end if
    3366             :     if (openfile) then
    3367           0 :       create_loc = .false.
    3368           0 :       if (present(create)) create_loc = create
    3369           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    3370             :     end if
    3371             :     ! check whether variable exists
    3372           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    3373             :       ! append
    3374           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    3375             :       ! consistency checks
    3376           0 :       if (idim .ne. ndim) stop "var2nc_2d_i4: number of variable dimensions /= number of file variable dimensions."
    3377             :       ! check unlimited dimension
    3378           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    3379           0 :       if (u_dimid .eq. -1) stop 'var2nc_2d_i4: cannot append, no unlimited dimension defined'
    3380             :       ! check for unlimited dimension
    3381           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_2d_i4: unlimited dimension not specified correctly'
    3382           0 :       if (present(nrec)) then
    3383           0 :         start(d_unlimit) = nrec
    3384             :       else
    3385             :         ! get length of unlimited dimension
    3386           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    3387             :         ! adapt start, that is find last written chunk
    3388           0 :         do i = u_len, 1, -1
    3389           0 :           if (dummy(1) /= nf90_fill_int) exit
    3390           0 :           start(d_unlimit) = i
    3391           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    3392             :         end do
    3393           0 :         start(d_unlimit) = start(d_unlimit) + 1
    3394             :       end if
    3395             :     else
    3396             :       ! define dimensions
    3397           0 :       do i = 1, ndim
    3398             :         ! check whether dimension exists
    3399           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    3400             :           ! create dimension
    3401           0 :           if (i .eq. d_unlimit) then
    3402             :             ! define unlimited dimension
    3403           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    3404             :           else
    3405             :             ! define limited dimension
    3406           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    3407             :           end if
    3408             :         end if
    3409             :       end do
    3410             :       ! define variable
    3411           0 :       call check(nf90_def_var(f_handle, v_name, NF90_INT, dimid, varid(ndim + 1), &
    3412           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    3413             :       ! add attributes
    3414           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    3415           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    3416           0 :       if (present(missing_value)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'missing_value', missing_value))
    3417           0 :       if (present(attributes)) then
    3418           0 :         do i = 1, size(attributes, dim = 1)
    3419           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    3420             :             ! write number
    3421           0 :             read(attributes(i, 2), '(I6)') dummy(1)
    3422           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3423           0 :                     trim(attributes(i, 1)), dummy(1)))
    3424             :           else
    3425             :             ! write string
    3426           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3427           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    3428             :           end if
    3429             :         end do
    3430             :       end if
    3431             :       ! end definition
    3432           0 :       call check(nf90_enddef(f_handle))
    3433             :     end if
    3434             :     ! check dimensions before writing
    3435           0 :     do i = 1, ndim_const
    3436           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    3437           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    3438           0 :               stop "var2nc_2d_i4: dimension name problem."
    3439           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    3440           0 :               stop "var2nc_2d_i4: variable dimension /= file variable dimension."
    3441             :     end do
    3442             :     ! write variable
    3443           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    3444             :     ! close netcdf_dataset
    3445           0 :     if (present(ncid)) then
    3446           0 :       if (ncid < 0_i4) ncid = f_handle
    3447             :     else
    3448           0 :       call close_netcdf(f_handle)
    3449             :     end if
    3450             :     !
    3451           0 :   end subroutine var2nc_2d_i4
    3452             : 
    3453           0 :   subroutine var2nc_2d_sp(f_name, arr, dnames, v_name, dim_unlimited, &
    3454           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    3455             :     !
    3456             :     implicit none
    3457             :     !
    3458             :     integer(i4), parameter :: ndim_const = 2
    3459             :     integer(i4) :: ndim
    3460             :     ! input variables
    3461             :     character(len = *), intent(in) :: f_name
    3462             :     real(sp), dimension(:, :), intent(in) :: arr
    3463             :     character(len = *), intent(in) :: v_name
    3464             :     character(len = *), dimension(:), intent(in) :: dnames
    3465             :     ! optional
    3466             :     integer(i4), optional, intent(in) :: dim_unlimited
    3467             :     character(len = *), optional, intent(in) :: long_name
    3468             :     character(len = *), optional, intent(in) :: units
    3469             :     real(sp), optional, intent(in) :: missing_value
    3470             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    3471             :     logical, optional, intent(in) :: create
    3472             :     integer(i4), optional, intent(inout) :: ncid
    3473             :     integer(i4), optional, intent(in) :: nrec
    3474             :     ! local variables
    3475             :     logical :: create_loc
    3476             :     character(256) :: dummy_name
    3477             :     integer(i4) :: deflate
    3478           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    3479           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    3480           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    3481             :     integer(i4) :: idim      ! read dimension on append
    3482             :     integer(i4) :: f_handle
    3483             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    3484             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    3485             :     integer(i4) :: u_len     ! length of unlimited dimension
    3486           0 :     integer(i4), dimension(:), allocatable :: dims
    3487           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    3488           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    3489             :     integer(i4) :: i         ! loop indices
    3490           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    3491           0 :     real(sp), dimension(1) :: dummy     ! dummy read
    3492             :     logical :: openfile  ! tmp logical
    3493             :     !
    3494           0 :     ndim = size(dnames, 1)
    3495             :     ! consistency checks
    3496           0 :     d_unlimit = 0_i4
    3497           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    3498           0 :     if ((ndim .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    3499           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    3500           0 :       stop '***ERROR see StdOut'
    3501             :     end if
    3502           0 :     if (ndim .gt. ndim_const + 1) then
    3503           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    3504           0 :       stop '***ERROR see StdOut'
    3505             :     end if
    3506           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    3507             :             (d_unlimit .lt. 0_i4)) then
    3508           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    3509           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    3510           0 :       stop '***ERROR see StdOut'
    3511             :     end if
    3512             :     !
    3513           0 :     allocate(chunksizes(ndim))
    3514           0 :     allocate(start(ndim))
    3515           0 :     allocate(counter(ndim))
    3516           0 :     allocate(dims(ndim))
    3517           0 :     allocate(dimid(ndim))
    3518           0 :     allocate(varid(1 + ndim))
    3519           0 :     allocate(dummy_count(ndim))
    3520             :     ! initialize
    3521           0 :     deflate = 1
    3522           0 :     if (ndim .gt. ndim_const) then
    3523           0 :       chunksizes = (/ size(arr, 1), size(arr, 2), 1 /)
    3524           0 :       dims(1 : ndim - 1) = shape(arr)
    3525           0 :       dims(ndim) = 1
    3526             :     else
    3527           0 :       chunksizes = (/ size(arr, 1), size(arr, 2) /)
    3528           0 :       if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    3529           0 :       dims(1 : ndim_const) = shape(arr)
    3530             :     end if
    3531           0 :     start(:) = 1_i4
    3532           0 :     counter(:) = dims
    3533           0 :     dummy_count = 1_i4
    3534           0 :     dummy = nf90_fill_float
    3535             :     ! open the netcdf file
    3536           0 :     if (present(ncid)) then
    3537           0 :       if (ncid < 0_i4) then
    3538             :         openfile = .true.
    3539             :       else
    3540           0 :         openfile = .false.
    3541           0 :         f_handle = ncid
    3542             :       end if
    3543             :     else
    3544             :       openfile = .true.
    3545             :     end if
    3546             :     if (openfile) then
    3547           0 :       create_loc = .false.
    3548           0 :       if (present(create)) create_loc = create
    3549           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    3550             :     end if
    3551             :     ! check whether variable exists
    3552           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    3553             :       ! append
    3554           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    3555             :       ! consistency checks
    3556           0 :       if (idim .ne. ndim) stop "var2nc_2d_sp: number of variable dimensions /= number of file variable dimensions."
    3557             :       ! check unlimited dimension
    3558           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    3559           0 :       if (u_dimid .eq. -1) stop 'var2nc_2d_sp: cannot append, no unlimited dimension defined'
    3560             :       ! check for unlimited dimension
    3561           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_2d_sp: unlimited dimension not specified correctly'
    3562           0 :       if (present(nrec)) then
    3563           0 :         start(d_unlimit) = nrec
    3564             :       else
    3565             :         ! get length of unlimited dimension
    3566           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    3567             :         ! adapt start, that is find last written chunk
    3568           0 :         do i = u_len, 1, -1
    3569           0 :           if (ne(dummy(1), nf90_fill_float)) exit
    3570           0 :           start(d_unlimit) = i
    3571           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    3572             :         end do
    3573           0 :         start(d_unlimit) = start(d_unlimit) + 1
    3574             :       end if
    3575             :     else
    3576             :       ! define dimensions
    3577           0 :       do i = 1, ndim
    3578             :         ! check whether dimension exists
    3579           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    3580             :           ! create dimension
    3581           0 :           if (i .eq. d_unlimit) then
    3582             :             ! define unlimited dimension
    3583           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    3584             :           else
    3585             :             ! define limited dimension
    3586           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    3587             :           end if
    3588             :         end if
    3589             :       end do
    3590             :       ! define variable
    3591           0 :       call check(nf90_def_var(f_handle, v_name, NF90_FLOAT, dimid, varid(ndim + 1), &
    3592           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    3593             :       ! add attributes
    3594           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    3595           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    3596           0 :       if (present(missing_value)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'missing_value', missing_value))
    3597           0 :       if (present(attributes)) then
    3598           0 :         do i = 1, size(attributes, dim = 1)
    3599           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    3600             :             ! write number
    3601           0 :             read(attributes(i, 2), '(F10.2)') dummy(1)
    3602           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3603           0 :                     trim(attributes(i, 1)), dummy(1)))
    3604             :           else
    3605             :             ! write string
    3606           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3607           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    3608             :           end if
    3609             :         end do
    3610             :       end if
    3611             :       ! end definition
    3612           0 :       call check(nf90_enddef(f_handle))
    3613             :     end if
    3614             :     ! check dimensions before writing
    3615           0 :     do i = 1, ndim_const
    3616           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    3617           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    3618           0 :               stop "var2nc_2d_sp: dimension name problem."
    3619           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    3620           0 :               stop "var2nc_2d_sp: variable dimension /= file variable dimension."
    3621             :     end do
    3622             :     ! write variable
    3623           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    3624             :     ! close netcdf_dataset
    3625           0 :     if (present(ncid)) then
    3626           0 :       if (ncid < 0_i4) ncid = f_handle
    3627             :     else
    3628           0 :       call close_netcdf(f_handle)
    3629             :     end if
    3630             :     !
    3631           0 :   end subroutine var2nc_2d_sp
    3632             : 
    3633           0 :   subroutine var2nc_2d_dp(f_name, arr, dnames, v_name, dim_unlimited, &
    3634           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    3635             :     !
    3636             :     implicit none
    3637             :     !
    3638             :     integer(i4), parameter :: ndim_const = 2
    3639             :     integer(i4) :: ndim
    3640             :     ! input variables
    3641             :     character(len = *), intent(in) :: f_name
    3642             :     real(dp), dimension(:, :), intent(in) :: arr
    3643             :     character(len = *), intent(in) :: v_name
    3644             :     character(len = *), dimension(:), intent(in) :: dnames
    3645             :     ! optional
    3646             :     integer(i4), optional, intent(in) :: dim_unlimited
    3647             :     character(len = *), optional, intent(in) :: long_name
    3648             :     character(len = *), optional, intent(in) :: units
    3649             :     real(dp), optional, intent(in) :: missing_value
    3650             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    3651             :     logical, optional, intent(in) :: create
    3652             :     integer(i4), optional, intent(inout) :: ncid
    3653             :     integer(i4), optional, intent(in) :: nrec
    3654             :     ! local variables
    3655             :     logical :: create_loc
    3656             :     character(256) :: dummy_name
    3657             :     integer(i4) :: deflate
    3658           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    3659           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    3660           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    3661             :     integer(i4) :: idim      ! read dimension on append
    3662             :     integer(i4) :: f_handle
    3663             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    3664             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    3665             :     integer(i4) :: u_len     ! length of unlimited dimension
    3666           0 :     integer(i4), dimension(:), allocatable :: dims
    3667           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    3668           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    3669             :     integer(i4) :: i         ! loop indices
    3670           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    3671           0 :     real(dp), dimension(1) :: dummy     ! dummy read
    3672             :     logical :: openfile  ! tmp logical
    3673             :     !
    3674           0 :     ndim = size(dnames, 1)
    3675             :     ! consistency checks
    3676           0 :     d_unlimit = 0_i4
    3677           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    3678           0 :     if ((ndim .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    3679           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    3680           0 :       stop '***ERROR see StdOut'
    3681             :     end if
    3682           0 :     if (ndim .gt. ndim_const + 1) then
    3683           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    3684           0 :       stop '***ERROR see StdOut'
    3685             :     end if
    3686           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    3687             :             (d_unlimit .lt. 0_i4)) then
    3688           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    3689           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    3690           0 :       stop '***ERROR see StdOut'
    3691             :     end if
    3692             :     !
    3693           0 :     allocate(chunksizes(ndim))
    3694           0 :     allocate(start(ndim))
    3695           0 :     allocate(counter(ndim))
    3696           0 :     allocate(dims(ndim))
    3697           0 :     allocate(dimid(ndim))
    3698           0 :     allocate(varid(1 + ndim))
    3699           0 :     allocate(dummy_count(ndim))
    3700             :     ! initialize
    3701           0 :     deflate = 1
    3702           0 :     if (ndim .gt. ndim_const) then
    3703           0 :       chunksizes = (/ size(arr, 1), size(arr, 2), 1 /)
    3704           0 :       dims(1 : ndim - 1) = shape(arr)
    3705           0 :       dims(ndim) = 1
    3706             :     else
    3707           0 :       chunksizes = (/ size(arr, 1), size(arr, 2) /)
    3708           0 :       if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    3709           0 :       dims(1 : ndim_const) = shape(arr)
    3710             :     end if
    3711           0 :     start(:) = 1_i4
    3712           0 :     counter(:) = dims
    3713           0 :     dummy_count = 1
    3714           0 :     dummy = nf90_fill_double
    3715             :     ! open the netcdf file
    3716           0 :     if (present(ncid)) then
    3717           0 :       if (ncid < 0_i4) then
    3718             :         openfile = .true.
    3719             :       else
    3720           0 :         openfile = .false.
    3721           0 :         f_handle = ncid
    3722             :       end if
    3723             :     else
    3724             :       openfile = .true.
    3725             :     end if
    3726             :     if (openfile) then
    3727           0 :       create_loc = .false.
    3728           0 :       if (present(create)) create_loc = create
    3729           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    3730             :     end if
    3731             :     ! check whether variable exists
    3732           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    3733             :       ! append
    3734           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    3735             :       ! consistency checks
    3736           0 :       if (idim .ne. ndim) stop "var2nc_2d_dp: number of variable dimensions /= number of file variable dimensions."
    3737             :       ! check unlimited dimension
    3738           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    3739           0 :       if (u_dimid .eq. -1) stop 'var2nc_2d_dp: cannot append, no unlimited dimension defined'
    3740             :       ! check for unlimited dimension
    3741           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_2d_dp: unlimited dimension not specified correctly'
    3742           0 :       if (present(nrec)) then
    3743           0 :         start(d_unlimit) = nrec
    3744             :       else
    3745             :         ! get length of unlimited dimension
    3746           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    3747             :         ! adapt start, that is find last written chunk
    3748           0 :         do i = u_len, 1, -1
    3749           0 :           if (ne(dummy(1), nf90_fill_double)) exit
    3750           0 :           start(d_unlimit) = i
    3751           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    3752             :         end do
    3753           0 :         start(d_unlimit) = start(d_unlimit) + 1
    3754             :       end if
    3755             :     else
    3756             :       ! define dimensions
    3757           0 :       do i = 1, ndim
    3758             :         ! check whether dimension exists
    3759           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    3760             :           ! create dimension
    3761           0 :           if (i .eq. d_unlimit) then
    3762             :             ! define unlimited dimension
    3763           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    3764             :           else
    3765             :             ! define limited dimension
    3766           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    3767             :           end if
    3768             :         end if
    3769             :       end do
    3770             :       ! define variable
    3771           0 :       call check(nf90_def_var(f_handle, v_name, NF90_DOUBLE, dimid, varid(ndim + 1), &
    3772           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    3773             :       ! add attributes
    3774           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    3775           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    3776           0 :       if (present(missing_value)) call check(nf90_put_att(f_handle, varid(ndim + 1), 'missing_value', missing_value))
    3777           0 :       if (present(attributes)) then
    3778           0 :         do i = 1, size(attributes, dim = 1)
    3779           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    3780             :             ! write number
    3781           0 :             read(attributes(i, 2), '(F10.2)') dummy(1)
    3782           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3783           0 :                     trim(attributes(i, 1)), dummy(1)))
    3784             :           else
    3785             :             ! write string
    3786           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3787           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    3788             :           end if
    3789             :         end do
    3790             :       end if
    3791             :       ! end definition
    3792           0 :       call check(nf90_enddef(f_handle))
    3793             :     end if
    3794             :     ! check dimensions before writing
    3795           0 :     do i = 1, ndim_const
    3796           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    3797           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    3798           0 :               stop "var2nc_2d_dp: dimension name problem."
    3799           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    3800           0 :               stop "var2nc_2d_dp: variable dimension /= file variable dimension."
    3801             :     end do
    3802             :     ! write variable
    3803           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    3804             :     ! close netcdf_dataset
    3805           0 :     if (present(ncid)) then
    3806           0 :       if (ncid < 0_i4) ncid = f_handle
    3807             :     else
    3808           0 :       call close_netcdf(f_handle)
    3809             :     end if
    3810             :     !
    3811           0 :   end subroutine var2nc_2d_dp
    3812             : 
    3813           0 :   subroutine var2nc_3d_i4(f_name, arr, dnames, v_name, dim_unlimited, &
    3814           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    3815             :     !
    3816             :     implicit none
    3817             :     !
    3818             :     integer(i4), parameter :: ndim_const = 3
    3819             :     integer(i4) :: ndim
    3820             :     ! input variables
    3821             :     character(len = *), intent(in) :: f_name
    3822             :     integer(i4), dimension(:, :, :), intent(in) :: arr
    3823             :     character(len = *), intent(in) :: v_name
    3824             :     character(len = *), dimension(:), intent(in) :: dnames
    3825             :     ! optional
    3826             :     integer(i4), optional, intent(in) :: dim_unlimited
    3827             :     character(len = *), optional, intent(in) :: long_name
    3828             :     character(len = *), optional, intent(in) :: units
    3829             :     integer(i4), optional, intent(in) :: missing_value
    3830             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    3831             :     logical, optional, intent(in) :: create
    3832             :     integer(i4), optional, intent(inout) :: ncid
    3833             :     integer(i4), optional, intent(in) :: nrec
    3834             :     ! local variables
    3835             :     logical :: create_loc
    3836             :     character(256) :: dummy_name
    3837             :     integer(i4) :: deflate
    3838           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    3839           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    3840           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    3841             :     integer(i4) :: idim      ! read dimension on append
    3842             :     integer(i4) :: f_handle
    3843             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    3844             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    3845             :     integer(i4) :: u_len     ! length of unlimited dimension
    3846           0 :     integer(i4), dimension(:), allocatable :: dims
    3847           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    3848           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    3849             :     integer(i4) :: i         ! loop indices
    3850           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    3851             :     integer(i4), dimension(1) :: dummy     ! dummy read
    3852             :     logical :: openfile  ! tmp logical
    3853             :     !
    3854           0 :     ndim = size(dnames, 1)
    3855             :     ! consistency checks
    3856           0 :     d_unlimit = 0_i4
    3857           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    3858           0 :     if ((ndim .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    3859           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    3860           0 :       stop '***ERROR see StdOut'
    3861             :     end if
    3862           0 :     if (ndim .gt. ndim_const + 1) then
    3863           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    3864           0 :       stop '***ERROR see StdOut'
    3865             :     end if
    3866           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    3867             :             (d_unlimit .lt. 0_i4)) then
    3868           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    3869           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    3870           0 :       stop '***ERROR see StdOut'
    3871             :     end if
    3872             :     !
    3873           0 :     allocate(chunksizes(ndim))
    3874           0 :     allocate(start(ndim))
    3875           0 :     allocate(counter(ndim))
    3876           0 :     allocate(dims(ndim))
    3877           0 :     allocate(dimid(ndim))
    3878           0 :     allocate(varid(1 + ndim))
    3879           0 :     allocate(dummy_count(ndim))
    3880             :     ! initialize
    3881           0 :     deflate = 1
    3882           0 :     if (ndim .gt. ndim_const) then
    3883           0 :       chunksizes = (/ size(arr, 1), size(arr, 2), size(arr, 3), 1 /)
    3884           0 :       dims(1 : ndim - 1) = shape(arr)
    3885           0 :       dims(ndim) = 1
    3886             :     else
    3887           0 :       chunksizes = (/ size(arr, 1), size(arr, 2), size(arr, 3) /)
    3888           0 :       if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    3889           0 :       dims(1 : ndim_const) = shape(arr)
    3890             :     end if
    3891           0 :     start(:) = 1_i4
    3892           0 :     counter(:) = dims
    3893           0 :     dummy_count = 1_i4
    3894           0 :     dummy = nf90_fill_int
    3895             :     ! open the netcdf file
    3896           0 :     if (present(ncid)) then
    3897           0 :       if (ncid < 0_i4) then
    3898             :         openfile = .true.
    3899             :       else
    3900           0 :         openfile = .false.
    3901           0 :         f_handle = ncid
    3902             :       end if
    3903             :     else
    3904             :       openfile = .true.
    3905             :     end if
    3906             :     if (openfile) then
    3907           0 :       create_loc = .false.
    3908           0 :       if (present(create)) create_loc = create
    3909           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    3910             :     end if
    3911             :     ! check whether variable exists
    3912           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    3913             :       ! append
    3914           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    3915             :       ! consistency checks
    3916           0 :       if (idim .ne. ndim) stop "var2nc_3d_i4: number of variable dimensions /= number of file variable dimensions."
    3917             :       ! check unlimited dimension
    3918           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    3919           0 :       if (u_dimid .eq. -1) stop 'var2nc_3d_i4: cannot append, no unlimited dimension defined'
    3920             :       ! check for unlimited dimension
    3921           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_3d_i4: unlimited dimension not specified correctly'
    3922           0 :       if (present(nrec)) then
    3923           0 :         start(d_unlimit) = nrec
    3924             :       else
    3925             :         ! get length of unlimited dimension
    3926           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    3927             :         ! adapt start, that is find last written chunk
    3928           0 :         do i = u_len, 1, -1
    3929           0 :           if (dummy(1) /= nf90_fill_int) exit
    3930           0 :           start(d_unlimit) = i
    3931           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    3932             :         end do
    3933           0 :         start(d_unlimit) = start(d_unlimit) + 1
    3934             :       end if
    3935             :     else
    3936             :       ! define dimensions
    3937           0 :       do i = 1, ndim
    3938             :         ! check whether dimension exists
    3939           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    3940             :           ! create dimension
    3941           0 :           if (i .eq. d_unlimit) then
    3942             :             ! define unlimited dimension
    3943           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    3944             :           else
    3945             :             ! define limited dimension
    3946           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    3947             :           end if
    3948             :         end if
    3949             :       end do
    3950             :       ! define variable
    3951           0 :       call check(nf90_def_var(f_handle, v_name, NF90_INT, dimid, varid(ndim + 1), &
    3952           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    3953             :       ! add attributes
    3954           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    3955           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    3956           0 :       if (present(missing_value)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'missing_value', missing_value))
    3957           0 :       if (present(attributes)) then
    3958           0 :         do i = 1, size(attributes, dim = 1)
    3959           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    3960             :             ! write number
    3961           0 :             read(attributes(i, 2), '(I6)') dummy(1)
    3962           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3963           0 :                     trim(attributes(i, 1)), dummy(1)))
    3964             :           else
    3965             :             ! write string
    3966           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    3967           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    3968             :           end if
    3969             :         end do
    3970             :       end if
    3971             :       ! end definition
    3972           0 :       call check(nf90_enddef(f_handle))
    3973             :     end if
    3974             :     ! check dimensions before writing
    3975           0 :     do i = 1, ndim_const
    3976           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    3977           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    3978           0 :               stop "var2nc_3d_i4: dimension name problem."
    3979           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    3980           0 :               stop "var2nc_3d_i4: variable dimension /= file variable dimension."
    3981             :     end do
    3982             :     ! write variable
    3983           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    3984             :     ! close netcdf_dataset
    3985           0 :     if (present(ncid)) then
    3986           0 :       if (ncid < 0_i4) ncid = f_handle
    3987             :     else
    3988           0 :       call close_netcdf(f_handle)
    3989             :     end if
    3990             :     !
    3991           0 :   end subroutine var2nc_3d_i4
    3992             : 
    3993           0 :   subroutine var2nc_3d_sp(f_name, arr, dnames, v_name, dim_unlimited, &
    3994           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    3995             :     !
    3996             :     implicit none
    3997             :     !
    3998             :     integer(i4), parameter :: ndim_const = 3
    3999             :     integer(i4) :: ndim
    4000             :     ! input variables
    4001             :     character(len = *), intent(in) :: f_name
    4002             :     real(sp), dimension(:, :, :), intent(in) :: arr
    4003             :     character(len = *), intent(in) :: v_name
    4004             :     character(len = *), dimension(:), intent(in) :: dnames
    4005             :     ! optional
    4006             :     integer(i4), optional, intent(in) :: dim_unlimited
    4007             :     character(len = *), optional, intent(in) :: long_name
    4008             :     character(len = *), optional, intent(in) :: units
    4009             :     real(sp), optional, intent(in) :: missing_value
    4010             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    4011             :     logical, optional, intent(in) :: create
    4012             :     integer(i4), optional, intent(inout) :: ncid
    4013             :     integer(i4), optional, intent(in) :: nrec
    4014             :     ! local variables
    4015             :     logical :: create_loc
    4016             :     character(256) :: dummy_name
    4017             :     integer(i4) :: deflate
    4018           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    4019           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    4020           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    4021             :     integer(i4) :: idim      ! read dimension on append
    4022             :     integer(i4) :: f_handle
    4023             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    4024             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    4025             :     integer(i4) :: u_len     ! length of unlimited dimension
    4026           0 :     integer(i4), dimension(:), allocatable :: dims
    4027           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    4028           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    4029             :     integer(i4) :: i         ! loop indices
    4030           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    4031           0 :     real(sp), dimension(1) :: dummy     ! dummy read
    4032             :     logical :: openfile  ! tmp logical
    4033             :     !
    4034           0 :     ndim = size(dnames, 1)
    4035             :     ! consistency checks
    4036           0 :     d_unlimit = 0_i4
    4037           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    4038           0 :     if ((ndim .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    4039           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    4040           0 :       stop '***ERROR see StdOut'
    4041             :     end if
    4042           0 :     if (ndim .gt. ndim_const + 1) then
    4043           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    4044           0 :       stop '***ERROR see StdOut'
    4045             :     end if
    4046           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    4047             :             (d_unlimit .lt. 0_i4)) then
    4048           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    4049           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    4050           0 :       stop '***ERROR see StdOut'
    4051             :     end if
    4052             :     !
    4053           0 :     allocate(chunksizes(ndim))
    4054           0 :     allocate(start(ndim))
    4055           0 :     allocate(counter(ndim))
    4056           0 :     allocate(dims(ndim))
    4057           0 :     allocate(dimid(ndim))
    4058           0 :     allocate(varid(1 + ndim))
    4059           0 :     allocate(dummy_count(ndim))
    4060             :     ! initialize
    4061           0 :     deflate = 1
    4062             :     ! set chunk sizes and dimension names
    4063           0 :     if (ndim .gt. ndim_const) then
    4064           0 :       chunksizes = (/ size(arr, 1), size(arr, 2), size(arr, 3), 1 /)
    4065           0 :       dims(1 : ndim - 1) = shape(arr)
    4066           0 :       dims(ndim) = 1
    4067             :     else
    4068           0 :       chunksizes = (/ size(arr, 1), size(arr, 2), size(arr, 3) /)
    4069           0 :       if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    4070           0 :       dims(1 : ndim_const) = shape(arr)
    4071             :     end if
    4072           0 :     start(:) = 1_i4
    4073           0 :     counter(:) = dims
    4074           0 :     dummy_count = 1_i4
    4075           0 :     dummy = nf90_fill_float
    4076             :     ! open the netcdf file
    4077           0 :     if (present(ncid)) then
    4078           0 :       if (ncid < 0_i4) then
    4079             :         openfile = .true.
    4080             :       else
    4081           0 :         openfile = .false.
    4082           0 :         f_handle = ncid
    4083             :       end if
    4084             :     else
    4085             :       openfile = .true.
    4086             :     end if
    4087             :     if (openfile) then
    4088           0 :       create_loc = .false.
    4089           0 :       if (present(create)) create_loc = create
    4090           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    4091             :     end if
    4092             :     ! check whether variable exists
    4093           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    4094             :       ! append
    4095           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    4096             :       ! consistency checks
    4097           0 :       if (idim .ne. ndim) stop "var2nc_3d_sp: number of variable dimensions /= number of file variable dimensions."
    4098             :       ! check unlimited dimension
    4099           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    4100           0 :       if (u_dimid .eq. -1) stop 'var2nc_3d_sp: cannot append, no unlimited dimension defined'
    4101             :       ! check for unlimited dimension
    4102           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_3d_sp: unlimited dimension not specified correctly'
    4103           0 :       if (present(nrec)) then
    4104           0 :         start(d_unlimit) = nrec
    4105             :       else
    4106             :         ! get length of unlimited dimension
    4107           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    4108             :         ! adapt start, that is find last written chunk
    4109           0 :         do i = u_len, 1, -1
    4110           0 :           if (ne(dummy(1), nf90_fill_float)) exit
    4111           0 :           start(d_unlimit) = i
    4112           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    4113             :         end do
    4114           0 :         start(d_unlimit) = start(d_unlimit) + 1
    4115             :       end if
    4116             :     else
    4117             :       ! define dimensions
    4118           0 :       do i = 1, ndim
    4119             :         ! check whether dimension exists
    4120           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    4121             :           ! create dimension
    4122           0 :           if (i .eq. d_unlimit) then
    4123             :             ! define unlimited dimension
    4124           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    4125             :           else
    4126             :             ! define limited dimension
    4127           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    4128             :           end if
    4129             :         end if
    4130             :       end do
    4131             :       ! define variable
    4132           0 :       call check(nf90_def_var(f_handle, v_name, NF90_FLOAT, dimid, varid(ndim + 1), &
    4133           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    4134             :       ! add attributes
    4135           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    4136           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    4137           0 :       if (present(missing_value)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'missing_value', missing_value))
    4138           0 :       if (present(attributes)) then
    4139           0 :         do i = 1, size(attributes, dim = 1)
    4140           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    4141             :             ! write number
    4142           0 :             read(attributes(i, 2), '(F10.2)') dummy(1)
    4143           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    4144           0 :                     trim(attributes(i, 1)), dummy(1)))
    4145             :           else
    4146             :             ! write string
    4147           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    4148           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    4149             :           end if
    4150             :         end do
    4151             :       end if
    4152             :       ! end definition
    4153           0 :       call check(nf90_enddef(f_handle))
    4154             :     end if
    4155             :     ! check dimensions before writing
    4156           0 :     do i = 1, ndim_const
    4157           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    4158           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    4159           0 :               stop "var2nc_3d_sp: dimension name problem."
    4160           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    4161           0 :               stop "var2nc_3d_sp: variable dimension /= file variable dimension."
    4162             :     end do
    4163             :     ! write variable
    4164           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    4165             :     ! close netcdf_dataset
    4166           0 :     if (present(ncid)) then
    4167           0 :       if (ncid < 0_i4) ncid = f_handle
    4168             :     else
    4169           0 :       call close_netcdf(f_handle)
    4170             :     end if
    4171             :     !
    4172           0 :   end subroutine var2nc_3d_sp
    4173             : 
    4174           0 :   subroutine var2nc_3d_dp(f_name, arr, dnames, v_name, dim_unlimited, &
    4175           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    4176             :     !
    4177             :     implicit none
    4178             :     !
    4179             :     integer(i4), parameter :: ndim_const = 3
    4180             :     integer(i4) :: ndim
    4181             :     ! input variables
    4182             :     character(len = *), intent(in) :: f_name
    4183             :     real(dp), dimension(:, :, :), intent(in) :: arr
    4184             :     character(len = *), intent(in) :: v_name
    4185             :     character(len = *), dimension(:), intent(in) :: dnames
    4186             :     ! optional
    4187             :     integer(i4), optional, intent(in) :: dim_unlimited
    4188             :     character(len = *), optional, intent(in) :: long_name
    4189             :     character(len = *), optional, intent(in) :: units
    4190             :     real(dp), optional, intent(in) :: missing_value
    4191             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    4192             :     logical, optional, intent(in) :: create
    4193             :     integer(i4), optional, intent(inout) :: ncid
    4194             :     integer(i4), optional, intent(in) :: nrec
    4195             :     ! local variables
    4196             :     logical :: create_loc
    4197             :     character(256) :: dummy_name
    4198             :     integer(i4) :: deflate
    4199           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    4200           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    4201           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    4202             :     integer(i4) :: idim      ! read dimension on append
    4203             :     integer(i4) :: f_handle
    4204             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    4205             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    4206             :     integer(i4) :: u_len     ! length of unlimited dimension
    4207           0 :     integer(i4), dimension(:), allocatable :: dims
    4208           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    4209           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    4210             :     integer(i4) :: i         ! loop indices
    4211           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    4212           0 :     real(dp), dimension(1) :: dummy     ! dummy read
    4213             :     logical :: openfile  ! tmp logical
    4214             :     !
    4215           0 :     ndim = size(dnames, 1)
    4216             :     ! consistency checks
    4217           0 :     d_unlimit = 0_i4
    4218           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    4219           0 :     if ((ndim .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    4220           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    4221           0 :       stop '***ERROR see StdOut'
    4222             :     end if
    4223           0 :     if (ndim .gt. ndim_const + 1) then
    4224           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    4225           0 :       stop '***ERROR see StdOut'
    4226             :     end if
    4227           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    4228             :             (d_unlimit .lt. 0_i4)) then
    4229           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    4230           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    4231           0 :       stop '***ERROR see StdOut'
    4232             :     end if
    4233             :     !
    4234           0 :     allocate(chunksizes(ndim))
    4235           0 :     allocate(start(ndim))
    4236           0 :     allocate(counter(ndim))
    4237           0 :     allocate(dims(ndim))
    4238           0 :     allocate(dimid(ndim))
    4239           0 :     allocate(varid(1 + ndim))
    4240           0 :     allocate(dummy_count(ndim))
    4241             :     ! initialize
    4242           0 :     deflate = 1
    4243           0 :     if (ndim .gt. ndim_const) then
    4244           0 :       chunksizes = (/ size(arr, 1), size(arr, 2), size(arr, 3), 1 /)
    4245           0 :       dims(1 : ndim - 1) = shape(arr)
    4246           0 :       dims(ndim) = 1
    4247             :     else
    4248           0 :       chunksizes = (/ size(arr, 1), size(arr, 2), size(arr, 3) /)
    4249           0 :       if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    4250           0 :       dims(1 : ndim_const) = shape(arr)
    4251             :     end if
    4252           0 :     start(:) = 1_i4
    4253           0 :     counter(:) = dims
    4254           0 :     dummy_count = 1
    4255           0 :     dummy = nf90_fill_double
    4256             :     ! open the netcdf file
    4257           0 :     if (present(ncid)) then
    4258           0 :       if (ncid < 0_i4) then
    4259             :         openfile = .true.
    4260             :       else
    4261           0 :         openfile = .false.
    4262           0 :         f_handle = ncid
    4263             :       end if
    4264             :     else
    4265             :       openfile = .true.
    4266             :     end if
    4267             :     if (openfile) then
    4268           0 :       create_loc = .false.
    4269           0 :       if (present(create)) create_loc = create
    4270           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    4271             :     end if
    4272             :     ! check whether variable exists
    4273           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    4274             :       ! append
    4275           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    4276             :       ! consistency checks
    4277           0 :       if (idim .ne. ndim) stop "var2nc_3d_dp: number of variable dimensions /= number of file variable dimensions."
    4278             :       ! check unlimited dimension
    4279           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    4280           0 :       if (u_dimid .eq. -1) stop 'var2nc_3d_dp: cannot append, no unlimited dimension defined'
    4281             :       ! check for unlimited dimension
    4282           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_3d_dp: unlimited dimension not specified correctly'
    4283           0 :       if (present(nrec)) then
    4284           0 :         start(d_unlimit) = nrec
    4285             :       else
    4286             :         ! get length of unlimited dimension
    4287           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    4288             :         ! adapt start, that is find last written chunk
    4289           0 :         do i = u_len, 1, -1
    4290           0 :           if (ne(dummy(1), nf90_fill_double)) exit
    4291           0 :           start(d_unlimit) = i
    4292           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    4293             :         end do
    4294           0 :         start(d_unlimit) = start(d_unlimit) + 1
    4295             :       end if
    4296             :     else
    4297             :       ! define dimensions
    4298           0 :       do i = 1, ndim
    4299             :         ! check whether dimension exists
    4300           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    4301             :           ! create dimension
    4302           0 :           if (i .eq. d_unlimit) then
    4303             :             ! define unlimited dimension
    4304           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    4305             :           else
    4306             :             ! define limited dimension
    4307           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    4308             :           end if
    4309             :         end if
    4310             :       end do
    4311             :       ! define variable
    4312           0 :       call check(nf90_def_var(f_handle, v_name, NF90_DOUBLE, dimid, varid(ndim + 1), &
    4313           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    4314             :       ! add attributes
    4315           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    4316           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    4317           0 :       if (present(missing_value)) call check(nf90_put_att(f_handle, varid(ndim + 1), 'missing_value', missing_value))
    4318           0 :       if (present(attributes)) then
    4319           0 :         do i = 1, size(attributes, dim = 1)
    4320           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    4321             :             ! write number
    4322           0 :             read(attributes(i, 2), '(F10.2)') dummy(1)
    4323           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    4324           0 :                     trim(attributes(i, 1)), dummy(1)))
    4325             :           else
    4326             :             ! write string
    4327           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    4328           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    4329             :           end if
    4330             :         end do
    4331             :       end if
    4332             :       ! end definition
    4333           0 :       call check(nf90_enddef(f_handle))
    4334             :     end if
    4335             :     ! check dimensions before writing
    4336           0 :     do i = 1, ndim_const
    4337           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    4338           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    4339           0 :               stop "var2nc_3d_dp: dimension name problem."
    4340           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    4341           0 :               stop "var2nc_3d_dp: variable dimension /= file variable dimension."
    4342             :     end do
    4343             :     ! write variable
    4344           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    4345             :     ! close netcdf_dataset
    4346           0 :     if (present(ncid)) then
    4347           0 :       if (ncid < 0_i4) ncid = f_handle
    4348             :     else
    4349           0 :       call close_netcdf(f_handle)
    4350             :     end if
    4351             :     !
    4352           0 :   end subroutine var2nc_3d_dp
    4353             : 
    4354           0 :   subroutine var2nc_4d_i4(f_name, arr, dnames, v_name, dim_unlimited, &
    4355           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    4356             :     !
    4357             :     implicit none
    4358             :     !
    4359             :     integer(i4), parameter :: ndim_const = 4
    4360             :     integer(i4) :: ndim
    4361             :     ! input variables
    4362             :     character(len = *), intent(in) :: f_name
    4363             :     integer(i4), dimension(:, :, :, :), intent(in) :: arr
    4364             :     character(len = *), intent(in) :: v_name
    4365             :     character(len = *), dimension(:), intent(in) :: dnames
    4366             :     ! optional
    4367             :     integer(i4), optional, intent(in) :: dim_unlimited
    4368             :     character(len = *), optional, intent(in) :: long_name
    4369             :     character(len = *), optional, intent(in) :: units
    4370             :     integer(i4), optional, intent(in) :: missing_value
    4371             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    4372             :     logical, optional, intent(in) :: create
    4373             :     integer(i4), optional, intent(inout) :: ncid
    4374             :     integer(i4), optional, intent(in) :: nrec
    4375             :     ! local variables
    4376             :     logical :: create_loc
    4377             :     character(256) :: dummy_name
    4378             :     integer(i4) :: deflate
    4379           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    4380           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    4381           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    4382             :     integer(i4) :: idim      ! read dimension on append
    4383             :     integer(i4) :: f_handle
    4384             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    4385             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    4386             :     integer(i4) :: u_len     ! length of unlimited dimension
    4387           0 :     integer(i4), dimension(:), allocatable :: dims
    4388           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    4389           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    4390             :     integer(i4) :: i         ! loop indices
    4391           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    4392             :     integer(i4), dimension(1) :: dummy     ! dummy read
    4393             :     logical :: openfile  ! tmp logical
    4394             :     !
    4395           0 :     ndim = size(dnames, 1)
    4396             :     ! consistency checks
    4397           0 :     d_unlimit = 0_i4
    4398           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    4399           0 :     if ((ndim .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    4400           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    4401           0 :       stop '***ERROR see StdOut'
    4402             :     end if
    4403           0 :     if (ndim .gt. ndim_const + 1) then
    4404           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    4405           0 :       stop '***ERROR see StdOut'
    4406             :     end if
    4407           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    4408             :             (d_unlimit .lt. 0_i4)) then
    4409           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    4410           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    4411           0 :       stop '***ERROR see StdOut'
    4412             :     end if
    4413             :     !
    4414           0 :     allocate(chunksizes(ndim))
    4415           0 :     allocate(start(ndim))
    4416           0 :     allocate(counter(ndim))
    4417           0 :     allocate(dims(ndim))
    4418           0 :     allocate(dimid(ndim))
    4419           0 :     allocate(varid(1 + ndim))
    4420           0 :     allocate(dummy_count(ndim))
    4421             :     ! initialize
    4422           0 :     deflate = 1
    4423           0 :     if (ndim .gt. ndim_const) then
    4424             :       chunksizes = (/ size(arr, 1), size(arr, 2), &
    4425           0 :               size(arr, 3), size(arr, 4), 1 /)
    4426           0 :       dims(1 : ndim - 1) = shape(arr)
    4427           0 :       dims(ndim) = 1
    4428             :     else
    4429             :       chunksizes = (/ size(arr, 1), size(arr, 2), &
    4430           0 :               size(arr, 3), size(arr, 4) /)
    4431           0 :       if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    4432           0 :       dims(1 : ndim_const) = shape(arr)
    4433             :     end if
    4434           0 :     start(:) = 1_i4
    4435           0 :     counter(:) = dims
    4436           0 :     dummy_count = 1_i4
    4437           0 :     dummy = nf90_fill_int
    4438             :     ! open the netcdf file
    4439           0 :     if (present(ncid)) then
    4440           0 :       if (ncid < 0_i4) then
    4441             :         openfile = .true.
    4442             :       else
    4443           0 :         openfile = .false.
    4444           0 :         f_handle = ncid
    4445             :       end if
    4446             :     else
    4447             :       openfile = .true.
    4448             :     end if
    4449             :     if (openfile) then
    4450           0 :       create_loc = .false.
    4451           0 :       if (present(create)) create_loc = create
    4452           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    4453             :     end if
    4454             :     ! check whether variable exists
    4455           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    4456             :       ! append
    4457           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    4458             :       ! consistency checks
    4459           0 :       if (idim .ne. ndim) stop "var2nc_4d_i4: number of variable dimensions /= number of file variable dimensions."
    4460             :       ! check unlimited dimension
    4461           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    4462           0 :       if (u_dimid .eq. -1) stop 'var2nc_4d_i4: cannot append, no unlimited dimension defined'
    4463             :       ! check for unlimited dimension
    4464           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_4d_sp: unlimited dimension not specified correctly'
    4465           0 :       if (present(nrec)) then
    4466           0 :         start(d_unlimit) = nrec
    4467             :       else
    4468             :         ! get length of unlimited dimension
    4469           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    4470             :         ! adapt start, that is find last written chunk
    4471           0 :         do i = u_len, 1, -1
    4472           0 :           if (dummy(1) /= nf90_fill_int) exit
    4473           0 :           start(d_unlimit) = i
    4474           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    4475             :         end do
    4476           0 :         start(d_unlimit) = start(d_unlimit) + 1
    4477             :       end if
    4478             :     else
    4479             :       ! define dimensions
    4480           0 :       do i = 1, ndim
    4481             :         ! check whether dimension exists
    4482           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    4483             :           ! create dimension
    4484           0 :           if (i .eq. d_unlimit) then
    4485             :             ! define unlimited dimension
    4486           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    4487             :           else
    4488             :             ! define limited dimension
    4489           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    4490             :           end if
    4491             :         end if
    4492             :       end do
    4493             :       ! define variable
    4494           0 :       call check(nf90_def_var(f_handle, v_name, NF90_INT, dimid, varid(ndim + 1), &
    4495           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    4496             :       ! add attributes
    4497           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    4498           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    4499           0 :       if (present(missing_value)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'missing_value', missing_value))
    4500           0 :       if (present(attributes)) then
    4501           0 :         do i = 1, size(attributes, dim = 1)
    4502           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    4503             :             ! write number
    4504           0 :             read(attributes(i, 2), '(I6)') dummy(1)
    4505           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    4506           0 :                     trim(attributes(i, 1)), dummy(1)))
    4507             :           else
    4508             :             ! write string
    4509           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    4510           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    4511             :           end if
    4512             :         end do
    4513             :       end if
    4514             :       ! end definition
    4515           0 :       call check(nf90_enddef(f_handle))
    4516             :     end if
    4517             :     ! check dimensions before writing
    4518           0 :     do i = 1, ndim_const
    4519           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    4520           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    4521           0 :               stop "var2nc_4d_i4: dimension name problem."
    4522           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    4523           0 :               stop "var2nc_4d_i4: variable dimension /= file variable dimension."
    4524             :     end do
    4525             :     ! write variable
    4526           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    4527             :     ! close netcdf_dataset
    4528           0 :     if (present(ncid)) then
    4529           0 :       if (ncid < 0_i4) ncid = f_handle
    4530             :     else
    4531           0 :       call close_netcdf(f_handle)
    4532             :     end if
    4533             :     !
    4534           0 :   end subroutine var2nc_4d_i4
    4535             : 
    4536           0 :   subroutine var2nc_4d_sp(f_name, arr, dnames, v_name, dim_unlimited, &
    4537           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    4538             :     !
    4539             :     implicit none
    4540             :     !
    4541             :     integer(i4), parameter :: ndim_const = 4
    4542             :     integer(i4) :: ndim
    4543             :     ! input variables
    4544             :     character(len = *), intent(in) :: f_name
    4545             :     real(sp), dimension(:, :, :, :), intent(in) :: arr
    4546             :     character(len = *), intent(in) :: v_name
    4547             :     character(len = *), dimension(:), intent(in) :: dnames
    4548             :     ! optional
    4549             :     integer(i4), optional, intent(in) :: dim_unlimited
    4550             :     character(len = *), optional, intent(in) :: long_name
    4551             :     character(len = *), optional, intent(in) :: units
    4552             :     real(sp), optional, intent(in) :: missing_value
    4553             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    4554             :     logical, optional, intent(in) :: create
    4555             :     integer(i4), optional, intent(inout) :: ncid
    4556             :     integer(i4), optional, intent(in) :: nrec
    4557             :     ! local variables
    4558             :     logical :: create_loc
    4559             :     character(256) :: dummy_name
    4560             :     integer(i4) :: deflate
    4561           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    4562           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    4563           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    4564             :     integer(i4) :: idim      ! read dimension on append
    4565             :     integer(i4) :: f_handle
    4566             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    4567             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    4568             :     integer(i4) :: u_len     ! length of unlimited dimension
    4569           0 :     integer(i4), dimension(:), allocatable :: dims
    4570           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    4571           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    4572             :     integer(i4) :: i         ! loop indices
    4573           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    4574           0 :     real(sp), dimension(1) :: dummy     ! dummy read
    4575             :     logical :: openfile  ! tmp logical
    4576             :     !
    4577           0 :     ndim = size(dnames, 1)
    4578             :     ! consistency checks
    4579           0 :     d_unlimit = 0_i4
    4580           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    4581           0 :     if ((ndim .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    4582           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    4583           0 :       stop '***ERROR see StdOut'
    4584             :     end if
    4585           0 :     if (ndim .gt. ndim_const + 1) then
    4586           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    4587           0 :       stop '***ERROR see StdOut'
    4588             :     end if
    4589           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    4590             :             (d_unlimit .lt. 0_i4)) then
    4591           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    4592           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    4593           0 :       stop '***ERROR see StdOut'
    4594             :     end if
    4595             :     !
    4596           0 :     allocate(chunksizes(ndim))
    4597           0 :     allocate(start(ndim))
    4598           0 :     allocate(counter(ndim))
    4599           0 :     allocate(dims(ndim))
    4600           0 :     allocate(dimid(ndim))
    4601           0 :     allocate(varid(1 + ndim))
    4602           0 :     allocate(dummy_count(ndim))
    4603             :     ! initialize
    4604           0 :     deflate = 1
    4605           0 :     if (ndim .gt. ndim_const) then
    4606             :       chunksizes = (/ size(arr, 1), size(arr, 2), &
    4607           0 :               size(arr, 3), size(arr, 4), 1 /)
    4608           0 :       dims(1 : ndim - 1) = shape(arr)
    4609           0 :       dims(ndim) = 1
    4610             :     else
    4611             :       chunksizes = (/ size(arr, 1), size(arr, 2), &
    4612           0 :               size(arr, 3), size(arr, 4) /)
    4613           0 :       if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    4614           0 :       dims(1 : ndim_const) = shape(arr)
    4615             :     end if
    4616           0 :     start(:) = 1_i4
    4617           0 :     counter(:) = dims
    4618           0 :     dummy_count = 1_i4
    4619           0 :     dummy = nf90_fill_float
    4620             :     ! open the netcdf file
    4621           0 :     if (present(ncid)) then
    4622           0 :       if (ncid < 0_i4) then
    4623             :         openfile = .true.
    4624             :       else
    4625           0 :         openfile = .false.
    4626           0 :         f_handle = ncid
    4627             :       end if
    4628             :     else
    4629             :       openfile = .true.
    4630             :     end if
    4631             :     if (openfile) then
    4632           0 :       create_loc = .false.
    4633           0 :       if (present(create)) create_loc = create
    4634           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    4635             :     end if
    4636             :     ! check whether variable exists
    4637           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    4638             :       ! append
    4639           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    4640             :       ! consistency checks
    4641           0 :       if (idim .ne. ndim) stop "var2nc_4d_sp: number of variable dimensions /= number of file variable dimensions."
    4642             :       ! check unlimited dimension
    4643           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    4644           0 :       if (u_dimid .eq. -1) stop 'var2nc_4d_sp: cannot append, no unlimited dimension defined'
    4645             :       ! check for unlimited dimension
    4646           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_4d_sp: unlimited dimension not specified correctly'
    4647           0 :       if (present(nrec)) then
    4648           0 :         start(d_unlimit) = nrec
    4649             :       else
    4650             :         ! get length of unlimited dimension
    4651           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    4652             :         ! adapt start, that is find last written chunk
    4653           0 :         do i = u_len, 1, -1
    4654           0 :           if (ne(dummy(1), nf90_fill_float)) exit
    4655           0 :           start(d_unlimit) = i
    4656           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    4657             :         end do
    4658           0 :         start(d_unlimit) = start(d_unlimit) + 1
    4659             :       end if
    4660             :     else
    4661             :       ! define dimensions
    4662           0 :       do i = 1, ndim
    4663             :         ! check whether dimension exists
    4664           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    4665             :           ! create dimension
    4666           0 :           if (i .eq. d_unlimit) then
    4667             :             ! define unlimited dimension
    4668           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    4669             :           else
    4670             :             ! define limited dimension
    4671           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    4672             :           end if
    4673             :         end if
    4674             :       end do
    4675             :       ! define variable
    4676           0 :       call check(nf90_def_var(f_handle, v_name, NF90_FLOAT, dimid, varid(ndim + 1), &
    4677           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    4678             :       ! add attributes
    4679           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    4680           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    4681           0 :       if (present(missing_value)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'missing_value', missing_value))
    4682           0 :       if (present(attributes)) then
    4683           0 :         do i = 1, size(attributes, dim = 1)
    4684           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    4685             :             ! write number
    4686           0 :             read(attributes(i, 2), '(F10.2)') dummy(1)
    4687           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    4688           0 :                     trim(attributes(i, 1)), dummy(1)))
    4689             :           else
    4690             :             ! write string
    4691           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    4692           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    4693             :           end if
    4694             :         end do
    4695             :       end if
    4696             :       ! end definition
    4697           0 :       call check(nf90_enddef(f_handle))
    4698             :     end if
    4699             :     ! check dimensions before writing
    4700           0 :     do i = 1, ndim_const
    4701           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    4702           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    4703           0 :               stop "var2nc_4d_sp: dimension name problem."
    4704           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    4705           0 :               stop "var2nc_4d_sp: variable dimension /= file variable dimension."
    4706             :     end do
    4707             :     ! write variable
    4708           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    4709             :     ! close netcdf_dataset
    4710           0 :     if (present(ncid)) then
    4711           0 :       if (ncid < 0_i4) ncid = f_handle
    4712             :     else
    4713           0 :       call close_netcdf(f_handle)
    4714             :     end if
    4715             :     !
    4716           0 :   end subroutine var2nc_4d_sp
    4717             : 
    4718           0 :   subroutine var2nc_4d_dp(f_name, arr, dnames, v_name, dim_unlimited, &
    4719           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    4720             :     !
    4721             :     implicit none
    4722             :     !
    4723             :     integer(i4), parameter :: ndim_const = 4
    4724             :     integer(i4) :: ndim
    4725             :     ! input variables
    4726             :     character(len = *), intent(in) :: f_name
    4727             :     real(dp), dimension(:, :, :, :), intent(in) :: arr
    4728             :     character(len = *), intent(in) :: v_name
    4729             :     character(len = *), dimension(:), intent(in) :: dnames
    4730             :     ! optional
    4731             :     integer(i4), optional, intent(in) :: dim_unlimited
    4732             :     character(len = *), optional, intent(in) :: long_name
    4733             :     character(len = *), optional, intent(in) :: units
    4734             :     real(dp), optional, intent(in) :: missing_value
    4735             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    4736             :     logical, optional, intent(in) :: create
    4737             :     integer(i4), optional, intent(inout) :: ncid
    4738             :     integer(i4), optional, intent(in) :: nrec
    4739             :     ! local variables
    4740             :     logical :: create_loc
    4741             :     character(256) :: dummy_name
    4742             :     integer(i4) :: deflate
    4743           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    4744           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    4745           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    4746             :     integer(i4) :: idim      ! read dimension on append
    4747             :     integer(i4) :: f_handle
    4748             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    4749             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    4750             :     integer(i4) :: u_len     ! length of unlimited dimension
    4751           0 :     integer(i4), dimension(:), allocatable :: dims
    4752           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    4753           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    4754             :     integer(i4) :: i         ! loop indices
    4755           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    4756           0 :     real(dp), dimension(1) :: dummy     ! dummy read
    4757             :     logical :: openfile  ! tmp logical
    4758             :     !
    4759           0 :     ndim = size(dnames, 1)
    4760             :     ! consistency checks
    4761           0 :     d_unlimit = 0_i4
    4762           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    4763           0 :     if ((ndim .eq. ndim_const + 1) .and. (d_unlimit .ne. ndim_const + 1)) then
    4764           0 :       print *, '***ERROR one more dimension name specified than dimension of array, but the last one is not unlimited'
    4765           0 :       stop '***ERROR see StdOut'
    4766             :     end if
    4767           0 :     if (ndim .gt. ndim_const + 1) then
    4768           0 :       print *, '***ERROR too many dimension name specified, should be atmost ndim_const + 1'
    4769           0 :       stop '***ERROR see StdOut'
    4770             :     end if
    4771           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    4772             :             (d_unlimit .lt. 0_i4)) then
    4773           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    4774           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    4775           0 :       stop '***ERROR see StdOut'
    4776             :     end if
    4777             :     !
    4778           0 :     allocate(chunksizes(ndim))
    4779           0 :     allocate(start(ndim))
    4780           0 :     allocate(counter(ndim))
    4781           0 :     allocate(dims(ndim))
    4782           0 :     allocate(dimid(ndim))
    4783           0 :     allocate(varid(1 + ndim))
    4784           0 :     allocate(dummy_count(ndim))
    4785             :     ! Initialize
    4786           0 :     deflate = 1
    4787           0 :     if (ndim .gt. ndim_const) then
    4788             :       chunksizes = (/ size(arr, 1), size(arr, 2), &
    4789           0 :               size(arr, 3), size(arr, 4), 1 /)
    4790           0 :       dims(1 : ndim - 1) = shape(arr)
    4791           0 :       dims(ndim) = 1
    4792             :     else
    4793             :       chunksizes = (/ size(arr, 1), size(arr, 2), &
    4794           0 :               size(arr, 3), size(arr, 4) /)
    4795           0 :       if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    4796           0 :       dims(1 : ndim_const) = shape(arr)
    4797             :     end if
    4798           0 :     start(:) = 1_i4
    4799           0 :     counter(:) = dims
    4800           0 :     dummy_count = 1
    4801           0 :     dummy = nf90_fill_double
    4802             :     ! open the netcdf file
    4803           0 :     if (present(ncid)) then
    4804           0 :       if (ncid < 0_i4) then
    4805             :         openfile = .true.
    4806             :       else
    4807           0 :         openfile = .false.
    4808           0 :         f_handle = ncid
    4809             :       end if
    4810             :     else
    4811             :       openfile = .true.
    4812             :     end if
    4813             :     if (openfile) then
    4814           0 :       create_loc = .false.
    4815           0 :       if (present(create)) create_loc = create
    4816           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    4817             :     end if
    4818             :     ! check whether variable exists
    4819           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    4820             :       ! append
    4821           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    4822             :       ! consistency checks
    4823           0 :       if (idim .ne. ndim) stop "var2nc_4d_dp: number of variable dimensions /= number of file variable dimensions."
    4824             :       ! check unlimited dimension
    4825           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    4826           0 :       if (u_dimid .eq. -1) stop 'var2nc_4d_dp: cannot append, no unlimited dimension defined'
    4827             :       ! check for unlimited dimension
    4828           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_4d_dp: unlimited dimension not specified correctly'
    4829           0 :       if (present(nrec)) then
    4830           0 :         start(d_unlimit) = nrec
    4831             :       else
    4832             :         ! get length of unlimited dimension
    4833           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    4834             :         ! adapt start, that is find last written chunk
    4835           0 :         do i = u_len, 1, -1
    4836           0 :           if (ne(dummy(1), nf90_fill_double)) exit
    4837           0 :           start(d_unlimit) = i
    4838           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    4839             :         end do
    4840           0 :         start(d_unlimit) = start(d_unlimit) + 1
    4841             :       end if
    4842             :     else
    4843             :       ! define dimensions
    4844           0 :       do i = 1, ndim
    4845             :         ! check whether dimension exists
    4846           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    4847             :           ! create dimension
    4848           0 :           if (i .eq. d_unlimit) then
    4849             :             ! define unlimited dimension
    4850           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    4851             :           else
    4852             :             ! define limited dimension
    4853           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    4854             :           end if
    4855             :         end if
    4856             :       end do
    4857             :       ! define variable
    4858           0 :       call check(nf90_def_var(f_handle, v_name, NF90_DOUBLE, dimid, varid(ndim + 1), &
    4859           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    4860             :       ! add attributes
    4861           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    4862           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    4863           0 :       if (present(missing_value)) call check(nf90_put_att(f_handle, varid(ndim + 1), 'missing_value', missing_value))
    4864           0 :       if (present(attributes)) then
    4865           0 :         do i = 1, size(attributes, dim = 1)
    4866           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    4867             :             ! write number
    4868           0 :             read(attributes(i, 2), '(F10.2)') dummy(1)
    4869           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    4870           0 :                     trim(attributes(i, 1)), dummy(1)))
    4871             :           else
    4872             :             ! write string
    4873           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    4874           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    4875             :           end if
    4876             :         end do
    4877             :       end if
    4878             :       ! end definition
    4879           0 :       call check(nf90_enddef(f_handle))
    4880             :     end if
    4881             :     ! check dimensions before writing
    4882           0 :     do i = 1, ndim_const
    4883           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    4884           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    4885           0 :               stop "var2nc_4d_dp: dimension name problem."
    4886           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    4887           0 :               stop "var2nc_4d_dp: variable dimension /= file variable dimension."
    4888             :     end do
    4889             :     ! write variable
    4890           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    4891             :     ! close netcdf_dataset
    4892           0 :     if (present(ncid)) then
    4893           0 :       if (ncid < 0_i4) ncid = f_handle
    4894             :     else
    4895           0 :       call close_netcdf(f_handle)
    4896             :     end if
    4897             :     !
    4898           0 :   end subroutine var2nc_4d_dp
    4899             : 
    4900           0 :   subroutine var2nc_5d_i4(f_name, arr, dnames, v_name, dim_unlimited, &
    4901           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    4902             :     !
    4903             :     implicit none
    4904             :     !
    4905             :     integer(i4), parameter :: ndim_const = 5
    4906             :     integer(i4) :: ndim
    4907             :     ! input variables
    4908             :     character(len = *), intent(in) :: f_name
    4909             :     integer(i4), dimension(:, :, :, :, :), intent(in) :: arr
    4910             :     character(len = *), intent(in) :: v_name
    4911             :     character(len = *), dimension(:), intent(in) :: dnames
    4912             :     ! optional
    4913             :     integer(i4), optional, intent(in) :: dim_unlimited
    4914             :     character(len = *), optional, intent(in) :: long_name
    4915             :     character(len = *), optional, intent(in) :: units
    4916             :     integer(i4), optional, intent(in) :: missing_value
    4917             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    4918             :     logical, optional, intent(in) :: create
    4919             :     integer(i4), optional, intent(inout) :: ncid
    4920             :     integer(i4), optional, intent(in) :: nrec
    4921             :     ! local variables
    4922             :     logical :: create_loc
    4923             :     character(256) :: dummy_name
    4924             :     integer(i4) :: deflate
    4925           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    4926           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    4927           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    4928             :     integer(i4) :: idim      ! read dimension on append
    4929             :     integer(i4) :: f_handle
    4930             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    4931             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    4932             :     integer(i4) :: u_len     ! length of unlimited dimension
    4933           0 :     integer(i4), dimension(:), allocatable :: dims
    4934           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    4935           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    4936             :     integer(i4) :: i         ! loop indices
    4937           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    4938             :     integer(i4), dimension(1) :: dummy     ! dummy read
    4939             :     logical :: openfile  ! tmp logical
    4940             :     !
    4941           0 :     ndim = size(dnames, 1)
    4942           0 :     d_unlimit = 0_i4
    4943           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    4944             :     ! consistency checks
    4945           0 :     if (ndim .gt. ndim_const) then
    4946           0 :       print *, '***ERROR more than five dimension names given'
    4947           0 :       stop '***ERROR see StdOut'
    4948             :     end if
    4949           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    4950             :             (d_unlimit .lt. 0_i4)) then
    4951           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    4952           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    4953           0 :       stop '***ERROR see StdOut'
    4954             :     end if
    4955             :     !
    4956           0 :     allocate(chunksizes(ndim))
    4957           0 :     allocate(start(ndim))
    4958           0 :     allocate(counter(ndim))
    4959           0 :     allocate(dims(ndim))
    4960           0 :     allocate(dimid(ndim))
    4961           0 :     allocate(varid(1 + ndim))
    4962           0 :     allocate(dummy_count(ndim))
    4963             :     ! initialize
    4964           0 :     deflate = 1
    4965           0 :     chunksizes = (/ size(arr, 1), size(arr, 2), size(arr, 3), size(arr, 4), size(arr, 5) /)
    4966           0 :     if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    4967           0 :     dims(1 : ndim) = shape(arr)
    4968           0 :     start(:) = 1_i4
    4969           0 :     counter(:) = dims
    4970           0 :     dummy_count = 1_i4
    4971           0 :     dummy = nf90_fill_int
    4972           0 :     d_unlimit = 0_i4
    4973           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    4974             :     ! open the netcdf file
    4975           0 :     if (present(ncid)) then
    4976           0 :       if (ncid < 0_i4) then
    4977             :         openfile = .true.
    4978             :       else
    4979           0 :         openfile = .false.
    4980           0 :         f_handle = ncid
    4981             :       end if
    4982             :     else
    4983             :       openfile = .true.
    4984             :     end if
    4985             :     if (openfile) then
    4986           0 :       create_loc = .false.
    4987           0 :       if (present(create)) create_loc = create
    4988           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    4989             :     end if
    4990             :     ! check whether variable exists
    4991           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    4992             :       ! append
    4993           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    4994             :       ! consistency checks
    4995           0 :       if (idim .ne. ndim) stop "var2nc_5d_i4: number of variable dimensions /= number of file variable dimensions."
    4996             :       ! check unlimited dimension
    4997           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    4998           0 :       if (u_dimid .eq. -1) stop 'var2nc_5d_i4: cannot append, no unlimited dimension defined'
    4999             :       ! check for unlimited dimension
    5000           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_5d_sp: unlimited dimension not specified correctly'
    5001           0 :       if (present(nrec)) then
    5002           0 :         start(d_unlimit) = nrec
    5003             :       else
    5004             :         ! get length of unlimited dimension
    5005           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    5006             :         ! adapt start, that is find last written chunk
    5007           0 :         do i = u_len, 1, -1
    5008           0 :           if (dummy(1) /= nf90_fill_int) exit
    5009           0 :           start(d_unlimit) = i
    5010           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    5011             :         end do
    5012           0 :         start(d_unlimit) = start(d_unlimit) + 1
    5013             :       end if
    5014             :     else
    5015             :       ! define dimensions
    5016           0 :       do i = 1, ndim
    5017             :         ! check whether dimension exists
    5018           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    5019             :           ! create dimension
    5020           0 :           if (i .eq. d_unlimit) then
    5021             :             ! define unlimited dimension
    5022           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    5023             :           else
    5024             :             ! define limited dimension
    5025           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    5026             :           end if
    5027             :         end if
    5028             :       end do
    5029             :       ! define variable
    5030           0 :       call check(nf90_def_var(f_handle, v_name, NF90_INT, dimid, varid(ndim + 1), &
    5031           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    5032             :       ! add attributes
    5033           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    5034           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    5035           0 :       if (present(missing_value)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'missing_value', missing_value))
    5036           0 :       if (present(attributes)) then
    5037           0 :         do i = 1, size(attributes, dim = 1)
    5038           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    5039             :             ! write number
    5040           0 :             read(attributes(i, 2), '(I6)') dummy(1)
    5041           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    5042           0 :                     trim(attributes(i, 1)), dummy(1)))
    5043             :           else
    5044             :             ! write string
    5045           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    5046           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    5047             :           end if
    5048             :         end do
    5049             :       end if
    5050             :       ! end definition
    5051           0 :       call check(nf90_enddef(f_handle))
    5052             :     end if
    5053             :     ! check dimensions before writing
    5054           0 :     do i = 1, ndim_const
    5055           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    5056           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    5057           0 :               stop "var2nc_5d_i4: dimension name problem."
    5058           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    5059           0 :               stop "var2nc_5d_i4: variable dimension /= file variable dimension."
    5060             :     end do
    5061             :     ! write variable
    5062           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    5063             :     ! close netcdf_dataset
    5064           0 :     if (present(ncid)) then
    5065           0 :       if (ncid < 0_i4) ncid = f_handle
    5066             :     else
    5067           0 :       call close_netcdf(f_handle)
    5068             :     end if
    5069             :     !
    5070           0 :   end subroutine var2nc_5d_i4
    5071             : 
    5072           0 :   subroutine var2nc_5d_sp(f_name, arr, dnames, v_name, dim_unlimited, &
    5073           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    5074             :     !
    5075             :     implicit none
    5076             :     !
    5077             :     integer(i4), parameter :: ndim_const = 5
    5078             :     integer(i4) :: ndim
    5079             :     ! input variables
    5080             :     character(len = *), intent(in) :: f_name
    5081             :     real(sp), dimension(:, :, :, :, :), intent(in) :: arr
    5082             :     character(len = *), intent(in) :: v_name
    5083             :     character(len = *), dimension(:), intent(in) :: dnames
    5084             :     ! optional
    5085             :     integer(i4), optional, intent(in) :: dim_unlimited
    5086             :     character(len = *), optional, intent(in) :: long_name
    5087             :     character(len = *), optional, intent(in) :: units
    5088             :     real(sp), optional, intent(in) :: missing_value
    5089             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    5090             :     logical, optional, intent(in) :: create
    5091             :     integer(i4), optional, intent(inout) :: ncid
    5092             :     integer(i4), optional, intent(in) :: nrec
    5093             :     ! local variables
    5094             :     logical :: create_loc
    5095             :     character(256) :: dummy_name
    5096             :     integer(i4) :: deflate
    5097           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    5098           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    5099           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    5100             :     integer(i4) :: idim      ! read dimension on append
    5101             :     integer(i4) :: f_handle
    5102             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    5103             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    5104             :     integer(i4) :: u_len     ! length of unlimited dimension
    5105           0 :     integer(i4), dimension(:), allocatable :: dims
    5106           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    5107           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    5108             :     integer(i4) :: i         ! loop indices
    5109           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    5110           0 :     real(sp), dimension(1) :: dummy     ! dummy read
    5111             :     logical :: openfile  ! tmp logical
    5112             :     !
    5113           0 :     ndim = size(dnames, 1)
    5114           0 :     d_unlimit = 0_i4
    5115           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    5116             :     ! consistency checks
    5117           0 :     if (ndim .gt. ndim_const) then
    5118           0 :       print *, '***ERROR more than five dimension names given'
    5119           0 :       stop '***ERROR see StdOut'
    5120             :     end if
    5121           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    5122             :             (d_unlimit .lt. 0_i4)) then
    5123           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    5124           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    5125           0 :       stop '***ERROR see StdOut'
    5126             :     end if
    5127             :     !
    5128           0 :     allocate(chunksizes(ndim))
    5129           0 :     allocate(start(ndim))
    5130           0 :     allocate(counter(ndim))
    5131           0 :     allocate(dims(ndim))
    5132           0 :     allocate(dimid(ndim))
    5133           0 :     allocate(varid(1 + ndim))
    5134           0 :     allocate(dummy_count(ndim))
    5135             :     ! initialize
    5136           0 :     deflate = 1
    5137           0 :     chunksizes = (/ size(arr, 1), size(arr, 2), size(arr, 3), size(arr, 4), size(arr, 5) /)
    5138           0 :     if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    5139           0 :     dims(1 : ndim) = shape(arr)
    5140           0 :     start(:) = 1_i4
    5141           0 :     counter(:) = dims
    5142           0 :     dummy_count = 1_i4
    5143           0 :     dummy = nf90_fill_float
    5144           0 :     d_unlimit = 0_i4
    5145           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    5146             :     ! open the netcdf file
    5147           0 :     if (present(ncid)) then
    5148           0 :       if (ncid < 0_i4) then
    5149             :         openfile = .true.
    5150             :       else
    5151           0 :         openfile = .false.
    5152           0 :         f_handle = ncid
    5153             :       end if
    5154             :     else
    5155             :       openfile = .true.
    5156             :     end if
    5157             :     if (openfile) then
    5158           0 :       create_loc = .false.
    5159           0 :       if (present(create)) create_loc = create
    5160           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    5161             :     end if
    5162             :     ! check whether variable exists
    5163           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    5164             :       ! append
    5165           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    5166             :       ! consistency checks
    5167           0 :       if (idim .ne. ndim) stop "var2nc_5d_sp: number of variable dimensions /= number of file variable dimensions."
    5168             :       ! check unlimited dimension
    5169           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    5170           0 :       if (u_dimid .eq. -1) stop 'var2nc_5d_sp: cannot append, no unlimited dimension defined'
    5171             :       ! check for unlimited dimension
    5172           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_5d_sp: unlimited dimension not specified correctly'
    5173           0 :       if (present(nrec)) then
    5174           0 :         start(d_unlimit) = nrec
    5175             :       else
    5176             :         ! get length of unlimited dimension
    5177           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    5178             :         ! adapt start, that is find last written chunk
    5179           0 :         do i = u_len, 1, -1
    5180           0 :           if (ne(dummy(1), nf90_fill_float)) exit
    5181           0 :           start(d_unlimit) = i
    5182           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    5183             :         end do
    5184           0 :         start(d_unlimit) = start(d_unlimit) + 1
    5185             :       end if
    5186             :     else
    5187             :       ! define dimensions
    5188           0 :       do i = 1, ndim
    5189             :         ! check whether dimension exists
    5190           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    5191             :           ! create dimension
    5192           0 :           if (i .eq. d_unlimit) then
    5193             :             ! define unlimited dimension
    5194           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    5195             :           else
    5196             :             ! define limited dimension
    5197           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    5198             :           end if
    5199             :         end if
    5200             :       end do
    5201             :       ! define variable
    5202           0 :       call check(nf90_def_var(f_handle, v_name, NF90_FLOAT, dimid, varid(ndim + 1), &
    5203           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    5204             :       ! add attributes
    5205           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    5206           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    5207           0 :       if (present(missing_value)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'missing_value', missing_value))
    5208           0 :       if (present(attributes)) then
    5209           0 :         do i = 1, size(attributes, dim = 1)
    5210           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    5211             :             ! write number
    5212           0 :             read(attributes(i, 2), '(F10.2)') dummy(1)
    5213           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    5214           0 :                     trim(attributes(i, 1)), dummy(1)))
    5215             :           else
    5216             :             ! write string
    5217           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    5218           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    5219             :           end if
    5220             :         end do
    5221             :       end if
    5222             :       ! end definition
    5223           0 :       call check(nf90_enddef(f_handle))
    5224             :     end if
    5225             :     ! check dimensions before writing
    5226           0 :     do i = 1, ndim_const
    5227           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    5228           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    5229           0 :               stop "var2nc_5d_sp: dimension name problem."
    5230           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    5231           0 :               stop "var2nc_5d_sp: variable dimension /= file variable dimension."
    5232             :     end do
    5233             :     ! write variable
    5234           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    5235             :     ! close netcdf_dataset
    5236           0 :     if (present(ncid)) then
    5237           0 :       if (ncid < 0_i4) ncid = f_handle
    5238             :     else
    5239           0 :       call close_netcdf(f_handle)
    5240             :     end if
    5241             :     !
    5242           0 :   end subroutine var2nc_5d_sp
    5243             : 
    5244           0 :   subroutine var2nc_5d_dp(f_name, arr, dnames, v_name, dim_unlimited, &
    5245           0 :           long_name, units, missing_value, attributes, create, ncid, nrec)
    5246             :     !
    5247             :     implicit none
    5248             :     !
    5249             :     integer(i4), parameter :: ndim_const = 5
    5250             :     integer(i4) :: ndim
    5251             :     ! input variables
    5252             :     character(len = *), intent(in) :: f_name
    5253             :     real(dp), dimension(:, :, :, :, :), intent(in) :: arr
    5254             :     character(len = *), intent(in) :: v_name
    5255             :     character(len = *), dimension(:), intent(in) :: dnames
    5256             :     ! optional
    5257             :     integer(i4), optional, intent(in) :: dim_unlimited
    5258             :     character(len = *), optional, intent(in) :: long_name
    5259             :     character(len = *), optional, intent(in) :: units
    5260             :     real(dp), optional, intent(in) :: missing_value
    5261             :     character(256), dimension(:, :), optional, intent(in) :: attributes
    5262             :     logical, optional, intent(in) :: create
    5263             :     integer(i4), optional, intent(inout) :: ncid
    5264             :     integer(i4), optional, intent(in) :: nrec
    5265             :     ! local variables
    5266             :     logical :: create_loc
    5267             :     character(256) :: dummy_name
    5268             :     integer(i4) :: deflate
    5269           0 :     integer(i4), dimension(:), allocatable :: chunksizes
    5270           0 :     integer(i4), dimension(:), allocatable :: start     ! start array for write
    5271           0 :     integer(i4), dimension(:), allocatable :: counter   ! length array for write
    5272             :     integer(i4) :: idim      ! read dimension on append
    5273             :     integer(i4) :: f_handle
    5274             :     integer(i4) :: d_unlimit ! index of unlimited dimension
    5275             :     integer(i4) :: u_dimid   ! dimid of unlimited dimension
    5276             :     integer(i4) :: u_len     ! length of unlimited dimension
    5277           0 :     integer(i4), dimension(:), allocatable :: dims
    5278           0 :     integer(i4), dimension(:), allocatable :: dimid     ! netcdf IDs of each dimension
    5279           0 :     integer(i4), dimension(:), allocatable :: varid     ! dimension variables and var id
    5280             :     integer(i4) :: i         ! loop indices
    5281           0 :     integer(i4), dimension(:), allocatable :: dummy_count
    5282           0 :     real(dp), dimension(1) :: dummy     ! dummy read
    5283             :     logical :: openfile  ! tmp logical
    5284             :     !
    5285           0 :     ndim = size(dnames, 1)
    5286           0 :     d_unlimit = 0_i4
    5287           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    5288             :     ! consistency checks
    5289           0 :     if (ndim .gt. ndim_const) then
    5290           0 :       print *, '***ERROR more than five dimension names given'
    5291           0 :       stop '***ERROR see StdOut'
    5292             :     end if
    5293           0 :     if  (((ndim .eq. ndim_const) .and. (d_unlimit .gt. ndim_const)) .or. &
    5294             :             (d_unlimit .lt. 0_i4)) then
    5295           0 :       print*, '***ERROR unlimited dimension out of bounds, must be positive but not greater than number of given dimensions'
    5296           0 :       print*, '***Dims: ', ndim, ndim_const, d_unlimit, ndim_const, d_unlimit
    5297           0 :       stop '***ERROR see StdOut'
    5298             :     end if
    5299             :     !
    5300           0 :     allocate(chunksizes(ndim))
    5301           0 :     allocate(start(ndim))
    5302           0 :     allocate(counter(ndim))
    5303           0 :     allocate(dims(ndim))
    5304           0 :     allocate(dimid(ndim))
    5305           0 :     allocate(varid(1 + ndim))
    5306           0 :     allocate(dummy_count(ndim))
    5307             :     ! initialize
    5308           0 :     deflate = 1
    5309           0 :     chunksizes = (/ size(arr, 1), size(arr, 2), size(arr, 3), size(arr, 4), size(arr, 5) /)
    5310           0 :     if (d_unlimit .gt. 0) chunksizes(d_unlimit) = 1
    5311           0 :     dims(1 : ndim) = shape(arr)
    5312           0 :     start(:) = 1_i4
    5313           0 :     counter(:) = dims
    5314           0 :     dummy_count = 1
    5315           0 :     dummy = nf90_fill_double
    5316           0 :     d_unlimit = 0_i4
    5317           0 :     if (present(dim_unlimited)) d_unlimit = dim_unlimited
    5318             :     ! open the netcdf file
    5319           0 :     if (present(ncid)) then
    5320           0 :       if (ncid < 0_i4) then
    5321             :         openfile = .true.
    5322             :       else
    5323           0 :         openfile = .false.
    5324           0 :         f_handle = ncid
    5325             :       end if
    5326             :     else
    5327             :       openfile = .true.
    5328             :     end if
    5329             :     if (openfile) then
    5330           0 :       create_loc = .false.
    5331           0 :       if (present(create)) create_loc = create
    5332           0 :       f_handle = open_netcdf(f_name, create = create_loc)
    5333             :     end if
    5334             :     ! check whether variable exists
    5335           0 :     if (nf90_noerr .eq. nf90_inq_varid(f_handle, v_name, varid(ndim + 1))) then
    5336             :       ! append
    5337           0 :       call check(nf90_inquire_variable(f_handle, varid(ndim + 1), ndims = idim, dimids = dimid))
    5338             :       ! consistency checks
    5339           0 :       if (idim .ne. ndim) stop "var2nc_5d_dp: number of variable dimensions /= number of file variable dimensions."
    5340             :       ! check unlimited dimension
    5341           0 :       call check(nf90_inquire(f_handle, unlimitedDimId = u_dimid))
    5342           0 :       if (u_dimid .eq. -1) stop 'var2nc_5d_dp: cannot append, no unlimited dimension defined'
    5343             :       ! check for unlimited dimension
    5344           0 :       if (dimid(d_unlimit) .ne. u_dimid) stop 'var2nc_5d_dp: unlimited dimension not specified correctly'
    5345           0 :       if (present(nrec)) then
    5346           0 :         start(d_unlimit) = nrec
    5347             :       else
    5348             :         ! get length of unlimited dimension
    5349           0 :         call check(nf90_inquire_dimension(f_handle, u_dimid, len = u_len))
    5350             :         ! adapt start, that is find last written chunk
    5351           0 :         do i = u_len, 1, -1
    5352           0 :           if (ne(dummy(1), nf90_fill_double)) exit
    5353           0 :           start(d_unlimit) = i
    5354           0 :           call check(nf90_get_var(f_handle, varid(ndim + 1), dummy, start, dummy_count))
    5355             :         end do
    5356           0 :         start(d_unlimit) = start(d_unlimit) + 1
    5357             :       end if
    5358             :     else
    5359             :       ! define dimensions
    5360           0 :       do i = 1, ndim
    5361             :         ! check whether dimension exists
    5362           0 :         if (nf90_noerr .ne. nf90_inq_dimid(f_handle, dnames(i), dimid(i))) then
    5363             :           ! create dimension
    5364           0 :           if (i .eq. d_unlimit) then
    5365             :             ! define unlimited dimension
    5366           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), NF90_UNLIMITED, dimid(i)))
    5367             :           else
    5368             :             ! define limited dimension
    5369           0 :             call check(nf90_def_dim(f_handle, trim(dnames(i)), dims(i), dimid(i)))
    5370             :           end if
    5371             :         end if
    5372             :       end do
    5373             :       ! define variable
    5374           0 :       call check(nf90_def_var(f_handle, v_name, NF90_DOUBLE, dimid, varid(ndim + 1), &
    5375           0 :               chunksizes = chunksizes(:), shuffle = .true., deflate_level = deflate))
    5376             :       ! add attributes
    5377           0 :       if (present(long_name)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'long_name', long_name))
    5378           0 :       if (present(units)) call check(nf90_put_att (f_handle, varid(ndim + 1), 'units', units))
    5379           0 :       if (present(missing_value)) call check(nf90_put_att(f_handle, varid(ndim + 1), 'missing_value', missing_value))
    5380           0 :       if (present(attributes)) then
    5381           0 :         do i = 1, size(attributes, dim = 1)
    5382           0 :           if (trim(attributes(i, 1)) .eq. 'missing_value') then
    5383             :             ! write number
    5384           0 :             read(attributes(i, 2), '(F10.2)') dummy(1)
    5385           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    5386           0 :                     trim(attributes(i, 1)), dummy(1)))
    5387             :           else
    5388             :             ! write string
    5389           0 :             call check(nf90_put_att(f_handle, varid(ndim + 1), &
    5390           0 :                     trim(attributes(i, 1)), trim(attributes(i, 2))))
    5391             :           end if
    5392             :         end do
    5393             :       end if
    5394             :       ! end definition
    5395           0 :       call check(nf90_enddef(f_handle))
    5396             :     end if
    5397             :     ! check dimensions before writing
    5398           0 :     do i = 1, ndim_const
    5399           0 :       call check(nf90_inquire_dimension(f_handle, dimid(i), dummy_name, dims(i)))
    5400           0 :       if (trim(dummy_name) .ne. dnames(i)) &
    5401           0 :               stop "var2nc_5d_dp: dimension name problem."
    5402           0 :       if ((dims(i) .ne. size(arr, i)) .and. (d_unlimit .ne. i)) &
    5403           0 :               stop "var2nc_5d_dp: variable dimension /= file variable dimension."
    5404             :     end do
    5405             :     ! write variable
    5406           0 :     call check(nf90_put_var(f_handle, varid(ndim + 1), arr, start, counter))
    5407             :     ! close netcdf_dataset
    5408           0 :     if (present(ncid)) then
    5409           0 :       if (ncid < 0_i4) ncid = f_handle
    5410             :     else
    5411           0 :       call close_netcdf(f_handle)
    5412             :     end if
    5413             :     !
    5414           0 :   end subroutine var2nc_5d_dp
    5415             : 
    5416             :   ! ----------------------------------------------------------------------------
    5417             :   !>     \brief dynamic writer
    5418             :   !>     \details This routine writes data, where one dimension has the unlimited attribute.
    5419             :   !!     Therefore, the number of the record which should be written has to be
    5420             :   !!     specified.
    5421             :   !!     See: http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-f90.html
    5422             : 
    5423             :   !>     \param[in] "integer(i4) :: nc"  stream id of an open netcdf file where data should be written
    5424             :   !!                                     can be obtained by an create_netcdf call
    5425             :   !>     \param[in] "integer(i4) :: rec" record id of record which will be written in the file
    5426             : 
    5427             :   !>     \note Writes only data, where the data pointers of the structure V are assigned
    5428             :   !!     and where one dimension has the unlimited attribute. Moreover only one
    5429             :   !!     record will be written.
    5430             :   !!     Writes only 1 to 4 dim arrays, integer, single or double precision.
    5431             : 
    5432             :   !>     \author Luis Samaniego
    5433             :   !>     \date Feb 2011
    5434             :   !>     \author Stephan Thober
    5435             :   !>     \date Dec 2011
    5436             :   !!           - added comments and generalized
    5437             :   !>     \author Matthias Cuntz
    5438             :   !>     \date Jan 2012
    5439             :   !!           - Info
    5440             :   !>     \author Stephan Thober
    5441             :   !>     \date Jan 2012
    5442             :   !!           - iRec is not optional
    5443             :   !>     \author Matthias Cuntz
    5444             :   !>     \date Mar 2013
    5445             :   !!           - removed Info
    5446           0 :   subroutine write_dynamic_netcdf(ncId, irec)
    5447             : 
    5448             :     implicit none
    5449             : 
    5450             :     ! netcdf related variables
    5451             :     integer(i4), intent(in) :: ncId
    5452             :     integer(i4), intent(in) :: iRec
    5453             : 
    5454             :     integer(i4) :: i
    5455             :     ! NOTES: 1) netcdf file must be on *** data mode ***
    5456             :     !        2) start and end of the data chuck is controled by
    5457             :     !           V(:)%start and  V(:)%count
    5458             : 
    5459             :     ! set values for variables (one scalar or grid at a time)
    5460             : 
    5461           0 :     do i = 1, nVars
    5462           0 :       if (.not. V(i)%unlimited) cycle
    5463           0 :       if (.not. V(i)%wFlag) cycle
    5464           0 :       V(i)%start (V(i)%nDims) = iRec
    5465           0 :       select case (V(i)%xtype)
    5466             :       case(NF90_BYTE)
    5467           0 :         select case (V(i)%nDims)
    5468             :         case (0)
    5469           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G0_b, V(i)%start))
    5470             :         case (1)
    5471           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G1_b, V(i)%start, V(i)%count))
    5472             :         case (2)
    5473           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G2_b, V(i)%start, V(i)%count))
    5474             :         case (3)
    5475           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G3_b, V(i)%start, V(i)%count))
    5476             :         case (4)
    5477           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G4_b, V(i)%start, V(i)%count))
    5478             :         end select
    5479             :       case (NF90_INT)
    5480           0 :         select case (V(i)%nDims - 1)
    5481             :         case (0)
    5482           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G0_i, V(i)%start))
    5483             :         case (1)
    5484           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G1_i, V(i)%start, V(i)%count))
    5485             :         case (2)
    5486           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G2_i, V(i)%start, V(i)%count))
    5487             :         case (3)
    5488           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G3_i, V(i)%start, V(i)%count))
    5489             :         case (4)
    5490           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G4_i, V(i)%start, V(i)%count))
    5491             :         end select
    5492             :       case (NF90_FLOAT)
    5493           0 :         select case (V(i)%nDims - 1)
    5494             :         case (0)
    5495           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G0_f, V(i)%start))
    5496             :         case (1)
    5497           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G1_f, V(i)%start, V(i)%count))
    5498             :         case (2)
    5499           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G2_f, V(i)%start, V(i)%count))
    5500             :         case (3)
    5501           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G3_f, V(i)%start, V(i)%count))
    5502             :         case (4)
    5503           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G4_f, V(i)%start, V(i)%count))
    5504             :         end select
    5505             :       case (NF90_DOUBLE)
    5506           0 :         select case (V(i)%nDims - 1)
    5507             :         case (0)
    5508           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G0_d, V(i)%start))
    5509             :         case (1)
    5510           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G1_d, V(i)%start, V(i)%count))
    5511             :         case (2)
    5512           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G2_d, V(i)%start, V(i)%count))
    5513             :         case (3)
    5514           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G3_d, V(i)%start, V(i)%count))
    5515             :         case (4)
    5516           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G4_d, V(i)%start, V(i)%count))
    5517             :         end select
    5518             :       end select
    5519             :     end do
    5520             : 
    5521           0 :   end subroutine write_dynamic_netcdf
    5522             : 
    5523             :   ! ----------------------------------------------------------------------------
    5524             :   !>     \brief static writer
    5525             :   !>     \details This routines writes static data in the netcdf file that is data
    5526             :   !!     where no dimension has the unlimited attribute.
    5527             :   !!     See: http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-f90.html
    5528             : 
    5529             :   !>     \param[in] "integer(i4) :: ncid" stream id of an open netcdf file where data should be written
    5530             :   !!                                      can be obtained by an create_netcdf call
    5531             : 
    5532             :   !>     \note Writes only data, where the data pointers of the structure V are assigned.
    5533             :   !!     Writes only 1 to 4 dim arrays, integer, single or double precision.
    5534             : 
    5535             :   ! HISTORY
    5536             :   !>     \author Luis Samaniego
    5537             :   !>     \date Feb 2011
    5538             :   !>     \author Stephan Thober
    5539             :   !>     \date Dec 2011
    5540             :   !!           - added comments and generalized
    5541             :   !>     \author Matthias Cuntz
    5542             :   !>     \date Jan 2012
    5543             :   !!           - Info
    5544             :   !>     \author Matthias Cuntz
    5545             :   !>     \date Mar 2013
    5546             :   !!           - removed Info
    5547             : 
    5548           0 :   subroutine write_static_netcdf(ncId)
    5549             : 
    5550             :     implicit none
    5551             : 
    5552             :     ! netcdf related variables
    5553             :     integer(i4), intent(in) :: ncId
    5554             : 
    5555             :     integer(i4) :: i
    5556             : 
    5557             :     ! write all static variables
    5558           0 :     do i = 1, nVars
    5559           0 :       if (V(i)%unlimited) cycle
    5560           0 :       if (.not. V(i)%wFlag) cycle
    5561           0 :       select case (V(i)%xtype)
    5562             :       case(NF90_BYTE)
    5563           0 :         select case (V(i)%nDims)
    5564             :         case (0)
    5565           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G0_b))
    5566             :         case (1)
    5567           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G1_b))
    5568             :         case (2)
    5569           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G2_b))
    5570             :         case (3)
    5571           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G3_b))
    5572             :         case (4)
    5573           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G4_b))
    5574             :         end select
    5575             :       case (NF90_INT)
    5576           0 :         select case (V(i)%nDims)
    5577             :         case (0)
    5578           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G0_i))
    5579             :         case (1)
    5580           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G1_i))
    5581             :         case (2)
    5582           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G2_i))
    5583             :         case (3)
    5584           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G3_i))
    5585             :         case (4)
    5586           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G4_i))
    5587             :         end select
    5588             :       case (NF90_FLOAT)
    5589           0 :         select case (V(i)%nDims)
    5590             :         case (0)
    5591           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G0_f))
    5592             :         case (1)
    5593           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G1_f))
    5594             :         case (2)
    5595           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G2_f))
    5596             :         case (3)
    5597           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G3_f))
    5598             :         case (4)
    5599           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G4_f))
    5600             :         end select
    5601             :       case (NF90_DOUBLE)
    5602           0 :         select case (V(i)%nDims)
    5603             :         case (0)
    5604           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G0_d))
    5605             :         case (1)
    5606           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G1_d))
    5607             :         case (2)
    5608           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G2_d))
    5609             :         case (3)
    5610           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G3_d))
    5611             :         case (4)
    5612           0 :           call check(nf90_put_var(ncId, V(i)%varId, V(i)%G4_d))
    5613             :         end select
    5614             :       end select
    5615             :     end do
    5616             : 
    5617           0 :   end subroutine write_static_netcdf
    5618             : 
    5619             :   ! -----------------------------------------------------------------------------
    5620             :   ! PRIVATE PART
    5621             :   !
    5622             : 
    5623             :   ! -----------------------------------------------------------------------------
    5624             : 
    5625             :   ! private open netcdf function - returns file handle
    5626           0 :   function open_netcdf(f_name, create)
    5627             :     implicit none
    5628             :     ! input variables
    5629             :     character(len = *), intent(in) :: f_name
    5630             :     logical, intent(in) :: create ! flag indicates that file exists
    5631             :     ! output variables
    5632             :     integer(i4) :: open_netcdf
    5633             :     !
    5634           0 :     if (create) then
    5635             :       ! create file
    5636           0 :       call check(nf90_create(trim(f_name), NF90_NETCDF4, open_netcdf))
    5637             :     else
    5638             :       ! open file
    5639           0 :       call check(nf90_open(trim(f_name), NF90_WRITE, open_netcdf))
    5640             :     end if
    5641           0 :   end function open_netcdf
    5642             : 
    5643             : 
    5644             :   ! -----------------------------------------------------------------------------
    5645             : 
    5646             :   !  private error checking routine
    5647         240 :   subroutine check(status)
    5648             : 
    5649             :     implicit none
    5650             : 
    5651             :     integer(i4), intent(in) :: status
    5652             : 
    5653         240 :     if (status /= nf90_noerr) then
    5654           0 :       write(*, *) 'mo_ncwrite.check error: ', trim(nf90_strerror(status))
    5655           0 :       stop
    5656             :     end if
    5657             : 
    5658           0 :   end subroutine check
    5659             : 
    5660             :   ! -----------------------------------------------------------------------------
    5661             : 
    5662         240 : end module mo_ncwrite

Generated by: LCOV version 1.16