! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! + + ! + ncdf_utils.f90 - part of the Glimmer-CISM ice model + ! + + ! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! ! Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 ! Glimmer-CISM contributors - see AUTHORS file for list of contributors ! ! This file is part of Glimmer-CISM. ! ! Glimmer-CISM is free software: you can redistribute it and/or modify ! it under the terms of the GNU General Public License as published by ! the Free Software Foundation, either version 2 of the License, or (at ! your option) any later version. ! ! Glimmer-CISM is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! GNU General Public License for more details. ! ! You should have received a copy of the GNU General Public License ! along with Glimmer-CISM. If not, see . ! ! Glimmer-CISM is hosted on BerliOS.de: ! https://developer.berlios.de/projects/glimmer-cism/ ! ! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #ifdef HAVE_CONFIG_H #include "config.inc" #endif !> This code provides a simple interface to create and then add !! to a netcdf file containing time-slices of a single 2D field, !! for use in debugging. module ncdf_utils use netcdf use glimmer_global implicit none type ncdf_utils_type integer :: id,varid,dimid1,dimid2,dimid3,d3id integer :: next=1 character(100) :: fname end type ncdf_utils_type contains subroutine ncdf_utils_create(handle,fname,varname,d1name,d2name,d1,d2) type(ncdf_utils_type),intent(out) :: handle !< Netcdf file handles character(*), intent(in) :: fname !< File name character(*), intent(in) :: varname !< Variable name character(*), intent(in) :: d1name !< Name of first dimension character(*), intent(in) :: d2name !< Name of second dimension real(sp),dimension(:),intent(in) :: d1 !< Dimension 1 real(sp),dimension(:),intent(in) :: d2 !< Dimension 2 integer :: ncerr,d1id,d2id ! Create file ncerr=nf90_create(fname,0,handle%id) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) handle%fname=fname ! Define dimensions ncerr=nf90_def_dim(handle%id,d1name,size(d1),handle%dimid1) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ncerr=nf90_def_dim(handle%id,d2name,size(d2),handle%dimid2) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ncerr=nf90_def_dim(handle%id,'time',NF90_UNLIMITED,handle%dimid3) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ! Define dimension variables ncerr=nf90_def_var(handle%id,d1name,NF90_FLOAT,(/handle%dimid1/),d1id) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ncerr=nf90_def_var(handle%id,d2name,NF90_FLOAT,(/handle%dimid2/),d2id) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ncerr=nf90_def_var(handle%id,'time',NF90_FLOAT,(/handle%dimid3/),handle%d3id) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ! Define 2D variable ncerr=nf90_def_var(handle%id,varname,NF90_DOUBLE, & (/handle%dimid1,handle%dimid2,handle%dimid3/),handle%varid) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ! Exit define mode and save dimension variables ncerr=nf90_enddef(handle%id) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ncerr=nf90_put_var(handle%id,d1id,d1) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ncerr=nf90_put_var(handle%id,d2id,d2) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) end subroutine ncdf_utils_create !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ subroutine ncdf_utils_write(handle,var,time) type(ncdf_utils_type), intent(inout) :: handle real(rk),dimension(:,:),intent(in) :: var real(sp), intent(in) :: time integer :: ncerr ncerr=nf90_put_var(handle%id,handle%varid,real(var,dp),(/1,1,handle%next/)) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ncerr=nf90_put_var(handle%id,handle%d3id,time,(/handle%next/)) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ncerr=nf90_sync(handle%id) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) handle%next=handle%next+1 end subroutine ncdf_utils_write !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ subroutine ncdf_utils_close(handle) type(ncdf_utils_type), intent(in) :: handle integer :: ncerr ncerr=nf90_close(handle%id) end subroutine ncdf_utils_close !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ subroutine ncdf_utils_read_slice(filename,varname,slice,array) character(*), intent(in) :: filename character(*), intent(in) :: varname integer, intent(in) :: slice real(rk),dimension(:,:),intent(out) :: array integer :: ncerr,fileid,varid ncerr=nf90_open(filename,0,fileid) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ncerr=nf90_inq_varid(fileid,varname,varid) if (ncerr/=NF90_NOERR) call ncerr_handle(ncerr) ncerr=nf90_get_var(fileid,varid,array,(/1,1,slice/)) end subroutine ncdf_utils_read_slice !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ subroutine ncerr_handle(ncerr) integer,intent(in) :: ncerr print*,nf90_strerror(ncerr) stop end subroutine ncerr_handle end module ncdf_utils