! --------------------------------------------- ! This module serves as a wrapper around netcdf. ! It serves two primary functions: ! 1) Turn netcdf into a "real" fortran module, without the INCLUDE call ! 2) Handle the NC_DOUBLE CPP key. Ideally, this key should ONLY appear here (WIP). TODO ! Ideally, the "real" netcdf module/headers should ONLY be called here. (WIP) TODO ! --------------------------------------------- ! TODO check that none of the wrapped functions remain elsewhere ! TODO check all uses of `use netcdf` + netcdf.inc MODULE lmdz_netcdf USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : REAL64, REAL32 USE netcdf IMPLICIT NONE ! Note: as we want to expose netcdf through this module, we don't make all PRIVATE by default as usual ! Instead, explicitely make PRIVATE the relevant items. PRIVATE CPP_NC_DOUBLE INCLUDE 'netcdf.inc' #ifdef NC_DOUBLE LOGICAL, PARAMETER :: CPP_NC_DOUBLE = .TRUE. ! Define a variable to reduce use of preprocessor ahead INTEGER, PARAMETER :: NF90_FORMAT = NF90_DOUBLE INTEGER, PARAMETER :: REAL_FORMAT = REAL64 #else LOGICAL, PARAMETER :: CPP_NC_DOUBLE = .FALSE. INTEGER, PARAMETER :: NF90_FORMAT = NF90_FLOAT INTEGER, PARAMETER :: REAL_FORMAT = REAL32 #endif CONTAINS ! Note: below, we use the same declarations as the fortran netcdf lib, hence the use of (*) ! We'd like to use "nf_put_var", but it already exists as a legacy nc4 function ! CPP_NC_DOUBLE wrapper around nf_put_var_real, nf_put_var_double INTEGER FUNCTION nf_put_var_rd(ncid, varid, vals) INTEGER, INTENT(IN) :: ncid, varid REAl(REAL_FORMAT), INTENT(IN) :: vals(*) ! (*) as declared in netcdf lib IF (CPP_NC_DOUBLE) THEN nf_put_var_rd = nf_put_var_double(ncid, varid, vals) ELSE nf_put_var_rd = nf_put_var_real(ncid, varid, vals) END IF END FUNCTION nf_put_var_rd ! CPP_NC_DOUBLE wrapper around nf_put_vara_real, nf_put_vara_double INTEGER FUNCTION nf_put_vara_rd(ncid, varid, start, counts, vals) INTEGER, INTENT(IN) :: ncid, varid INTEGER, INTENT(IN) :: start(*), counts(*) REAl(REAL_FORMAT), INTENT(IN) :: vals(*) IF (CPP_NC_DOUBLE) THEN nf_put_vara_rd = nf_put_vara_double(ncid, varid, start, counts, vals) ELSE nf_put_vara_rd = nf_put_vara_real(ncid, varid, start, counts, vals) END IF END FUNCTION nf_put_vara_rd ! CPP_NC_DOUBLE wrapper around nf_get_vara_real, nf_get_vara_double INTEGER FUNCTION nf_get_vara_rd(ncid, varid, start, counts, vals) INTEGER, INTENT(IN) :: ncid, varid INTEGER, INTENT(IN) :: start(*), counts(*) REAl(REAL_FORMAT), INTENT(OUT) :: vals(*) IF (CPP_NC_DOUBLE) THEN nf_get_vara_rd = nf_get_vara_double(ncid, varid, start, counts, vals) ELSE nf_get_vara_rd = nf_get_vara_real(ncid, varid, start, counts, vals) END IF END FUNCTION nf_get_vara_rd END MODULE lmdz_netcdf