C $Header: /u/gcmpack/MITgcm/pkg/mnc/mnc_cw_cvars.F,v 1.16 2011/05/23 01:08:22 jmc Exp $ C $Name: $ #include "MNC_OPTIONS.h" C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| CBOP 1 C !ROUTINE: MNC_CW_WRITE_CVAR C !INTERFACE: SUBROUTINE MNC_CW_WRITE_CVAR( I fname, I cvname, I fid, I did, I bi, bj, I myThid ) C !DESCRIPTION: C Write a CF-convention coordinate variable (a vector). C !USES: implicit none #include "MNC_COMMON.h" #include "SIZE.h" #include "EEPARAMS.h" #include "PARAMS.h" #include "GRID.h" #ifdef ALLOW_EXCH2 #include "W2_EXCH2_SIZE.h" #include "W2_EXCH2_TOPOLOGY.h" #endif #include "netcdf.inc" C Functions integer IFNBLNK, ILNBLNK C !INPUT PARAMETERS: character*(*) fname character*(*) cvname integer fid, did, bi,bj integer myThid CEOP C !LOCAL VARIABLES: integer i, vid, nnf, nnl, doit, err integer nids, cv_did(1), xtmin,ytmin character*(MAX_LEN_MBUF) msgbuf integer cv_start(1), cv_count(1) _RS rtmp(sNx + 2*OLx + sNy + 2*OLy + Nr) C variables for text attributes integer MAX_LEN_NAME, ia PARAMETER ( MAX_LEN_NAME = 128 ) character*(MAX_LEN_NAME) units, long_name, positive DO i=1,MAX_LEN_NAME units(i:i) = ' ' long_name(i:i) = ' ' positive(i:i) = ' ' ENDDO nnf = IFNBLNK(cvname) nnl = ILNBLNK(cvname) xtmin = 0 ytmin = 0 #ifdef ALLOW_EXCH2 xtmin = exch2_tbasex(W2_myTileList(bi,bj)) ytmin = exch2_tbasey(W2_myTileList(bi,bj)) #else IF ( .NOT. useCubedSphereExchange ) THEN C make sure for a non-cubed-sphere curvi-linear grid, C that the X/Y coordinate variables are monotonous C bi+(myXGlobalLo-1)/sNx is the i-tile number C bj+(myYGlobalLo-1)/sNy is the j-tile number xtmin = sNx * ( bi+(myXGlobalLo-1)/sNx - 1 ) ytmin = sNy * ( bj+(myYGlobalLo-1)/sNy - 1 ) ENDIF #endif doit = 1 nids = 1 cv_did(1)= did C Check all the coordinate variables that we know about IF (cvname(nnf:nnl) .EQ. 'X') THEN cv_start(1) = 1 cv_count(1) = sNx #ifdef ALLOW_EXCH2 DO i = cv_start(1),cv_count(1) rtmp(i) = xtmin + i ENDDO #else IF ( usingCurvilinearGrid .OR. rotateGrid ) THEN DO i = cv_start(1),cv_count(1) rtmp(i) = xtmin + i ENDDO ELSE DO i = cv_start(1),cv_count(1) rtmp(i) = xC(i,1,bi,bj) ENDDO ENDIF #endif IF ( usingCartesianGrid ) THEN long_name = 'X-coordinate of cell center' units = 'meters' ELSEIF ( usingCurvilinearGrid .OR. rotateGrid ) THEN long_name = 'i-index of cell center' units = 'none' ELSEIF ( usingSphericalPolarGrid ) THEN long_name = 'longitude of cell center' units = 'degrees_east' ELSEIF ( usingCylindricalGrid ) THEN long_name = 'polar angle coordinate of cell center' units = 'degrees' ELSE C unknown grid type print *, 'S/R MNC_CW_CVARS: Ooops, unknown horizontal grid!' ENDIF ELSEIF (cvname(nnf:nnl) .EQ. 'Xp1') THEN cv_start(1) = 1 cv_count(1) = sNx + 1 #ifdef ALLOW_EXCH2 DO i = cv_start(1),cv_count(1) rtmp(i) = xtmin + i ENDDO #else IF ( usingCurvilinearGrid .OR. rotateGrid ) THEN DO i = cv_start(1),cv_count(1) rtmp(i) = xtmin + i ENDDO ELSE DO i = cv_start(1),cv_count(1) rtmp(i) = xG(i,1,bi,bj) ENDDO ENDIF #endif IF ( usingCartesianGrid ) THEN long_name = 'X-Coordinate of cell corner' units = 'meters' ELSEIF ( usingCurvilinearGrid .OR. rotateGrid ) THEN long_name = 'i-index of cell corner' units = 'none' ELSEIF ( usingSphericalPolarGrid ) THEN long_name = 'longitude of cell corner' units = 'degrees_east' ELSEIF ( usingCylindricalGrid ) THEN long_name = 'polar angle of cell corner' units = 'degrees' ELSE C unknown grid type print *, 'S/R MNC_CW_CVARS: Ooops, unknown horizontal grid!' ENDIF ELSEIF (cvname(nnf:nnl) .EQ. 'Xwh') THEN cv_start(1) = 1 cv_count(1) = sNx + 2*OLx #ifdef ALLOW_EXCH2 DO i = cv_start(1),cv_count(1) rtmp(i) = xtmin + i ENDDO #else IF ( usingCurvilinearGrid .OR. rotateGrid ) THEN DO i = cv_start(1),cv_count(1) rtmp(i) = xtmin - OLx + i ENDDO ELSE DO i = cv_start(1),cv_count(1) rtmp(i) = xC(i,1,bi,bj) CML???? rtmp(i) = xC(i-Olx,1,bi,bj) ENDDO ENDIF #endif IF ( usingCartesianGrid ) THEN long_name = 'X-Coordinate of cell center including overlaps' units = 'meters' ELSEIF ( usingCurvilinearGrid .OR. rotateGrid ) THEN long_name = 'i-index of cell center including overlaps' units = 'none' ELSEIF ( usingSphericalPolarGrid ) THEN long_name = 'longitude of cell center including overlaps' units = 'degrees_east' ELSEIF ( usingCylindricalGrid ) THEN long_name = & 'polar angle coordinate of cell center including overlaps' units = 'degrees' ELSE C unknown grid type print *, 'S/R MNC_CW_CVARS: Ooops, unknown horizontal grid!' ENDIF ELSEIF (cvname(nnf:nnl) .EQ. 'Y') THEN cv_start(1) = 1 cv_count(1) = sNy #ifdef ALLOW_EXCH2 DO i = cv_start(1),cv_count(1) rtmp(i) = ytmin + i ENDDO #else IF ( usingCurvilinearGrid .OR. rotateGrid ) THEN DO i = cv_start(1),cv_count(1) rtmp(i) = ytmin + i ENDDO ELSE DO i = cv_start(1),cv_count(1) rtmp(i) = yC(1,i,bi,bj) ENDDO ENDIF #endif IF ( usingCartesianGrid ) THEN long_name = 'Y-Coordinate of cell center' units = 'meters' ELSEIF ( usingCurvilinearGrid .OR. rotateGrid ) THEN long_name = 'j-index of cell center' units = 'none' ELSEIF ( usingSphericalPolarGrid ) THEN long_name = 'latitude of cell center' units = 'degrees_north' ELSEIF ( usingCylindricalGrid ) THEN long_name = 'radial coordinate of cell center' units = 'meters' ELSE C unknown grid type print *, 'S/R MNC_CW_CVARS: Ooops, unknown horizontal grid!' ENDIF ELSEIF (cvname(nnf:nnl) .EQ. 'Yp1') THEN cv_start(1) = 1 cv_count(1) = sNy + 1 #ifdef ALLOW_EXCH2 DO i = cv_start(1),cv_count(1) rtmp(i) = ytmin + i ENDDO #else IF ( usingCurvilinearGrid .OR. rotateGrid ) THEN DO i = cv_start(1),cv_count(1) rtmp(i) = ytmin + i ENDDO ELSE DO i = cv_start(1),cv_count(1) rtmp(i) = yG(1,i,bi,bj) ENDDO ENDIF #endif IF ( usingCartesianGrid ) THEN long_name = 'Y-Coordinate of cell corner' units = 'meters' ELSEIF ( usingCurvilinearGrid .OR. rotateGrid ) THEN long_name = 'j-index of cell corner' units = 'none' ELSEIF ( usingSphericalPolarGrid ) THEN long_name = 'latitude of cell corner' units = 'degrees_north' ELSEIF ( usingCylindricalGrid ) THEN long_name = 'radial coordinate of cell corner' units = 'meters' ELSE C unknown grid type print *, 'S/R MNC_CW_CVARS: Ooops, unknown horizontal grid!' ENDIF ELSEIF (cvname(nnf:nnl) .EQ. 'Ywh') THEN cv_start(1) = 1 cv_count(1) = sNy + 2*OLy #ifdef ALLOW_EXCH2 DO i = cv_start(1),cv_count(1) rtmp(i) = ytmin + i ENDDO #else IF ( usingCurvilinearGrid .OR. rotateGrid ) THEN DO i = cv_start(1),cv_count(1) rtmp(i) = ytmin - OLy + i ENDDO ELSE DO i = cv_start(1),cv_count(1) rtmp(i) = yC(1,i-OLy,bi,bj) ENDDO ENDIF #endif IF ( usingCartesianGrid ) THEN long_name = 'Y-Coordinate of cell center including overlaps' units = 'meters' ELSEIF ( usingCurvilinearGrid .OR. rotateGrid ) THEN long_name = 'j-index of cell center including overlaps' units = 'none' ELSEIF ( usingSphericalPolarGrid ) THEN long_name = 'latitude of cell center including overlaps' units = 'degrees_north' ELSEIF ( usingCylindricalGrid ) THEN long_name = & 'radial coordinate of cell center including overlaps' units = 'meters' ELSE C unknown grid type print *, 'S/R MNC_CW_CVARS: Ooops, unknown horizontal grid!' ENDIF ELSEIF (cvname(nnf:nnl) .EQ. 'Z') THEN cv_start(1) = 1 cv_count(1) = Nr DO i = cv_start(1),cv_count(1) rtmp(i) = rC(i) ENDDO C long_name = 'vertical coordinate of cell center' IF ( usingZCoords ) THEN units = 'meters' positive = 'up' ELSEIF ( usingPCoords ) THEN units = 'pascal' ELSE C unknown grid type print *, 'S/R MNC_CW_CVARS: Ooops, unknown vertical grid!' ENDIF ELSEIF (cvname(nnf:nnl) .EQ. 'Zp1') THEN cv_start(1) = 1 cv_count(1) = Nr + 1 DO i = cv_start(1),cv_count(1) rtmp(i) = rF(i) ENDDO C long_name = 'vertical coordinate of cell interface' IF ( usingZCoords ) THEN units = 'meters' positive = 'up' ELSEIF ( usingPCoords ) THEN units = 'pascal' ELSE C unknown grid type print *, 'S/R MNC_CW_CVARS: Ooops, unknown vertical grid!' ENDIF ELSEIF (cvname(nnf:nnl) .EQ. 'Zu') THEN cv_start(1) = 1 cv_count(1) = Nr DO i = cv_start(1),cv_count(1) rtmp(i) = rF(i + 1) ENDDO C IF ( usingZCoords ) THEN long_name = 'vertical coordinate of lower cell interface' units = 'meters' positive = 'up' ELSEIF ( usingPCoords ) THEN long_name = 'vertical coordinate of upper cell interface' units = 'pascal' ELSE C unknown grid type print *, 'S/R MNC_CW_CVARS: Ooops, unknown vertical grid!' ENDIF ELSEIF (cvname(nnf:nnl) .EQ. 'Zl') THEN cv_start(1) = 1 cv_count(1) = Nr DO i = cv_start(1),cv_count(1) rtmp(i) = rF(i) ENDDO C IF ( usingZCoords ) THEN long_name = 'vertical coordinate of upper cell interface' units = 'meters' positive = 'up' ELSEIF ( usingPCoords ) THEN long_name = 'vertical coordinate of lower cell interface' units = 'pascal' ELSE C unknown grid type print *, 'S/R MNC_CW_CVARS: Ooops, unknown vertical grid!' ENDIF ELSEIF (cvname(nnf:nnl) .EQ. 'Zm1') THEN cv_start(1) = 1 cv_count(1) = Nr - 1 DO i = cv_start(1),cv_count(1) rtmp(i) = rF(i + 1) ENDDO C IF ( usingZCoords ) THEN long_name = 'vertical coordinate of lower cell interface' units = 'meters' positive = 'up' ELSEIF ( usingPCoords ) THEN long_name = 'vertical coordinate of upper cell interface' units = 'pascal' ELSE C unknown grid type print *, 'S/R MNC_CW_CVARS: Ooops, unknown vertical grid!' ENDIF ELSE doit = 0 ENDIF IF ( doit .EQ. 1 ) THEN CALL MNC_FILE_REDEF(fname, myThid) #ifdef REAL4_IS_SLOW err = NF_DEF_VAR(fid, cvname, NF_DOUBLE, & nids, cv_did, vid) #else err = NF_DEF_VAR(fid, cvname, NF_FLOAT, & nids, cv_did, vid) #endif /* REAL4_IS_SLOW */ i = ILNBLNK( fname ) write(msgbuf,'(5a)') 'defining coordinate variable ''', & cvname(nnf:nnl), ''' in file ''', fname(1:i), '''' CALL MNC_HANDLE_ERR(err, msgbuf, myThid) C add attributes if set ia = ILNBLNK(long_name) IF ( ia .GT. 0 ) THEN err = NF_PUT_ATT_TEXT(fid, vid, 'long_name', ia, long_name) write(msgbuf,'(5a)') & 'adding attribute ''long_name'' to coordinate variable ''', & cvname(nnf:nnl), ''' in file ''', fname(1:i), '''' CALL MNC_HANDLE_ERR(err, msgbuf, myThid) ENDIF ia = ILNBLNK(units) IF ( ia .GT. 0 ) THEN err = NF_PUT_ATT_TEXT(fid, vid, 'units', ia, units) write(msgbuf,'(5a)') & 'adding attribute ''units'' to coordinate variable ''', & cvname(nnf:nnl), ''' in file ''', fname(1:i), '''' CALL MNC_HANDLE_ERR(err, msgbuf, myThid) ENDIF ia = ILNBLNK(positive) IF ( ia .GT. 0 ) THEN err = NF_PUT_ATT_TEXT(fid, vid, 'positive', ia, positive) write(msgbuf,'(5a)') & 'adding attribute ''positive'' to coordinate variable ''', & cvname(nnf:nnl), ''' in file ''', fname(1:i), '''' CALL MNC_HANDLE_ERR(err, msgbuf, myThid) ENDIF C CALL MNC_FILE_ENDDEF(fname, myThid) #ifdef REAL4_IS_SLOW err = NF_PUT_VARA_DOUBLE(fid, vid, & cv_start, cv_count, rtmp) #else err = NF_PUT_VARA_REAL(fid, vid, & cv_start, cv_count, rtmp) #endif /* REAL4_IS_SLOW */ write(msgbuf,'(5a)') 'writing coordinate variable ''', & cvname(nnf:nnl), ''' in file ''', fname(1:i), '''' CALL MNC_HANDLE_ERR(err, msgbuf, myThid) ENDIF RETURN END C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|