C -*-fortran-*- C $Header: /u/gcmpack/MITgcm/pkg/regrid/regrid_scalar_out.template,v 1.1 2006/08/15 04:05:48 edhill Exp $ C $Name: $ #include "REGRID_OPTIONS.h" C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| CBOP 0 C !ROUTINE: REGRID_SCALAR_RX_OUT C !INTERFACE: SUBROUTINE REGRID_SCALAR_RX_OUT( I mnc_bname, igout, var, vname, nz, izlev, I myThid ) C !DESCRIPTION: C Perform simple 2D scalar regrid and write the result to the C specified file C !USES: IMPLICIT NONE #include "SIZE.h" #include "EEPARAMS.h" #include "PARAMS.h" #include "REGRID_SIZE.h" #include "REGRID.h" C !INPUT PARAMETERS: C igout :: index of output grid to use C var :: variable on "standard" model grid C vname :: variable name C nz :: number of z levels C izlev :: index vector of z levels C myThid :: my thread Id number INTEGER nz __V var(1-OLx:sNx+OLx,1-OLy:sNy+OLy,nz,nSx,nSy) CHARACTER*(*) mnc_bname CHARACTER*(*) vname INTEGER izlev(nz) INTEGER igout, myThid CEOP C !LOCAL VARIABLES: C msgBuf - Informational/error meesage buffer INTEGER ILNBLNK EXTERNAL ILNBLNK C CHARACTER*(MAX_LEN_MBUF) msgBuf INTEGER iz, bi,bj, ii,ind, nval, nnb #ifdef RX_IS_REAL4 REAL*4 ptsums(REGRID_NELEM_MAX,nSx,nSy) #endif #ifdef RX_IS_REAL8 REAL*8 ptsums(REGRID_NELEM_MAX,nSx,nSy) #endif #ifdef ALLOW_MNC INTEGER CW_DIMS, NLEN PARAMETER ( CW_DIMS = 10 ) PARAMETER ( NLEN = 80 ) INTEGER offsets(CW_DIMS) INTEGER dim(CW_DIMS), ib(CW_DIMS), ie(CW_DIMS) CHARACTER*(NLEN) dn(CW_DIMS) CHARACTER*(NLEN) regrid_vname CHARACTER*(NLEN) d_cw_name CHARACTER*(NLEN) dn_blnk #endif /* ALLOW_MNC */ C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| DO ii = 1,CW_DIMS offsets(ii) = 0 ENDDO C ============================================= C Create the MNC definition for the variable #ifdef ALLOW_MNC _BEGIN_MASTER( myThid ) #ifdef ALLOW_USE_MPI IF ( mpiMyId .EQ. 0 ) THEN #endif /* ALLOW_USE_MPI */ bi = myBxLo(myThid) bj = myByLo(myThid) IF (useMNC .AND. regrid_mnc) THEN DO ii = 1,NLEN dn_blnk(ii:ii) = ' ' ENDDO dn(1)(1:NLEN) = dn_blnk(1:NLEN) WRITE(dn(1),'(a,i6.6)') 'Zrgl_', nz dim(1) = nz ib(1) = 1 ie(1) = nz CALL MNC_CW_ADD_GNAME('regrid_levels', 1, & dim, dn, ib, ie, myThid) CALL MNC_CW_ADD_VNAME('regrid_levels', 'regrid_levels', & 0,0, myThid) CALL MNC_CW_ADD_VATTR_TEXT('regrid_levels','description', & 'Idicies of vertical levels within the source arrays', & myThid) CALL MNC_CW_I_W('I',mnc_bname,bi,bj, & 'regrid_levels', izlev, myThid) CALL MNC_CW_DEL_VNAME('regrid_levels', myThid) CALL MNC_CW_DEL_GNAME('regrid_levels', myThid) d_cw_name(1:NLEN) = dn_blnk(1:NLEN) DO ii = 1,CW_DIMS dn(ii)(1:NLEN) = dn_blnk(1:NLEN) ENDDO C All the horizontal dimensions of the output grid are flattened C into a single total-DoF vector. WRITE(dn(1),'(a,i10.10)') 'regrid_', regrid_nout(igout) dim(1) = regrid_nout(igout) ib(1) = 1 ie(1) = regrid_nout(igout) C Vertical dimension dn(2)(1:NLEN) = dn_blnk(1:NLEN) WRITE(dn(2),'(a,i6.6)') 'Zrgl_', nz dim(2) = nz ib(2) = 1 ie(2) = nz C Time dimension dn(3)(1:1) = 'T' dim(3) = -1 ib(3) = 1 ie(3) = 1 C Generate unique grid names WRITE(d_cw_name,'(a3,i3.3,a1,i3.3)') 'rg_',igout,'_',nz CALL MNC_CW_ADD_GNAME(d_cw_name, 3, & dim, dn, ib, ie, myThid) regrid_vname(1:NLEN) = dn_blnk(1:NLEN) write(regrid_vname,'(a,a)') 'regrid_', vname CALL MNC_CW_ADD_VNAME(regrid_vname, d_cw_name, & 0,0, myThid) C CALL MNC_CW_ADD_VATTR_TEXT(vname,'units','-',myThid) ENDIF #ifdef ALLOW_USE_MPI ENDIF #endif /* ALLOW_USE_MPI */ _END_MASTER( myThid ) _BARRIER #endif /* ALLOW_MNC */ C ============================================= C Empty the per-thread vectors for all possible threads _BEGIN_MASTER( myThid ) DO bj = 1,nSy DO bi = 1,nSx DO ind = 1,regrid_nout(igout) ptsums( ind, bi,bj ) = 0. _d 0 ENDDO ENDDO ENDDO _END_MASTER( myThid ) _BARRIER C ============================================= C Compute the distributed sparse matrix multiply DO iz = 1,nz DO bj = myByLo(myThid), myByHi(myThid) DO bi = myBxLo(myThid), myBxHi(myThid) DO ind = 1,regrid_nout(igout) ptsums( ind, bi,bj ) = 0. _d 0 ENDDO C Compute the per-thread partial sums DO ind = regrid_ibeg(igout,bi,bj),regrid_iend(igout,bi,bj) ptsums( regrid_i_out(ind,bi,bj), bi,bj ) = & ptsums( regrid_i_out(ind,bi,bj), bi,bj ) & + regrid_amat(ind,bi,bj) & * var( regrid_i_loc(ind,bi,bj), & regrid_j_loc(ind,bi,bj), izlev(iz), bi,bj) ENDDO C Sum over all threads and MPI processes nval = regrid_nout(igout) ENDDO ENDDO _BARRIER #ifdef RX_IS_REAL4 CALL GLOBAL_VEC_SUM_R4( REGRID_NELEM_MAX,nval,ptsums,myThid ) #endif #ifdef RX_IS_REAL8 CALL GLOBAL_VEC_SUM_R8( REGRID_NELEM_MAX,nval,ptsums,myThid ) #endif C At this point, we have the global sum. The master thread of the C lead MPI process should now write the output. _BEGIN_MASTER( myThid ) #ifdef ALLOW_USE_MPI IF ( mpiMyId .EQ. 0 ) THEN #endif /* ALLOW_USE_MPI */ bi = myBxLo(myThid) bj = myByLo(myThid) offsets(2) = iz CALL MNC_CW_RL_W_OFFSET('D',mnc_bname,1,1, & regrid_vname, ptsums(1,bi,bj), offsets, myThid) #ifdef ALLOW_USE_MPI ENDIF #endif /* ALLOW_USE_MPI */ _END_MASTER( myThid ) _BARRIER ENDDO /* iz */ CALL MNC_CW_DEL_VNAME(regrid_vname, myThid) CALL MNC_CW_DEL_GNAME(d_cw_name, myThid) RETURN END C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|