!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! - Ariane - (May - 2007)
!!
!! bruno.blanke@univ-brest.fr and nicolas.grima@univ-brest.fr
!!
!! This software is a computer program whose purpose is
!! the computation of 3D streamlines in a given velocity field
!! (as the output of an Ocean General Circulation Model) and
!! subsequent water masses analyses.
!!
!! This software is governed by the CeCILL license under French law and
!! abiding by the rules of distribution of free software. You can use,
!! modify and/ or redistribute the software under the terms of the CeCILL
!! license as circulated by CEA, CNRS and INRIA at the following URL
!! "http://www.cecill.info".
!!
!! As a counterpart to the access to the source code and rights to copy,
!! modify and redistribute granted by the license, users are provided only
!! with a limited warranty and the software's author, the holder of the
!! economic rights, and the successive licensors have only limited
!! liability.
!!
!! In this respect, the user's attention is drawn to the risks associated
!! with loading, using, modifying and/or developing or reproducing the
!! software by the user in light of its specific status of free software,
!! that may mean that it is complicated to manipulate, and that also
!! therefore means that it is reserved for developers and experienced
!! professionals having in-depth computer knowledge. Users are therefore
!! encouraged to load and test the software's suitability as regards their
!! requirements in conditions enabling the security of their systems and/or
!! data to be ensured and, more generally, to use and operate it in the
!! same conditions as regards security.
!!
!! The fact that you are presently reading this means that you have had
!! knowledge of the CeCILL license and that you accept its terms.
!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!****h* ariane/mod_netcdf
!! NAME
!! mod_netcdf (mod_netcdf.f90 - Fortran90 module)
!!
!! USAGE
!! Include 'USE mod_netcdf' in the header of your Fortran 90 source
!! code.
!! Then you'll have access to the subroutine:
!! - sub_build_filename
!! - sub_open_netcdf_file
!! - sub_close_netcdf_file
!! - sub_read_netcdf_varid_ndims
!! - sub_read_netcdf_var_dims
!! - sub_select_var_dims
!! - sub_read_netcdf_var4d
!! - sub_read_netcdf_att_info
!! -
!!
!! FUNCTION
!! Netcdf subroutine to Ariane application.
!!
!! AUTHOR
!! * Origin : Bruno Blanke (1992)
!! * F77toF90: Nicolas Grima (April-May 2005)
!!
!! CREATION DATE
!! * April-May 2005
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! RESULT
!!
!!
!! EXAMPLES
!!
!!
!! NOTES
!! ROBODoc header style.
!!
!! TODO
!!
!!
!! PORTABILITY
!! Machine-OS - Fortran90/95 compiler
!! * i686-pc-linux-gnu - ifort
!! * i686-pc-linux-gnu - g95
!!
!! SEE ALSO
!!
!!
!! USES
!! * USE mod_precision
!! * USE mod_namelist
!! * USE netcdf
!!
!! USED BY
!! * mod_input_data.f90
!! * mod_input_grid.f90
!!
!! SOURCE
!!=========================================================================
MODULE mod_netcdf 3,3
!------------------!
! USE ASSOCIAITION !
!------------------!
USE mod_precision
USE mod_memory
USE mod_namelist
USE netcdf
USE mod_reducmem
!!NG: 19 06 2009
REAL(kind = rprec), DIMENSION(:) , ALLOCATABLE :: dumtab1d
REAL(kind = rprec), DIMENSION(:,:) , ALLOCATABLE :: dumtab2d
REAL(kind = rprec), DIMENSION(:,:,:) , ALLOCATABLE :: dumtab3d
REAL(kind = rprec), DIMENSION(:,:,:,:), ALLOCATABLE :: dumtab4d
!!***
CONTAINS
!=========================================================================
!!****f* mod_netcdf/sub_build_filename()
!! NAME
!! sub_build_filename()
!!
!! FUNCTION
!! Build file name with namelist parameters.
!! We assume that netcdf file_name are build on this form:
!! netcdf file_name = prefix_XXXX_suffix
!! Where XXXX, is an integer from "ind0" to "indn" on "ndigits" (here 4).
!!
!! AUTHOR
!! * Origin : Nicolas Grima (April-May 2005)
!!
!! CREATION DATE
!! * April-May 2005
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * Input:
!! - ind : an integer epresenting the netcdf file number
!! - maxsize : number of digits on which "ind is represented
!! - c_prefix: first part of the netcdf file name
!! - c_suffix: last part of the netcdf file name
!! * Output:
!! - c_filename: the netcdf file_name
!!
!! TODO
!!
!!
!! USED BY
!! * mod_input_data.f90
!! * mod_input_grid.f90
!!
!! SOURCE
!!=======================================================================
SUBROUTINE sub_build_filename(ind, maxsize, c_prefix, c_suffix, c_filename) 12
!-------------!
! Declaration !
!-------------!
!- arguments -!
INTEGER(kind=iprec), INTENT(in) :: ind, maxsize
CHARACTER(len=*) , INTENT(in) :: c_prefix, c_suffix
CHARACTER(len=*) , INTENT(out) :: c_filename
!- local variables -!
CHARACTER(len=4), PARAMETER :: c_none='NONE'
CHARACTER(len=14) :: cmft
!-------------!
! Code begins !
!-------------!
!- Test if the netcdf filename has a number -!
!- ind == -1 means that there's a single netcdf file -!
!- Each case is represented :
!- - netcdf file name = prefix
!- - netcdf file name = suffix
!- - netcdf file name = prefix suffix
!- ind /= -1 means that the netcdf file has a number -!
!- Each case is represented :
!- - netcdf file name = prefix ind suffix
!- - netcdf file name = ind suffix
!- - netcdf file name = prefix ind
IF (ind < 0) THEN
IF ((c_prefix /= c_none ).AND.(c_suffix == c_none)) THEN
c_filename = TRIM(c_prefix)
ELSEIF ((c_prefix == c_none ).AND.(c_suffix /= c_none)) THEN
c_filename = TRIM(c_suffix)
ELSEIF((c_prefix /= c_none ).AND.(c_suffix /= c_none)) THEN
c_filename = TRIM(c_prefix) // TRIM(c_suffix)
ELSE
WRITE(lun_error,*)'mod_netcdf: build_filename: error', ind, c_prefix, c_suffix
STOP
ENDIF
ELSE
IF ((c_prefix /= c_none ).AND.(c_suffix /= c_none)) THEN
WRITE(cmft , 1101) maxsize, maxsize
WRITE(c_filename, FMT=cmft) TRIM(c_prefix), ind, TRIM(c_suffix)
ELSEIF ((c_prefix == c_none ).AND.(c_suffix /= c_none)) THEN
WRITE(cmft , 1102) maxsize, maxsize
WRITE(c_filename, FMT=cmft) ind, TRIM(c_suffix)
ELSEIF ((c_prefix /= c_none ).AND.(c_suffix == c_none)) THEN
WRITE(cmft , 1103) maxsize, maxsize
WRITE(c_filename, FMT=cmft) TRIM(c_prefix), ind
ELSE
WRITE(lun_error,*)'mod_netcdf: build_filename: error', ind, c_prefix, c_suffix
STOP
ENDIF
ENDIF
!- Formats -!
!- For example: I5.5 means that integer will represented on 5 digits -!
!- zero value are added to complete digits -!
1101 FORMAT('(A, I', I2, '.', I2, ', A)')
1102 FORMAT('(I' , I2, '.', I2, ', A)')
1103 FORMAT('(A, I', I2, '.', I2, ')')
END SUBROUTINE sub_build_filename
!!***
!=========================================================================
!!****f* mod_netcdf/sub_open_netcdf_file()
!! NAME
!! sub_open_netcdf_file()
!!
!! FUNCTION
!! Open a netcdf file.
!! !! Netcdf version 3.6.0 or newer is required for F90 calls !!
!!
!! AUTHOR
!! * Origin : Nicolas Grima (April-May 2005)
!!
!! CREATION DATE
!! * April-May 2005
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * INPUTS:
!! - c_dir : the directory where the netcdf file is.
!! - c_filename: the netcdf file name.
!! * OUTPUT:
!! - ncid : return the netcdf file ID.
!!
!! TODO
!!
!!
!! USED BY
!! * mod_input_data.f90
!! * mod_input_grid.f90
!!
!! SOURCE
!!=======================================================================
SUBROUTINE sub_open_netcdf_file(c_dir, c_filename, ncid) 13
!-------------!
! Declaration !
!-------------!
!- arguments -!
CHARACTER(len = *) , INTENT(in) :: c_dir, c_filename
INTEGER(kind = iprec), INTENT(out) :: ncid
!- local variables -!
INTEGER(kind = ishort) :: is_err
!-------------!
! Code begins !
!-------------!
!- Netcdf call -!
is_err = nf90_open( &
path = TRIM(c_dir)//'/'//TRIM(c_filename), &
mode = nf90_nowrite , &
ncid = ncid &
)
!- Test if there's a problem -!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_open_netcdf_file: problem to open netcdf file!'
WRITE(lun_error,*) ' path = ', TRIM(c_dir)//'/'//TRIM(c_filename)
STOP
ELSE
WRITE(*,*)''
WRITE(*,*)'-> Netcdf File - Successful Opening -', &
TRIM(c_dir)//'/'//TRIM(c_filename), ' - ncid = ', ncid
ENDIF
END SUBROUTINE sub_open_netcdf_file
!!***
!========================================================================
!=========================================================================
!!****f* mod_netcdf/sub_close_netcdf_file()
!! NAME
!! sub_close_netcdf_file()
!!
!! FUNCTION
!! Close a netcdf file.
!! !! Netcdf version 3.6.0 or newer is required for F90 calls !!
!!
!! AUTHOR
!! * Origin : Nicolas Grima (April-May 2005)
!!
!! CREATION DATE
!! * April-May 2005
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * ncid (input): the netcdf file ID
!!
!! TODO
!!
!!
!! USED BY
!! * mod_input_data.f90
!! * mod_input_grid.f90
!!
!! SOURCE
!!=======================================================================
SUBROUTINE sub_close_netcdf_file(ncid) 16
!-------------!
! Declaration !
!-------------!
!- arguments -!
INTEGER(kind=iprec), INTENT(in) :: ncid
!- local variables -!
INTEGER(kind=ishort) :: is_err
!-------------!
! Code begins !
!-------------!
!- Netcdf call -!
is_err = nf90_close(ncid = ncid)
!- Test if there's a problem -!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_close_netcdf_file: problem to close netcdf file!'
WRITE(lun_error,*) ' ncid = ', ncid
STOP
ELSE
WRITE(*,*)'-> Netcdf File - Successful Closing - ncid =', ncid
WRITE(*,*)''
ENDIF
END SUBROUTINE sub_close_netcdf_file
!!***
!========================================================================
!=========================================================================
!!****f* mod_netcdf/sub_read_netcdf_varid_ndims()
!! NAME
!! sub_read_netcdf_varid_ndims()
!!
!! FUNCTION
!! Inquire netcdf variable ID and dims
!!
!! AUTHOR
!! * Origin : Nicolas Grima (April-May 2005)
!!
!! CREATION DATE
!! * April-May 2005
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * Inputs:
!! - ncid : netcdf file ID
!! - nc_var: netcdf avriable name
!! * Outputs:
!! - varid : netcdf variable ID
!! - ndims : netcdf variable dimension number
!!
!! TODO
!!
!! USES
!! * nf90_inq_varid (Netcdf lib 3.6.x or newer)
!! * nf90_inquire_variable (Netcdf lib 3.6.x or newer)
!!
!! USED BY
!! * mod_netcdf (Private)
!!
!! SOURCE
!!=======================================================================
SUBROUTINE sub_read_netcdf_varid_ndims(ncid, nc_var, varid, ndims) 19
!-------------!
! Declaration !
!-------------!
!- arguments -!
INTEGER(kind=iprec), INTENT(in) :: ncid
CHARACTER(len= *) , INTENT(in) :: nc_var
INTEGER(kind=iprec), INTENT(out) :: varid
INTEGER(kind=iprec), OPTIONAL, INTENT(out) :: ndims
!- local variables -!
INTEGER(kind=ishort) :: is_err
!-------------!
! Code begins !
!-------------!
!-------------!
!- Get varid -!
!-------------!
is_err = nf90_inq_varid( &
ncid = ncid , &
name = TRIM(nc_var) , &
varid = varid &
)
!- Test problem or error -!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*)'mod_netcdf: sub_read_netcdf_varid_ndims: netcdf variable name problem!'
WRITE(lun_error,*)' ncid = ', ncid
WRITE(lun_error,*)' name = ', TRIM(nc_var)
WRITE(lun_error,*)' varid = ', varid
STOP
ENDIF
!------------------------------------!
!- Get variable number of dimension -!
!------------------------------------!
IF (present(ndims)) THEN
is_err = nf90_inquire_variable( &
ncid = ncid , &
varid = varid , &
ndims = ndims &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) &
STOP 'mod_netcdf: sub_read_netcdf_varid_ndims: netcdf variable ndims problem!'
ENDIF
END SUBROUTINE sub_read_netcdf_varid_ndims
!!***
!========================================================================
!=========================================================================
!!****f* mod_netcdf/sub_read_netcdf_var_dims()
!! NAME
!! sub_read_netcdf_var_dims()
!!
!! FUNCTION
!! Read netcdf variable dimension lengths from netcdf dimension ID.
!!
!! AUTHOR
!! * Origin : Nicolas Grima (April-May 2005)
!!
!! CREATION DATE
!! * April-May 2005
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * Inputs:
!! - ncid : netcdf file ID
!! - varid: netcdf variable ID
!! - ndims: netcdf variable dimension number
!! * Output:
!! - dims : netcdf variable dimensions
!!
!! TODO
!!
!! USES
!! * nf90_inquire_variable
!! * nf90_inquire_dimension
!!
!! USED BY
!! * mod_netcdf (Private)
!!
!! SOURCE
!!=======================================================================
SUBROUTINE sub_read_netcdf_var_dims(ncid, varid, ndims, dims) 2
!-------------!
! Declaration !
!-------------!
!- arguments -!
INTEGER(kind=iprec), INTENT(in) :: ncid, varid, ndims
INTEGER(kind=iprec), DIMENSION(:), INTENT(out):: dims
!- local variables -!
INTEGER(kind=ishort) :: is_err ! error code returns by netcdf function
INTEGER(kind=ishort) :: ii ! dummy variable for a DoLoop
! dimids: netcdf dimension ID. It necessary to have this information
! before to inquire each dimension length of a netcdf variable.
INTEGER(kind=ishort), DIMENSION(:), ALLOCATABLE :: dimids
!-------------!
! Code begins !
!-------------!
!----------------------!
!- Dynamic allocation -!
!----------------------!
ALLOCATE(dimids(ndims))
!!NG : 19 06 2009 CALL sub_memory(size(dimids),'i','dimids','sub_read_netcdf_var_dims')
!------------------------------!
!- Get variable dimension IDs -!
!------------------------------!
is_err = nf90_inquire_variable( &
ncid = ncid , &
varid = varid , &
dimids = dimids &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var_dims: problem to inquire variable!'
WRITE(lun_error,*) ' ncid = ', ncid
WRITE(lun_error,*) ' varid = ', varid
WRITE(lun_error,*) ' dimids = ', dimids
STOP
ENDIF
!-----------------------------------------------------!
!- For each dimension, get variable dimension length -!
!-----------------------------------------------------!
DO ii = 1, ndims
!------------------------!
!- Get dimension length -!
!------------------------!
is_err = nf90_inquire_dimension( &
ncid = ncid , &
dimid = dimids(ii) , &
len = dims(ii) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var_dims: problem to inquire dimension!'
WRITE(lun_error,*) ' ncid = ', ncid
WRITE(lun_error,*) ' ii = ', ii
WRITE(lun_error,*) ' dimid = ', dimids(ii)
WRITE(lun_error,*) ' len = ' , dims(ii)
STOP
ENDIF
ENDDO
!----------------------!
!- Deallocation -!
!----------------------!
!!NG : 19 06 2009 CALL sub_memory(-size(dimids),'i','dimids','sub_read_netcdf_var_dims')
DEALLOCATE(dimids)
END SUBROUTINE sub_read_netcdf_var_dims
!!***
!========================================================================
!!****f* mod_netcdf/sub_select_var_dims()
!! NAME
!! sub_select_var_dims()
!!
!! FUNCTION
!! Get netcdf variable dimension lengths, calls:
!! - sub_read_netcdf_varid_ndims
!! - sub_read_netcdf_var_dims
!! to do this.
!! And after compare these dimesion length with imt, jmt, kmt and lmt
!! and the order how there used (or stored) for a netcdf variable.
!!
!! Dimension order is very important to reorder netcdf 1d, 2d, 3d or 4d
!! arrays in the 4d Ariane arrays which have (imt, jmt, kmt, lmt)
!! dimension.
!!
!! EXAMPLES
!! * A netcdf variable has (imt, jmt, kmt, lmt) dimensions.
!! In this case:
!! - dimx = imt
!! - dimy = jmt
!! - dimz = kmt
!! - dimt = lmt
!! And: - dimsorder = /1,2,3,4/
!!
!! * A netcdf variable has (kmt,lmt) dimensions.
!! In this case:
!! - dimx = 1
!! - dimy = 1
!! - dimz = kmt
!! - dimt = lmt
!! And: - dimsorder = /0,0,1,2/
!!
!! * A netcdf variable has (imt, jmt, lmt) dimensions.
!! In this case:
!! - dimx = imt
!! - dimy = jmt
!! - dimz = 1
!! - dimt = lmt
!! And: - dimsorder = /1,2,0,3/
!!
!! * A netcdf variable has (imt, jmt, 1, lmt) dimensions.
!! In this case:
!! - dimx = imt
!! - dimy = jmt
!! - dimz = 1
!! - dimt = lmt
!! And: - dimsorder = /1,2,4,3/
!!
!! * A netcdf variable has (1, 1, kmt, 1) dimensions.
!! In this case:
!! - dimx = 1
!! - dimy = 1
!! - dimz = kmt
!! - dimt = 1
!! And: - dimsorder = /2,3,1,4/
!!
!!
!! AUTHOR
!! * Origin : Nicolas Grima (April-May 2005)
!!
!! CREATION DATE
!! * April-May 2005
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * Inputs:
!! - ncid : netcdf file ID
!! - nc_var_name: netcdf variable name
!!
!! * Outputs:
!! - varid : netcdf variable ID
!! - dimsorder: dimensions order (see below Examples)
!! - dimx : x dimension
!! - dimy : y dimension
!! - dimz : z dimension
!! - dimt : time dimension
!!
!! TODO
!!
!! USES
!! * sub_read_netcdf_varid_ndims
!! * sub_read_netcdf_var_dims
!!
!! USED BY
!! * mod_input_data.f90
!! * mod_input_grid.f90
!!
!! SOURCE
!!=======================================================================
SUBROUTINE sub_select_var_dims( & 52,2
ncid, nc_var_name, varid, dimsorder, &
dimx, dimy, dimz, dimt, key_ijt)
!-------------!
! Declaration !
!-------------!
!- arguments -!
INTEGER(kind = iprec), INTENT(in) :: ncid
CHARACTER(len = *) , INTENT(in) :: nc_var_name
INTEGER(kind = iprec), DIMENSION(4), INTENT(out) :: dimsorder
INTEGER(kind = iprec), INTENT(out) :: varid, dimx, dimy, dimz, dimt
LOGICAL , OPTIONAL :: key_ijt !! NG 05_10_2009
!- local variables -!
INTEGER(kind = iprec) :: ii ! dummy variable for a DoLoop
INTEGER(kind = iprec) :: ndims ! number of dimensions
INTEGER(kind = iprec) :: icnt
! dims: variable dimension lengths are stored in this array
INTEGER(kind = iprec), DIMENSION(:), ALLOCATABLE :: dims
INTEGER(kind = iprec), DIMENSION(4) :: sumdims, dumdims
!-------------!
! Code begins !
!-------------!
!-------------------!
!- Initializations -!
!-------------------!
dimsorder(:) = 0
dimx = 1
dimy = 1
dimz = 1
dimt = 1
icnt = 1 ! counter
!- Dimension sum -!
sumdims(1) = 1 ! 1+0+0+0
sumdims(2) = 3 ! 1+2+0+0
sumdims(3) = 6 ! 1+2+3+0
sumdims(4) = 10 ! 1+2+3+4
write(*,*) 'TRIM(nc_var_name) = ', TRIM(nc_var_name)
!-------------------------------------------------!
!- Read the netcdf variable number of dimensions -!
!-------------------------------------------------!
CALL sub_read_netcdf_varid_ndims
(ncid, TRIM(nc_var_name), varid, ndims)
!---------------------------!
!- allocate dims array and -!
!- set dimsorder array.-!---!
!-----------------------!
IF ( (ndims > 0).AND.(ndims < 5)) THEN
!----------------------!
!- Dynamic allocation -!
!----------------------!
ALLOCATE(dims(ndims))
!!NG : 19 06 2009 CALL sub_memory(size(dims),'i','dims','sub_select_var_dims')
!------------------------------------------!
!- Read netcdf variable dimension lengths -!
!------------------------------------------!
CALL sub_read_netcdf_var_dims
(ncid, varid, ndims, dims)
!----------------------------------------------------------------!
!- DoLoop: Read below FUNCTION and EXAMPLES to understand these -!
!- lines. -!---------------------------------------------!
!------------------!
DO ii = 1, ndims
!!NG !-------!
!!NG !- IMT -!
!!NG !-------!
!!NG IF ( (dims(ii) == imt).OR.(key_roms.AND.(dims(ii) == imt-1)) ) THEN
!!NG dimx = dims_reg(1,3)
!!NG dimsorder(1) = ii
!!NG !-------!
!!NG !- JMT -!
!!NG !-------!
!!NG ELSEIF ( (dims(ii) == jmt).OR.(key_roms.AND.(dims(ii) == jmt-1)) ) THEN
!!NG dimy = dims_reg(2,3)
!!NG dimsorder(2) = ii
!!NG
!!NG !-------!
!!NG !- KMT -!
!!NG !-------!
!!NG ELSEIF ( (dims(ii) == kmt).OR.(key_roms.AND.(dims(ii) == kmt-1)) &
!!NG .OR.(key_symphonie.AND.(dims(ii) == kmt-1))) THEN
!!NG dimz = dims_reg(3,3)
!!NG dimsorder(3) = ii
!-------!
!- IMT -!
!-------!
IF ( &
(dims(ii) == imt.AND.dimsorder(1) == 0) .OR.&
(key_roms.AND.dims(ii) == imt-1.AND.dimsorder(1) == 0) &
) THEN
dimx = dims_reg(1,3)
dimsorder(1) = ii
!-------!
!- JMT -!
!-------!
ELSEIF ( &
(dims(ii) == jmt.AND.dimsorder(2) == 0) .OR.&
(key_roms.AND.dims(ii) == jmt-1.AND.dimsorder(2) == 0) &
) THEN
dimy = dims_reg(2,3)
dimsorder(2) = ii
!-------!
!- KMT -!
!-------!
ELSEIF (PRESENT(key_ijt)) THEN
!- We assume that the last dimension is time -!
IF (ii == ndims) THEN
!-------!
!- LMT -!
!-------!
!!NG-idea: IF ( (dims(ii) < lmt).AND.(ind0_xx >= 0) ) THEN
IF (dims(ii) < lmt) THEN
dimt = dims(ii)
ELSE
dimt = lmt
ENDIF
dimsorder(4) = ii
!----------------------------------------------------!
!- Sometimes netcdf arrays were stored in 4D arrays -!
!- with some dimensions set at 1 -!------------------!
!- example: OPA 8.2/ORCA 2 -!-----!
!---------------------------!
ELSEIF (dims(ii) == 1 ) THEN
dumdims(icnt) = ii
icnt = icnt + 1
ELSE
WRITE(*,*)'mod_netcdf: dimension problems in input files !'
STOP
ENDIF
ELSE
IF((dims(ii) == kmt.AND.dimsorder(3) == 0) .OR.&
(key_add_bottom.AND.dims(ii) == kmt-1.AND.dimsorder(3) == 0).OR.&
(key_roms.AND.dims(ii) == kmt-1.AND.dimsorder(3) == 0) .OR.&
(key_symphonie.AND.dims(ii) == kmt-1.AND.dimsorder(3) == 0) &
) THEN
IF (key_add_bottom) THEN
dimz = dims_reg(3,3)-1
ELSE
dimz = dims_reg(3,3)
ENDIF
dimsorder(3) = ii
ELSE !!NG-bug: There was a bug here in version v1.2.1 !!
!- We assume that the last dimension is time -!
IF (ii == ndims) THEN
!-------!
!- LMT -!
!-------!
!!NG-idea: IF ( (dims(ii) < lmt).AND.(ind0_xx >= 0) ) THEN
IF (dims(ii) < lmt) THEN
dimt = dims(ii)
ELSE
dimt = lmt
ENDIF
dimsorder(4) = ii
!----------------------------------------------------!
!- Sometimes netcdf arrays were stored in 4D arrays -!
!- with some dimensions set at 1 -!------------------!
!- example: OPA 8.2/ORCA 2 -!-----!
!---------------------------!
ELSEIF (dims(ii) == 1 ) THEN
dumdims(icnt) = ii
icnt = icnt + 1
ELSE
WRITE(*,*)'mod_netcdf: dimension problems in input files !'
STOP
ENDIF
ENDIF
ENDIF
ENDDO
!---------------------!
!- Deallocate memory -!
!---------------------!
!!NG : 19 06 2009 CALL sub_memory(-size(dims),'i','dims','sub_select_var_dims')
DEALLOCATE(dims)
ELSE
!-----------------------!
!- IF ERROR or PROBLEM -!
!-----------------------!
STOP 'mod_netcdf: sub_select_var_dims: problem on ndims!'
ENDIF
!----------------------------------------------------!
!- Sometimes netcdf arrays were stored in 4D arrays -!
!- with some dimensions set at 1 -!------------------!
!- example: OPA 8.2/ORCA 2 -!-----!
!---------------------------!
icnt = 1
IF ( SUM(dimsorder) /= sumdims(ndims) ) THEN
DO ii = 1, ndims
IF (dimsorder(ii) == 0 ) THEN
dimsorder(ii) = dumdims(icnt)
icnt = icnt + 1
ENDIF
ENDDO
ENDIF
END SUBROUTINE sub_select_var_dims
!!***
!========================================================================
!!****f* mod_netcdf/sub_read_netcdf_var()
!! NAME
!! sub_read_netcdf_var()
!!
!! FUNCTION
!! Read netcdf data
!!
!! AUTHOR
!! * Origin : Nicolas Grima (March 2007)
!!
!! CREATION DATE
!! * September 2009
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * Inputs:
!! - ncid : netcdf file ID
!! - varid : netcdf varaible ID
!! - var : a variable
!!
!! * Output:
!! - var: a variable
!!
!! TODO
!!
!! USES
!! * nf90_get_var (netcdf lib)
!!
!! USED BY
!! * mod_input_particules.f90
!!
!! SOURCE
!!=======================================================================
SUBROUTINE sub_read_netcdf_var( ncid, varid, var) 3
INTEGER(kind = iprec), INTENT(IN) :: ncid
INTEGER(kind = iprec), INTENT(IN) :: varid
REAL(kind = rprec) , INTENT(OUT) :: var
INTEGER(kind = iprec) :: is_err
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = var &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var: &
&problem to read 1 value netcdf data !', is_err
WRITE(lun_error,*) ' ncid = ', ncid
WRITE(lun_error,*) ' varid = ', varid
STOP
ENDIF
END SUBROUTINE sub_read_netcdf_var
!!***
!========================================================================
!!****f* mod_netcdf/sub_read_netcdf_var1d()
!! NAME
!! sub_read_netcdf_var1d()
!!
!! FUNCTION
!! Read 1d netcdf data array and store it in a 1d array.
!!
!! AUTHOR
!! * Origin : Nicolas Grima (March 2007)
!!
!! CREATION DATE
!! * March 2007
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * Inputs:
!! - ncid : netcdf file ID
!! - varid : netcdf varaible ID
!! - var : 1D array
!!
!! * Output:
!! - var: a 1d dummy array
!!
!! TODO
!!
!! USES
!! * nf90_get_var (netcdf lib)
!!
!! USED BY
!! * mod_input_particules.f90
!!
!! SOURCE
!!=======================================================================
SUBROUTINE sub_read_netcdf_var1d(ncid, varid, var) 15
INTEGER(kind = iprec), INTENT(IN) :: ncid
INTEGER(kind = iprec), INTENT(IN) :: varid
REAL(kind = rprec), DIMENSION(:), INTENT(OUT) :: var
INTEGER(kind = iprec) :: is_err
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = var(:) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var1d: &
&problem to read 1D netcdf data !', is_err
WRITE(lun_error,*) ' ncid = ', ncid
WRITE(lun_error,*) ' varid = ', varid
STOP
ENDIF
END SUBROUTINE sub_read_netcdf_var1d
!!***
!========================================================================
!!****f* mod_netcdf/sub_read_netcdf_var4d()
!! NAME
!! sub_read_netcdf_var4d()
!!
!! FUNCTION
!! Read 1d, 2d, 3d or 4d netcdf data array and
!! store it in a 4d array (Reshape: intrinsinc F90 function).
!!
!! AUTHOR
!! * Origin : Nicolas Grima (April-May 2005)
!!
!! CREATION DATE
!! * April-May 2005
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * Inputs:
!! - ncid : netcdf file ID
!! - varid : netcdf varaible ID
!! - dimsorder : variable dimension order
!! - dims_reg : the region dimensions (see mod_reducmem.f90)
!!
!! * Output:
!! - var: a 4d dummy array
!!
!! TODO
!!
!! USES
!! * nf90_get_var (netcdf lib)
!! * Reshape (F90 intrinsinc function)
!!
!! USED BY
!! * mod_input_data.f90
!! * mod_input_grid.f90
!!
!! SOURCE
!!=======================================================================
SUBROUTINE sub_read_netcdf_var4d( ncid, varid, var, dimsorder, dims_reg, & 48,14
ind_time)
!-------------!
! Declaration !
!-------------!
!- arguments -!
INTEGER(kind=iprec), INTENT(in) :: ncid, varid
REAL(kind=rprec) , DIMENSION(:,:,:,:), INTENT(out) :: var
INTEGER(kind=iprec), DIMENSION(4), INTENT(in) :: dimsorder
INTEGER(kind=iprec), DIMENSION(4,3), INTENT(in) :: dims_reg
INTEGER(kind=iprec), OPTIONAL :: ind_time
!- local variables -!
REAL(kind = rprec) :: sfval
REAL(kind = rprec) :: aoval
!!NG: 19 06 2009 REAL(kind = rprec), DIMENSION(:) , ALLOCATABLE :: dumtab1d
!!NG: 19 06 2009 REAL(kind = rprec), DIMENSION(:,:) , ALLOCATABLE :: dumtab2d
!!NG: 19 06 2009 REAL(kind = rprec), DIMENSION(:,:,:) , ALLOCATABLE :: dumtab3d
!!NG: 19 06 2009 REAL(kind = rprec), DIMENSION(:,:,:,:), ALLOCATABLE :: dumtab4d
INTEGER(kind=iprec), DIMENSION(4) :: nb_dims, st_dims
INTEGER(kind=iprec), DIMENSION(4) :: refsize, refstart, order
INTEGER(kind=ishort) :: ii, is_err, nof, inc
INTEGER(kind=ishort) :: limit, lim1, lim2, lim3
INTEGER(kind=ishort) :: indmin11, indmax11, start11, count11
INTEGER(kind=ishort) :: indmin21, indmax21, start21, count21
INTEGER(kind=ishort) :: indmin31, indmax31, start31, count31
INTEGER(kind=ishort) :: indmin41, indmax41, start41, count41
INTEGER(kind=ishort) :: indmin12, indmax12, start12, count12
INTEGER(kind=ishort) :: indmin22, indmax22, start22, count22
INTEGER(kind=ishort) :: indmin32, indmax32, start32, count32
INTEGER(kind=ishort) :: indmin42, indmax42, start42, count42
!-------------!
! Code begins !
!-------------!
!-------------------!
!- Initializations -!
!-------------------!
!------------------------------------------------!
!- Get the reference size of the 4d array where -!
!- netcdf data will be stored. -!----------------!
!-------------------------------!
refsize(1) = SIZE(var,DIM=1)
refsize(2) = SIZE(var,DIM=2)
refsize(3) = SIZE(var,DIM=3)
refsize(4) = SIZE(var,DIM=4)
!--------------------------------------!
!- Get the first indice of the region -!
!--------------------------------------!
refstart(1) = dims_reg(1,1)
refstart(2) = dims_reg(2,1)
refstart(3) = dims_reg(3,1)
IF (PRESENT(ind_time)) THEN
refstart(4) = ind_time
ELSE
refstart(4) = dims_reg(4,1)
ENDIF
!-----------------------------------------------!
!- The number of dimension of the netcdf array -!
!- "nof" should be equal to 1, 2, 3, or 4 -!----!
!------------------------------------------!
nof = COUNT(dimsorder > 0)
!- Initializations -!
order(:) = dimsorder(:)
nb_dims(:)=0
st_dims(:)=0
!------------------------------------------------------------------!
!-In this DoLoop "nb_dims" and "order" arrays will be set.
!- These information stored in these arrays is very important to
!- reshape netcdf data arrays to the 4d Ariane arrays.
!- examples:
!- - If dimsorder=/1,2,3,4/ then
!- nb_dims =/imt_reg,jmt_reg,kmt_reg,lmt_reg/
!- or nb_dims =/imt,jmt,kmt,lmt/
!- order =/1,2,3,4/
!-
!- - If dimsorder=/0,0,1,2/ then
!- nb_dims =/kmt_reg,lmt_reg,0,0/
!- or nb_dims =/kmt,lmt,0,0/
!- order =/3,4,1,2/
!-
!- - If dimsorder=/1,2,0,3/ then
!- nb_dims =/imt_reg,jmt_reg,lmt_reg,0/
!- or nb_dims =/imt,jmt,lmt,0/
!- order =/1,2,4,3/
!------------------------------------------------------------------!
inc = nof + 1
DO ii =1, 4
IF ( dimsorder(ii) /= 0) THEN
nb_dims(dimsorder(ii)) = refsize(ii)
IF ( nb_dims(dimsorder(ii)) == 1 ) THEN
st_dims(dimsorder(ii)) = 1
ELSE
st_dims(dimsorder(ii)) = refstart(ii)
ENDIF
ELSE
order(ii) = inc
inc = inc + 1
ENDIF
ENDDO
IF (PRESENT(ind_time)) THEN
st_dims(dimsorder(4)) = refstart(4)
ENDIF
!! NG: DEBUG
!! write(*,*)'DEBUG: refsize: ',refsize
!! write(*,*)'DEBUG: refstart: ',refstart
!! write(*,*)'DEBUG: nb_dims: ',nb_dims
!! NG:
!---------------------------------------------------------------------!
!- Get 1d, 2d, 3d or 4d netcdf data array and store it in a 4d array -!
!---------------------------------------------------------------------!
SELECT CASE(nof)
CASE(1)
!=============!
!== 1D case ==!
!=============!
IF (.NOT.ALLOCATED(dumtab1d)) THEN
ALLOCATE(dumtab1d(nb_dims(1)))
CALL sub_memory
(size(dumtab1d),'r','dumtab1d','sub_read_netcdf_var4d')
ELSEIF (SIZE(dumtab1d, dim=1) /= nb_dims(1)) THEN
CALL sub_memory
(-size(dumtab1d),'r','dumtab1d','sub_read_netcdf_var4d')
DEALLOCATE(dumtab1d)
ALLOCATE(dumtab1d(nb_dims(1)))
CALL sub_memory
(size(dumtab1d),'r','dumtab1d','sub_read_netcdf_var4d')
ENDIF
!-------------------------------------------------------!
! Test if the region is in two parts in i (longitude). -!-------------!
! In this case we read the netcdf data in two times (performance ?). -!
!---------------------------------------------------------------------!
IF ( (dimsorder(1) == 1) .AND. (dims_reg(1,1) > dims_reg(1,2)) ) THEN
!------------------------------------------------------------!
!---------------------------- 1D ----------------------------!
!------------------------------------------------------------!
!- -!
!- first second -!
!- part part -!
!- ========|---------------------------------|+++++ -!
!- -!
!- data are stored => |+++++========| -!
!- -!
!------------------------------------------------------------!
limit = dims_reg(1,3) - dims_reg(1,2)
!--------------!
!- First part -!
!--------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab1d(1:limit) , &
start = (/ dims_reg(1,1) /), &
count = (/ limit /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 1D netcdf data!'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' dims_reg(1,1) = ', dims_reg(1,1)
WRITE(lun_error,*) ' limit = ', limit
STOP
ENDIF
!---------------!
!- second part -!
!---------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab1d(limit+1:nb_dims(1)), &
start = (/ 1 /) , &
count = (/ dims_reg(1,2)+1 /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 1D netcdf data!'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' dims_reg(1,2)+1 = ', dims_reg(1,2)+1
STOP
ENDIF
ELSE
!------------------------------------------------------------!
!---------------------------- 1D ----------------------------!
!------------------------------------------------------------!
!- -!
!- ------------------|=============|--------------- -!
!- -!
!- data are stored => |=============| -!
!- -!
!------------------------------------------------------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab1d(:) , &
start = (/ st_dims(1) /), &
count = (/ nb_dims(1) /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 1D netcdf data !'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' st_dims(1) = ', st_dims(1)
WRITE(lun_error,*) ' nb_dims(1) = ', nb_dims(1)
STOP
ENDIF
ENDIF
var(:,:,:,:) = RESHAPE(source = dumtab1d, shape = refsize, order = order)
!!NG: 19 06 2009 CALL sub_memory(-size(dumtab1d),'r','dumtab1d','sub_select_var_dims')
!!NG: 19 06 2009 DEALLOCATE(dumtab1d)
CASE(2)
!=============!
!== 2D case ==!
!=============!
IF (.NOT.ALLOCATED(dumtab2d)) THEN
ALLOCATE(dumtab2d(nb_dims(1), nb_dims(2)))
CALL sub_memory
(size(dumtab2d),'r','dumtab2d','sub_read_netcdf_var4d')
ELSEIF ( &
(SIZE(dumtab2d, dim=1) /= nb_dims(1)).OR. &
(SIZE(dumtab2d, dim=2) /= nb_dims(2)) ) THEN
CALL sub_memory
(-size(dumtab2d),'r','dumtab2d','sub_read_netcdf_var4d')
DEALLOCATE(dumtab2d)
ALLOCATE(dumtab2d(nb_dims(1), nb_dims(2)))
CALL sub_memory
(size(dumtab2d),'r','dumtab2d','sub_read_netcdf_var4d')
ENDIF
! Test if the region is in two parts in i (longitude).
! In this case we read the netcdf data in two times (performance ?).
!
IF ( (dimsorder(1) /= 0).AND.(dims_reg(1,1) > dims_reg(1,2)) ) THEN
!------------------------------------------------------------!
!---------------------------- 2D ----------------------------!
!------------------------------------------------------------!
!- -!
!- +----------------------------------------------+ -!
!- | | -!
!- | | -!
!- | | -!
!- |======== +++++++++| -!
!- | | | | -!
!- | | | | -!
!- | | | | -!
!- | | | | -!
!- |======== +++++++++| -!
!- | | -!
!- +----------------------------------------------+ -!
!- -!
!- +++++++++======== -!
!- data are stored => | | | -!
!- | | | -!
!- | | | -!
!- | | | -!
!- +++++++++======== -!
!- -!
!------------------------------------------------------------!
IF (nb_dims(1) /= 1 ) THEN
lim1 = dims_reg(1,3) - dims_reg(1,2)
lim2 = lim1 + 1
lim3 = dims_reg(1,2)
ELSE
lim1 = 1
lim2 = lim1
lim3 = lim1
ENDIF
!-------------------!
!- 2 cases : -!
!- -> i, j -!
!- -> j, i -!
!-------------------!
IF (dimsorder(1) == 1) THEN
indmin11 = 1 ; indmax11 = lim1
start11 = st_dims(1); count11 = lim1
indmin21 = 1 ; indmax21 = nb_dims(2)
start21 = st_dims(2); count21 = nb_dims(2)
indmin12 = lim2 ; indmax12 = nb_dims(1)
start12 = 1 ; count12 = lim3
indmin22 = 1 ; indmax22 = nb_dims(2)
start22 = st_dims(2); count22 = nb_dims(2)
ELSE ! we assume that dimsorder(1) == 2
indmin11 = 1 ; indmax11 = nb_dims(1)
start11 = st_dims(1); count11 = nb_dims(1)
indmin21 = 1 ; indmax21 = lim1
start21 = st_dims(2); count21 = lim1
indmin12 = 1 ; indmax12 = nb_dims(1)
start12 = st_dims(1); count12 = nb_dims(1)
indmin22 = lim2 ; indmax22 = nb_dims(2)
start22 = 1 ; count22 = lim3
ENDIF
!--------------!
!- First part -!
!--------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab2d(indmin11:indmax11,indmin21:indmax21), &
start = (/start11, start21 /) , &
count = (/count11, count21 /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 2D netcdf data !'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' start11, start21 = ', start11, start21
WRITE(lun_error,*) ' count11, count21 = ', count11, count21
STOP
ENDIF
!---------------!
!- second part -!
!---------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab2d(indmin12:indmax12,indmin22:indmax22), &
start = (/start12, start22 /) , &
count = (/count12, count22 /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 2D netcdf data !'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' start12, start22 = ', start12, start22
WRITE(lun_error,*) ' count12, count22 = ', count12, count22
STOP
ENDIF
ELSE
!------------------------------------------------------------!
!---------------------------- 2D ----------------------------!
!------------------------------------------------------------!
!- -!
!- +----------------------------------------------+ -!
!- | | -!
!- | | -!
!- | | -!
!- | ================= | -!
!- | | | | -!
!- | | | | -!
!- | | | | -!
!- | ================= | -!
!- | | -!
!- | | -!
!- +----------------------------------------------+ -!
!- -!
!- ================= -!
!- data are stored => | | -!
!- | | -!
!- | | -!
!- ================= -!
!- -!
!------------------------------------------------------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab2d(:,:) , &
start = (/ st_dims(1), st_dims(2) /), &
count = (/ nb_dims(1), nb_dims(2) /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 2D netcdf data !'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' st_dims(1), st_dims(2) = ', st_dims(1), st_dims(2)
WRITE(lun_error,*) ' nb_dims(1), nb_dims(2) = ', nb_dims(1), nb_dims(2)
STOP
ENDIF
ENDIF
var(:,:,:,:) = RESHAPE(source = dumtab2d, shape = refsize, order = order)
!!NG: 19 06 2009 CALL sub_memory(-size(dumtab2d),'r','dumtab2d','sub_read_netcdf_var4d')
!!NG: 19 06 2009 DEALLOCATE(dumtab2d)
CASE(3)
!=============!
!== 3D case ==!
!=============!
IF (.NOT.ALLOCATED(dumtab3d)) THEN
ALLOCATE(dumtab3d(nb_dims(1), nb_dims(2), nb_dims(3)))
CALL sub_memory
(size(dumtab3d),'r','dumtab3d','sub_read_netcdf_var4d')
ELSEIF ( &
(SIZE(dumtab3d, dim=1) /= nb_dims(1)).OR. &
(SIZE(dumtab3d, dim=2) /= nb_dims(2)).OR. &
(SIZE(dumtab3d, dim=3) /= nb_dims(3))) THEN
CALL sub_memory
(-size(dumtab3d),'r','dumtab3d','sub_read_netcdf_var4d')
DEALLOCATE(dumtab3d)
ALLOCATE(dumtab3d(nb_dims(1), nb_dims(2), nb_dims(3)))
CALL sub_memory
(size(dumtab3d),'r','dumtab3d','sub_read_netcdf_var4d')
ENDIF
! Test if the region is in two parts in i (longitude).
! In this case we read the netcdf data in two times (performance ?).
!
IF ( (dimsorder(1) /= 0).AND.(dims_reg(1,1) > dims_reg(1,2)) ) THEN
!------------------------------------------------------------!
!---------------------------- 3D ----------------------------!
!------------------------------------------------------------!
!- +----------------------------------------------+ -!
!- / /| -!
!- / / | -!
!- / / | -!
!- / / + -!
!- +----------------------------------------------+ /| -!
!- | | / | -!
!- | | / | -!
!- | |/ | -!
!- |======== ++++++++++ + -!
!- | | | | /| -!
!- | | | | / + -!
!- | | | | / / -!
!- | | | |/ / -!
!- |======== ++++++++++ / -!
!- | |/ -!
!- +----------------------------------------------+ -!
!- -!
!- +++++++++=======+ -!
!- / / /| -!
!- data are stored => / / / | -!
!- / / / | -!
!- / / / + -!
!- +++++++++======== / -!
!- | | | / -!
!- | | | / -!
!- | | | / -!
!- | | |/ -!
!- +++++++++======== -!
!- -!
!------------------------------------------------------------!
IF (nb_dims(1) /= 1 ) THEN
lim1 = dims_reg(1,3) - dims_reg(1,2)
lim2 = lim1 + 1
lim3 = dims_reg(1,2)
ELSE
lim1 = 1
lim2 = lim1
lim3 = lim1
ENDIF
!------------------------------!
!- 3 cases : -!
!- -> i, j, k or i, k, j -!
!- -> j, i, k or k, i, j -!
!- -> j, k, i or k, j, i -!
!------------------------------!
IF (dimsorder(1) == 1) THEN
indmin11 = 1 ; indmax11 = lim1
start11 = st_dims(1); count11 = lim1
indmin21 = 1 ; indmax21 = nb_dims(2)
start21 = st_dims(2); count21 = nb_dims(2)
indmin31 = 1 ; indmax31 = nb_dims(3)
start31 = st_dims(3); count31 = nb_dims(3)
indmin12 = lim2 ; indmax12 = nb_dims(1)
start12 = 1 ; count12 = lim3
indmin22 = 1 ; indmax22 = nb_dims(2)
start22 = st_dims(2); count22 = nb_dims(2)
indmin32 = 1 ; indmax32 = nb_dims(3)
start32 = st_dims(3); count32 = nb_dims(3)
ELSEIF (dimsorder(1) == 2) THEN
indmin11 = 1 ; indmax11 = nb_dims(1)
start11 = st_dims(1); count11 = nb_dims(1)
indmin21 = 1 ; indmax21 = lim1
start21 = st_dims(2); count21 = lim1
indmin31 = 1 ; indmax31 = nb_dims(3)
start31 = st_dims(3); count31 = nb_dims(3)
indmin12 = 1 ; indmax12 = nb_dims(1)
start12 = st_dims(1); count12 = nb_dims(1)
indmin22 = lim2 ; indmax22 = nb_dims(2)
start22 = 1 ; count22 = lim3
indmin32 = 1 ; indmax32 = nb_dims(3)
start32 = st_dims(3); count32 = nb_dims(3)
ELSE ! we assume that dimsorder(1) == 3
indmin11 = 1 ; indmax11 = nb_dims(1)
start11 = st_dims(1); count11 = nb_dims(1)
indmin21 = 1 ; indmax21 = nb_dims(2)
start21 = st_dims(2); count21 = nb_dims(2)
indmin31 = 1 ; indmax31 = lim1
start31 = st_dims(3); count31 = lim1
indmin12 = 1 ; indmax12 = nb_dims(1)
start12 = st_dims(1); count12 = nb_dims(1)
indmin22 = 1 ; indmax22 = nb_dims(2)
start22 = st_dims(2); count22 = nb_dims(2)
indmin32 = lim2 ; indmax32 = nb_dims(3)
start32 = 1 ; count32 = lim3
ENDIF
!--------------!
!- First part -!
!--------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab3d(indmin11:indmax11 , &
indmin21:indmax21 , &
indmin31:indmax31) , &
start = (/start11, start21, start31 /), &
count = (/count11, count21, count31 /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 3D netcdf data !'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' start11, start21, start31 = ', start11, start21, start31
WRITE(lun_error,*) ' count11, count21, count31 = ', count11, count21, count31
STOP
ENDIF
!---------------!
!- second part -!
!---------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab3d(indmin12:indmax12 , &
indmin22:indmax22 , &
indmin32:indmax32) , &
start = (/start12, start22, start32 /), &
count = (/count12, count22, count32 /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 3D netcdf data !'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' start12, start22, start32 = ', start12, start22, start32
WRITE(lun_error,*) ' count12, count22, start32 = ', count12, count22, start32
STOP
ENDIF
ELSE
!------------------------------------------------------------!
!---------------------------- 3D ----------------------------!
!------------------------------------------------------------!
!- +----------------------------------------------+ -!
!- / /| -!
!- / / | -!
!- / / | -!
!- / / | -!
!- +----------------------------------------------+ | -!
!- | | | -!
!- | | | -!
!- | | | -!
!- | *==============* | | -!
!- | | | | | -!
!- | | | | + -!
!- | | | | / -!
!- | | | | / -!
!- | *==============* | / -!
!- | |/ -!
!- +----------------------------------------------+ -!
!- -!
!- *===============* -!
!- / /| -!
!- data are stored => / / | -!
!- / / | -!
!- / / | -!
!- *===============* / -!
!- | | / -!
!- | | / -!
!- | | / -!
!- | |/ -!
!- *===============* -!
!- -!
!------------------------------------------------------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab3d(:,:,:) , &
start = (/ st_dims(1), st_dims(2), st_dims(3) /), &
count = (/ nb_dims(1), nb_dims(2), nb_dims(3) /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 3D netcdf data !'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' st_dims(1), st_dims(2), st_dims(3) = ', st_dims(1), st_dims(2), st_dims(3)
WRITE(lun_error,*) ' nb_dims(1), nb_dims(2), nb_dims(3) = ', nb_dims(1), nb_dims(2), nb_dims(3)
STOP
ENDIF
ENDIF
var(:,:,:,:) = RESHAPE(source = dumtab3d, shape = refsize, order = order)
!!NG: 19 06 2009 CALL sub_memory(-size(dumtab3d),'r','dumtab3d','sub_read_netcdf_var4d')
!!NG: 19 06 2009 DEALLOCATE(dumtab3d)
CASE(4)
!=============!
!== 4D case ==!
!=============!
IF (.NOT.ALLOCATED(dumtab4d)) THEN
ALLOCATE(dumtab4d(nb_dims(1), nb_dims(2), nb_dims(3), nb_dims(4)))
CALL sub_memory
(size(dumtab4d),'r','dumtab4d','sub_read_netcdf_var4d')
ELSEIF ( &
(SIZE(dumtab4d, dim=1) /= nb_dims(1)).OR. &
(SIZE(dumtab4d, dim=2) /= nb_dims(2)).OR. &
(SIZE(dumtab4d, dim=3) /= nb_dims(3)).OR. &
(SIZE(dumtab4d, dim=4) /= nb_dims(4))) THEN
CALL sub_memory
(-size(dumtab4d),'r','dumtab4d','sub_read_netcdf_var4d')
DEALLOCATE(dumtab4d)
ALLOCATE(dumtab4d(nb_dims(1), nb_dims(2),nb_dims(3),nb_dims(4)))
CALL sub_memory
(size(dumtab4d),'r','dumtab4d','sub_read_netcdf_var4d')
ENDIF
! Test if the region is in two parts in i (longitude).
! In this case we read the netcdf data in two times (performance ?).
!
IF ( (dimsorder(1) /= 0).AND.(dims_reg(1,1) > dims_reg(1,2)) ) THEN
!------------------------------------------------------------!
!------------------------ 3D + TIME ------------------------!
!------------------------------------------------------------!
!- +----------------------------------------------+ -!
!- / /| -!
!- / / | -!
!- / / | -!
!- / / + -!
!- +----------------------------------------------+ /| -!
!- | | / | -!
!- | | / | -!
!- | |/ | -!
!- |======== ++++++++++ + -!
!- | | | | /| -!
!- | | | | / + -!
!- | | | | / / -!
!- | | | |/ / -!
!- |======== ++++++++++ / -!
!- | |/ -!
!- +----------------------------------------------+ -!
!- -!
!- +++++++++=======+ -!
!- / / /| -!
!- data are stored => / / / | -!
!- / / / | -!
!- / / / + -!
!- +++++++++======== / -!
!- | | | / -!
!- | | | / -!
!- | | | / -!
!- | | |/ -!
!- +++++++++======== -!
!- -!
!------------------------------------------------------------!
IF (nb_dims(1) /= 1 ) THEN
lim1 = dims_reg(1,3) - dims_reg(1,2)
lim2 = lim1 + 1
lim3 = dims_reg(1,2)
ELSE
lim1 = 1
lim2 = lim1
lim3 = lim1
ENDIF
!--------------------------------!
!- 4 cases : -!
!- -> i = first dimension -!
!- -> i = second dimension -!
!- -> i = third dimension -!
!- -> i = fourth dimension -!
!--------------------------------!
IF (dimsorder(1) == 1) THEN
indmin11 = 1 ; indmax11 = lim1
start11 = st_dims(1); count11 = lim1
indmin21 = 1 ; indmax21 = nb_dims(2)
start21 = st_dims(2); count21 = nb_dims(2)
indmin31 = 1 ; indmax31 = nb_dims(3)
start31 = st_dims(3); count31 = nb_dims(3)
indmin41 = 1 ; indmax41 = nb_dims(4)
start41 = st_dims(4); count41 = nb_dims(4)
indmin12 = lim2 ; indmax12 = nb_dims(1)
start12 = 1 ; count12 = lim3
indmin22 = 1 ; indmax22 = nb_dims(2)
start22 = st_dims(2); count22 = nb_dims(2)
indmin32 = 1 ; indmax32 = nb_dims(3)
start32 = st_dims(3); count32 = nb_dims(3)
indmin42 = 1 ; indmax42 = nb_dims(4)
start42 = st_dims(4); count42 = nb_dims(4)
ELSEIF (dimsorder(1) == 2) THEN
indmin11 = 1 ; indmax11 = nb_dims(1)
start11 = st_dims(1); count11 = nb_dims(1)
indmin21 = 1 ; indmax21 = lim1
start21 = st_dims(2); count21 = lim1
indmin31 = 1 ; indmax31 = nb_dims(3)
start31 = st_dims(3); count31 = nb_dims(3)
indmin41 = 1 ; indmax41 = nb_dims(4)
start41 = st_dims(4); count41 = nb_dims(4)
indmin12 = 1 ; indmax12 = nb_dims(1)
start12 = st_dims(1); count12 = nb_dims(1)
indmin22 = lim2 ; indmax22 = nb_dims(2)
start22 = 1 ; count22 = lim3
indmin32 = 1 ; indmax32 = nb_dims(3)
start32 = st_dims(3); count32 = nb_dims(3)
indmin42 = 1 ; indmax42 = nb_dims(4)
start42 = st_dims(4); count42 = nb_dims(4)
ELSEIF (dimsorder(1) == 3) THEN
indmin11 = 1 ; indmax11 = nb_dims(1)
start11 = st_dims(1); count11 = nb_dims(1)
indmin21 = 1 ; indmax21 = nb_dims(2)
start21 = st_dims(2); count21 = nb_dims(2)
indmin31 = 1 ; indmax31 = lim1
start31 = st_dims(3); count31 = lim1
indmin41 = 1 ; indmax41 = nb_dims(4)
start41 = st_dims(4); count41 = nb_dims(4)
indmin12 = 1 ; indmax12 = nb_dims(1)
start12 = st_dims(1); count12 = nb_dims(1)
indmin22 = 1 ; indmax22 = nb_dims(2)
start22 = st_dims(2); count22 = nb_dims(2)
indmin32 = lim2 ; indmax32 = nb_dims(3)
start32 = 1 ; count32 = lim3
indmin42 = 1 ; indmax42 = nb_dims(4)
start42 = st_dims(4); count42 = nb_dims(4)
ELSE ! we assume that dimsorder(1) == 4
indmin11 = 1 ; indmax11 = nb_dims(1)
start11 = st_dims(1); count11 = nb_dims(1)
indmin21 = 1 ; indmax21 = nb_dims(2)
start21 = st_dims(2); count21 = nb_dims(2)
indmin31 = 1 ; indmax31 = nb_dims(3)
start31 = st_dims(3); count31 = nb_dims(3)
indmin41 = 1 ; indmax41 = lim1
start41 = st_dims(4); count41 = lim1
indmin12 = 1 ; indmax12 = nb_dims(1)
start12 = st_dims(1); count12 = nb_dims(1)
indmin22 = 1 ; indmax22 = nb_dims(2)
start22 = st_dims(2); count22 = nb_dims(2)
indmin32 = 1 ; indmax32 = nb_dims(3)
start32 = st_dims(3); count32 = nb_dims(3)
indmin42 = lim2 ; indmax42 = nb_dims(4)
start42 = 1 ; count42 = lim3
ENDIF
!--------------!
!- First part -!
!--------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab4d(indmin11:indmax11 , &
indmin21:indmax21 , &
indmin31:indmax31 , &
indmin41:indmax41) , &
start = (/start11, start21, start31, start41 /), &
count = (/count11, count21, count31, count41 /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 4D netcdf data !'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' start11, start21, start31, start41 = ', start11, start21, start31, start41
WRITE(lun_error,*) ' count11, count21, count31, count41 = ', count11, count21, count31, count41
STOP
ENDIF
!---------------!
!- second part -!
!---------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab4d(indmin12:indmax12 , &
indmin22:indmax22 , &
indmin32:indmax32 , &
indmin42:indmax42) , &
start = (/start12, start22, start32, start42 /), &
count = (/count12, count22, count32, count42 /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 4D netcdf data !'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' start12, start22, start32, start42 = ', start12, start22, start32, start42
WRITE(lun_error,*) ' count12, count22, start32, count42 = ', count12, count22, start32, count42
STOP
ENDIF
ELSE
!------------------------------------------------------------!
!------------------------ 3D + TIME -------------------------!
!------------------------------------------------------------!
!- +----------------------------------------------+ -!
!- / /| -!
!- / / | -!
!- / / | -!
!- / / | -!
!- +----------------------------------------------+ | -!
!- | | | -!
!- | | | -!
!- | | | -!
!- | *==============* | | -!
!- | | | | | -!
!- | | | | + -!
!- | | | | / -!
!- | | | | / -!
!- | *==============* | / -!
!- | |/ -!
!- +----------------------------------------------+ -!
!- -!
!- *===============* -!
!- / /| -!
!- data are stored => / / | -!
!- / / | -!
!- / / | -!
!- *===============* / -!
!- | | / -!
!- | | / -!
!- | | / -!
!- | |/ -!
!- *===============* -!
!- -!
!------------------------------------------------------------!
is_err = nf90_get_var( &
ncid = ncid , &
varid = varid , &
values = dumtab4d(:,:,:,:) , &
start = (/ st_dims(1), st_dims(2), st_dims(3), st_dims(4) /), &
count = (/ nb_dims(1), nb_dims(2), nb_dims(3), nb_dims(4) /) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_var4d: problem to read 4D netcdf data !'
WRITE(lun_error,*) ' NetCDF error = ', is_err
WRITE(lun_error,*) ' st_dims(1), st_dims(2), st_dims(3), st_dims(4) = ', &
st_dims(1), st_dims(2), st_dims(3), st_dims(4)
WRITE(lun_error,*) ' nb_dims(1), nb_dims(2), nb_dims(3), nb_dims(4) = ', &
nb_dims(1), nb_dims(2), nb_dims(3), nb_dims(4)
STOP
ENDIF
ENDIF
!! Bug if shape(var) = shape(dumtab4d), i.e. refsize(:) = nb_dims(:)
!! var(:,:,:,:) = RESHAPE(source = dumtab4d, shape = refsize, order = order)
!! NG: 19/01/2009 write(lun_standard,*)'size var ',shape(var)
!! NG: 19/01/2009 write(lun_standard,*)'size dumtab4d',shape(dumtab4d)
var(:,:,:,:) = dumtab4d(:,:,:,:)
!!NG: 19 06 2009 CALL sub_memory(-size(dumtab4d),'r','dumtab4d','sub_read_netcdf_var4d')
!!NG: 19 06 2009 DEALLOCATE(dumtab4d)
CASE DEFAULT
STOP
END SELECT
!---------------------------------------------------------!
!- To reduce place some data are saved in integer 16bits -!
!- for example DRAKKAR - OPA 1/4 of degres -!
!- Here data are first scaled and an offset is added -!
!---------------------------------------------------------!
!-----------------------------------!
!- Scale_factor is red or set to 1 -!
!-----------------------------------!
CALL sub_read_netcdf_att_val
( &
ncid , &
varid , &
'scale_factor' , &
sfval , &
1._rprec )
var(:,:,:,:) = var(:,:,:,:) * sfval
!---------------------------------!
!- Add_offset is red or set to 0 -!
!---------------------------------!
CALL sub_read_netcdf_att_val
( &
ncid , &
varid , &
'add_offset' , &
aoval , &
0._rprec )
var(:,:,:,:) = var(:,:,:,:) + aoval
END SUBROUTINE sub_read_netcdf_var4d
!!***
!========================================================================
!!****f* mod_netcdf/sub_read_netcdf_att_val()
!! NAME
!! sub_read_netcdf_att_info()
!!
!! FUNCTION
!! Read attribute information of a netcdf variable
!!
!! AUTHOR
!! * Origin : Nicolas Grima (April-May 2005)
!!
!! CREATION DATE
!! * April-May 2005
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * Inputs:
!! - ncid : netcdf file ID
!! - varid : netcdf variable ID
!! - attname: attribute name of the netcdf variable (ID)
!!
!! * Output:
!! - attval: attribute value
!!
!! TODO
!!
!! USES
!! * nf90_get_att (netcdf lib)
!!
!! USED BY
!! * mod_input_data.f90
!! * mod_input_grid.f90
!! SOURCE
!!=======================================================================
SUBROUTINE sub_read_netcdf_att_val(ncid, varid, attname, attval, valdef) 15
!-------------!
! Declaration !
!-------------!
!- arguments -!
INTEGER(kind=iprec), INTENT(in) :: ncid
INTEGER(kind=iprec), INTENT(in) :: varid
CHARACTER(len=*) , INTENT(in) :: attname
REAL(kind=rprec) , INTENT(out) :: attval
REAL(kind=rprec) , INTENT(in) :: valdef
!- local variables -!
INTEGER(kind=ishort) :: is_err ! error code returns by netcdf function
!-------------!
! Code begins !
!-------------!
!- Netcdf function which get a attribute value for a specified variable.
is_err = nf90_get_att( &
ncid = ncid , &
varid = varid , &
name = attname , &
values = attval &
)
!-----------------------------------------------------------!
!- If the attribute doesn't exist set to the default value -!
!-----------------------------------------------------------!
IF (is_err /= NF90_NOERR) THEN
attval = valdef
ENDIF
END SUBROUTINE sub_read_netcdf_att_val
!!***
!========================================================================
!!****f* mod_netcdf/sub_read_netcdf_global_att()
!! NAME
!! sub_read_netcdf_global_att()
!!
!! FUNCTION
!! Read ROMS Global Attributes hc sc_w and Cs_w
!!
!! AUTHOR
!! * Origin : Nicolas Grima (November 2005)
!!
!! CREATION DATE
!! * November 2005
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * Input:
!!
!! * Output:
!!
!! TODO
!!
!! USES
!! *
!!
!! USED BY
!! * mod_input_data.f90
!!
!! SOURCE
!!=======================================================================
SUBROUTINE sub_read_netcdf_global_att( & 3,2
c_dir, c_fn , &
c_hc, c_sc_w, c_Cs_w , &
hc, sc_w, Cs_w)
CHARACTER(len = *) , INTENT(IN) :: c_dir, c_fn
CHARACTER(len = *) , INTENT(IN) :: c_hc, c_sc_w, c_Cs_w
REAL(kind = rprec) , INTENT(OUT) :: hc
REAL(kind = rprec), DIMENSION(:), INTENT(OUT) :: sc_w, Cs_w
INTEGER(kind = iprec) :: is_err ! netcdf error code
INTEGER(kind = iprec) :: ncid ! netcdf file ID
CALL sub_open_netcdf_file
(c_dir, c_fn, ncid)
!- HC -!
is_err = nf90_get_att ( &
ncid = ncid , &
varid = NF90_GLOBAL, &
name = c_hc , &
values = hc &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_global_att: &
& problem to read ',TRIM(c_hc)
STOP
ENDIF
!- SC_W -!
is_err = nf90_get_att ( &
ncid = ncid , &
varid = NF90_GLOBAL , &
name = c_sc_w , &
values = sc_w(dims_reg(3,3):1:-1) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_global_att: &
& problem to read ',TRIM(c_sc_w)
STOP
ENDIF
!- CS_W -!
is_err = nf90_get_att ( &
ncid = ncid , &
varid = NF90_GLOBAL , &
name = c_Cs_w , &
values = cs_w(dims_reg(3,3):1:-1) &
)
!-------------------------!
!- Test problem or error -!
!-------------------------!
IF (is_err /= nf90_noerr) THEN
WRITE(lun_error,*) 'mod_netcdf: sub_read_netcdf_global_att: &
& problem to read ',TRIM(c_Cs_w)
STOP
ENDIF
!- Close netcdf file -!
CALL sub_close_netcdf_file
(ncid)
END SUBROUTINE sub_read_netcdf_global_att
!!***
!========================================================================
!!****f* mod_netcdf/sub_read_netcdf_global_att()
!! NAME
!! sub_read_netcdf_global_att()
!!
!! FUNCTION
!! Read ROMS Global Attributes hc sc_w and Cs_w
!!
!! AUTHOR
!! * Origin : Nicolas Grima (November 2005)
!!
!! CREATION DATE
!! * November 2005
!!
!! HISTORY
!! Date (dd/mm/yyyy/) - Modification(s)
!!
!! ARGUMENTS
!! * Input:
!!
!! * Output:
!!
!! TODO
!!
!! USES
!! *
!!
!! USED BY
!! * mod_input_data.f90
!!
!! SOURCE
!!=======================================================================
SUBROUTINE sub_netcdf_dealloc_mem() 2,4
IF (ALLOCATED(dumtab1d)) THEN
CALL sub_memory
(-size(dumtab1d),'r','dumtab1d', &
'sub_netcdf_dealloc_mem')
DEALLOCATE(dumtab1d)
END IF
IF (ALLOCATED(dumtab2d)) THEN
CALL sub_memory
(-size(dumtab2d),'r','dumtab2d', &
'sub_netcdf_dealloc_mem')
DEALLOCATE(dumtab2d)
END IF
IF (ALLOCATED(dumtab3d)) THEN
CALL sub_memory
(-size(dumtab3d),'r','dumtab3d', &
'sub_netcdf_dealloc_mem')
DEALLOCATE(dumtab3d)
END IF
IF (ALLOCATED(dumtab4d)) THEN
CALL sub_memory
(-size(dumtab4d),'r','dumtab4d', &
'sub_netcdf_dealloc_mem')
DEALLOCATE(dumtab4d)
END IF
END SUBROUTINE sub_netcdf_dealloc_mem
END MODULE mod_netcdf