123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !
- ! This file converts a POP grid.dat file to a remapping grid file
- ! in netCDF format.
- !
- !-----------------------------------------------------------------------
- !
- ! CVS:$Id: convertPOPT.f,v 1.4 2001/08/21 21:22:56 pwjones Exp $
- !
- ! Copyright (c) 1997, 1998 the Regents of the University of
- ! California.
- !
- ! Unless otherwise indicated, this software has been authored
- ! by an employee or employees of the University of California,
- ! operator of the Los Alamos National Laboratory under Contract
- ! No. W-7405-ENG-36 with the U.S. Department of Energy. The U.S.
- ! Government has rights to use, reproduce, and distribute this
- ! software. The public may copy and use this software without
- ! charge, provided that this Notice and any statement of authorship
- ! are reproduced on all copies. Neither the Government nor the
- ! University makes any warranty, express or implied, or assumes
- ! any liability or responsibility for the use of this software.
- !
- !***********************************************************************
- program convertPOPT
- !-----------------------------------------------------------------------
- !
- ! This file converts a POP grid.dat file to a remapping grid file.
- !
- !-----------------------------------------------------------------------
- use kinds_mod
- use constants
- use iounits
- use netcdf_mod
- implicit none
- !-----------------------------------------------------------------------
- !
- ! variables that describe the grid
- ! 4/3 nx = 192, ny = 128
- ! 2/3 (mod) nx = 384, ny = 288
- ! x3p Greenland DP nx = 100, ny = 116
- ! x2p Greenland DP nx = 160, ny = 192
- ! x1p Greenland DP nx = 320, ny = 384
- !
- !-----------------------------------------------------------------------
- integer (kind=int_kind), parameter ::
- & nx = 320, ny = 384,
- & grid_size = nx*ny,
- & grid_rank = 2,
- & grid_corners = 4
- integer (kind=int_kind), dimension(2) ::
- & grid_dims ! size of each dimension
- character(char_len), parameter ::
- & grid_name = 'Greenland DP x1p',
- & grid_file_in = '/scratch/pwjones/grid.320x384.da',
- & grid_topo_in = '/scratch/pwjones/kmt.320x384.da',
- & grid_file_out = '/scratch/pwjones/Greenland_DP_x1p.nc'
- real (kind=dbl_kind), parameter ::
- & radius = 6370.0e5_dbl_kind ! radius of Earth (cm)
- &, area_norm = one/(radius*radius)
- !-----------------------------------------------------------------------
- !
- ! grid coordinates and masks
- !
- !-----------------------------------------------------------------------
- integer (kind=int_kind), dimension(grid_size) ::
- & grid_imask
- real (kind=dbl_kind), dimension(grid_size) ::
- & grid_area , ! area as computed in POP
- & grid_center_lat, ! lat/lon coordinates for
- & grid_center_lon ! each grid center in radians
- real (kind=dbl_kind), dimension(grid_corners,grid_size) ::
- & grid_corner_lat, ! lat/lon coordinates for
- & grid_corner_lon ! each grid corner in radians
- real (kind=dbl_kind), dimension(nx,ny) ::
- & HTN, HTE ! T-cell grid lengths
- !-----------------------------------------------------------------------
- !
- ! other local variables
- !
- !-----------------------------------------------------------------------
- integer (kind=int_kind) :: i, j, n, iunit, ocn_add, im1, jm1
- integer (kind=int_kind) ::
- & ncstat, ! general netCDF status variable
- & nc_grid_id, ! netCDF grid dataset id
- & nc_gridsize_id, ! netCDF grid size dim id
- & nc_gridcorn_id, ! netCDF grid corner dim id
- & nc_gridrank_id, ! netCDF grid rank dim id
- & nc_griddims_id, ! netCDF grid dimensions id
- & nc_grdcntrlat_id, ! netCDF grid center lat id
- & nc_grdcntrlon_id, ! netCDF grid center lon id
- & nc_grdimask_id, ! netCDF grid mask id
- & nc_gridarea_id, ! netCDF grid area id
- & nc_grdcrnrlat_id, ! netCDF grid corner lat id
- & nc_grdcrnrlon_id ! netCDF grid corner lon id
- integer (kind=int_kind), dimension(2) ::
- & nc_dims2_id ! netCDF dim id array for 2-d arrays
- real (kind=dbl_kind) :: tmplon, dxt, dyt
- !-----------------------------------------------------------------------
- !
- ! read in grid info
- ! lat/lon info is on velocity points which correspond
- ! to the NE corner (in logical space) of the grid cell.
- !
- !-----------------------------------------------------------------------
- call get_unit(iunit)
- open(unit=iunit, file=grid_topo_in, status='old',
- & form='unformatted', access='direct', recl=grid_size*4)
- read (unit=iunit,rec=1) grid_imask
- call release_unit(iunit)
- call get_unit(iunit)
- open(unit=iunit, file=grid_file_in, status='old',
- & form='unformatted', access='direct', recl=grid_size*8)
- read (unit=iunit, rec=1) grid_corner_lat(3,:)
- read (unit=iunit, rec=2) grid_corner_lon(3,:)
- read (unit=iunit, rec=3) HTN
- read (unit=iunit, rec=4) HTE
- call release_unit(iunit)
- grid_dims(1) = nx
- grid_dims(2) = ny
- !-----------------------------------------------------------------------
- !
- ! convert KMT field to integer grid mask
- !
- !-----------------------------------------------------------------------
- grid_imask = min(grid_imask, 1)
- !-----------------------------------------------------------------------
- !
- ! compute remaining corners
- !
- !-----------------------------------------------------------------------
- do j=1,ny
- do i=1,nx
- ocn_add = (j-1)*nx + i
- if (i .ne. 1) then
- im1 = ocn_add - 1
- else
- im1 = ocn_add + nx - 1
- endif
- grid_corner_lat(4,ocn_add) = grid_corner_lat(3,im1)
- grid_corner_lon(4,ocn_add) = grid_corner_lon(3,im1)
- end do
- end do
- do j=2,ny
- do i=1,nx
- ocn_add = (j-1)*nx + i
- jm1 = (j-2)*nx + i
- grid_corner_lat(2,ocn_add) = grid_corner_lat(3,jm1)
- grid_corner_lat(1,ocn_add) = grid_corner_lat(4,jm1)
- grid_corner_lon(2,ocn_add) = grid_corner_lon(3,jm1)
- grid_corner_lon(1,ocn_add) = grid_corner_lon(4,jm1)
- end do
- end do
- !-----------------------------------------------------------------------
- !
- ! mock up the lower row boundaries
- !
- !-----------------------------------------------------------------------
- do i=1,nx
- grid_corner_lat(1,i) = -pih + tiny
- grid_corner_lat(2,i) = -pih + tiny
- grid_corner_lon(1,i) = grid_corner_lon(4,i)
- grid_corner_lon(2,i) = grid_corner_lon(3,i)
- end do
- !-----------------------------------------------------------------------
- !
- ! correct for 0,2pi longitude crossings
- !
- !-----------------------------------------------------------------------
- do ocn_add=1,grid_size
- if (grid_corner_lon(1,ocn_add) > pi2)
- & grid_corner_lon(1,ocn_add) =
- & grid_corner_lon(1,ocn_add) - pi2
- if (grid_corner_lon(1,ocn_add) < 0.0)
- & grid_corner_lon(1,ocn_add) =
- & grid_corner_lon(1,ocn_add) + pi2
- do n=2,grid_corners
- tmplon = grid_corner_lon(n ,ocn_add) -
- & grid_corner_lon(n-1,ocn_add)
- if (tmplon < -three*pih) grid_corner_lon(n,ocn_add) =
- & grid_corner_lon(n,ocn_add) + pi2
- if (tmplon > three*pih) grid_corner_lon(n,ocn_add) =
- & grid_corner_lon(n,ocn_add) - pi2
- end do
- end do
- !-----------------------------------------------------------------------
- !
- ! compute ocean cell centers by averaging corner values
- !
- !-----------------------------------------------------------------------
- do ocn_add=1,grid_size
- grid_center_lat(ocn_add) = grid_corner_lat(1,ocn_add)
- grid_center_lon(ocn_add) = grid_corner_lon(1,ocn_add)
- do n=2,grid_corners
- grid_center_lat(ocn_add) = grid_center_lat(ocn_add) +
- & grid_corner_lat(n,ocn_add)
- grid_center_lon(ocn_add) = grid_center_lon(ocn_add) +
- & grid_corner_lon(n,ocn_add)
- end do
- grid_center_lat(ocn_add) = grid_center_lat(ocn_add)/
- & float(grid_corners)
- grid_center_lon(ocn_add) = grid_center_lon(ocn_add)/
- & float(grid_corners)
- if (grid_center_lon(ocn_add) > pi2)
- & grid_center_lon(ocn_add) = grid_center_lon(ocn_add) - pi2
- if (grid_center_lon(ocn_add) < 0.0)
- & grid_center_lon(ocn_add) = grid_center_lon(ocn_add) + pi2
- end do
- !-----------------------------------------------------------------------
- !
- ! compute cell areas in same way as POP
- !
- !-----------------------------------------------------------------------
- n = 0
- do j=1,ny
- if (j > 1) then
- jm1 = j-1
- else
- jm1 = 1
- endif
- do i=1,nx
- if (i > 1) then
- im1 = i-1
- else
- im1 = nx
- endif
- n = n+1
- dxt = half*(HTN(i,j) + HTN(i,jm1))
- dyt = half*(HTE(i,j) + HTE(im1,j))
- if (dxt == zero) dxt=one
- if (dyt == zero) dyt=one
- grid_area(n) = dxt*dyt*area_norm
- end do
- end do
- !-----------------------------------------------------------------------
- !
- ! set up attributes for netCDF file
- !
- !-----------------------------------------------------------------------
- !***
- !*** create netCDF dataset for this grid
- !***
- ncstat = nf_create (grid_file_out, NF_CLOBBER,
- & nc_grid_id)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_att_text (nc_grid_id, NF_GLOBAL, 'title',
- & len_trim(grid_name), grid_name)
- call netcdf_error_handler(ncstat)
- !***
- !*** define grid size dimension
- !***
- ncstat = nf_def_dim (nc_grid_id, 'grid_size', grid_size,
- & nc_gridsize_id)
- call netcdf_error_handler(ncstat)
- !***
- !*** define grid rank dimension
- !***
- ncstat = nf_def_dim (nc_grid_id, 'grid_rank', grid_rank,
- & nc_gridrank_id)
- call netcdf_error_handler(ncstat)
- !***
- !*** define grid corner dimension
- !***
- ncstat = nf_def_dim (nc_grid_id, 'grid_corners', grid_corners,
- & nc_gridcorn_id)
- call netcdf_error_handler(ncstat)
- !***
- !*** define grid dim size array
- !***
- ncstat = nf_def_var (nc_grid_id, 'grid_dims', NF_INT,
- & 1, nc_gridrank_id, nc_griddims_id)
- call netcdf_error_handler(ncstat)
- !***
- !*** define grid center latitude array
- !***
- ncstat = nf_def_var (nc_grid_id, 'grid_center_lat', NF_DOUBLE,
- & 1, nc_gridsize_id, nc_grdcntrlat_id)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_att_text (nc_grid_id, nc_grdcntrlat_id, 'units',
- & 7, 'radians')
- call netcdf_error_handler(ncstat)
- !***
- !*** define grid center longitude array
- !***
- ncstat = nf_def_var (nc_grid_id, 'grid_center_lon', NF_DOUBLE,
- & 1, nc_gridsize_id, nc_grdcntrlon_id)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_att_text (nc_grid_id, nc_grdcntrlon_id, 'units',
- & 7, 'radians')
- call netcdf_error_handler(ncstat)
- !***
- !*** define grid area array
- !***
- ncstat = nf_def_var (nc_grid_id, 'grid_area', NF_DOUBLE,
- & 1, nc_gridsize_id, nc_gridarea_id)
- call netcdf_error_handler(ncstat)
- !***
- !*** define grid mask
- !***
- ncstat = nf_def_var (nc_grid_id, 'grid_imask', NF_INT,
- & 1, nc_gridsize_id, nc_grdimask_id)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_att_text (nc_grid_id, nc_grdimask_id, 'units',
- & 8, 'unitless')
- call netcdf_error_handler(ncstat)
- !***
- !*** define grid corner latitude array
- !***
- nc_dims2_id(1) = nc_gridcorn_id
- nc_dims2_id(2) = nc_gridsize_id
- ncstat = nf_def_var (nc_grid_id, 'grid_corner_lat', NF_DOUBLE,
- & 2, nc_dims2_id, nc_grdcrnrlat_id)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_att_text (nc_grid_id, nc_grdcrnrlat_id, 'units',
- & 7, 'radians')
- call netcdf_error_handler(ncstat)
- !***
- !*** define grid corner longitude array
- !***
- ncstat = nf_def_var (nc_grid_id, 'grid_corner_lon', NF_DOUBLE,
- & 2, nc_dims2_id, nc_grdcrnrlon_id)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_att_text (nc_grid_id, nc_grdcrnrlon_id, 'units',
- & 7, 'radians')
- call netcdf_error_handler(ncstat)
- !***
- !*** end definition stage
- !***
- ncstat = nf_enddef(nc_grid_id)
- call netcdf_error_handler(ncstat)
- !-----------------------------------------------------------------------
- !
- ! write grid data
- !
- !-----------------------------------------------------------------------
- ncstat = nf_put_var_int(nc_grid_id, nc_griddims_id, grid_dims)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_var_double(nc_grid_id, nc_grdcntrlat_id,
- & grid_center_lat)
- ncstat = nf_put_var_int(nc_grid_id, nc_grdimask_id, grid_imask)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_var_double(nc_grid_id, nc_gridarea_id,
- & grid_area)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_var_double(nc_grid_id, nc_grdcntrlat_id,
- & grid_center_lat)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_var_double(nc_grid_id, nc_grdcntrlon_id,
- & grid_center_lon)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_var_double(nc_grid_id, nc_grdcrnrlat_id,
- & grid_corner_lat)
- call netcdf_error_handler(ncstat)
- ncstat = nf_put_var_double(nc_grid_id, nc_grdcrnrlon_id,
- & grid_corner_lon)
- call netcdf_error_handler(ncstat)
- ncstat = nf_close(nc_grid_id)
- !***********************************************************************
- end program convertPOPT
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|