⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d2a3dijk.f90

📁 CCSM Research Tools: Community Atmosphere Model (CAM)
💻 F90
字号:
#include <misc.h>!-----------------------------------------------------------------------!BOP! !ROUTINE: d2a3ijk -- Generalized 2nd order D-to-A grid transform (3D)!                      Output array is i,j,k!! !INTERFACE:      subroutine d2a3dijk(u, v, ua, va, im, jm, ktot,                   &                           jfirst, jlast, ng_d, ngus, ngun, ngvs, ngvn,  &                          ifirst, ilast, coslon, sinlon)! !USES:      use precision      use pmgrid, only : twod_decomp, myid_y, myidxy_y, myidxy_x, &                         nprxy_x, iam#if defined( SPMD )      use spmd_dyn, only: comm_y, commxy_y, commxy_x      use parutilitiesmodule, only : parcollective3d, sumop      use mod_comm, only: bufferpack3d, bufferunpack2d, buff_s, buff_r, &                          mp_send, mp_recv, mp_barrier#endif      implicit none! !INPUT PARAMETERS:      integer, intent(in)  :: im      ! Dimensions longitude (total)      integer, intent(in)  :: jm      ! Dimensions latitude (total)      integer, intent(in)  :: ktot    ! Dimensions vertical (strip)      integer, intent(in)  :: jfirst  ! latitude strip start      integer, intent(in)  :: jlast   ! latitude strip finish      integer, intent(in)  :: ng_d    ! ghost latitudes on D grid      integer, intent(in)  :: ngus    ! ghost latitudes on U south      integer, intent(in)  :: ngun    ! ghost latitudes on U north      integer, intent(in)  :: ngvs    ! ghost latitudes on V south      integer, intent(in)  :: ngvn    ! ghost latitudes on V north      integer, intent(in)  :: ifirst  ! longitude strip start      integer, intent(in)  :: ilast   ! longitude strip finish      real(r8), intent(in) :: u(ifirst:ilast,jfirst-ngus:jlast+ngun,ktot) ! U-Wind ghosted N1      real(r8), intent(in) :: v(ifirst:ilast,jfirst-ngvs:jlast+ngvn,ktot) ! V-Wind      real(r8) coslon(im),sinlon(im)  ! Sine and cosine in longitude! !INPUT/OUTPUT PARAMETERS:      real(r8), intent(inout) :: ua(ifirst:ilast,jfirst:jlast,ktot) ! U-Wind      real(r8), intent(inout) :: va(ifirst:ilast,jfirst:jlast,ktot) ! V-Wind! !DESCRIPTION:!!     This routine performs a second order !     interpolation of three-dimensional wind!     fields on a D grid to an A grid.  !!! !REVISION HISTORY:!     WS  00.12.22 : Creation from d2a3d!     AAM 01.06.13 : Generalized to 2D decomposition!!EOP!-----------------------------------------------------------------------!BOC      integer imh, i, j, k, itot, jtot, ltot, lbegin, lend, ik      real(r8) un(ktot), vn(ktot), us(ktot), vs(ktot)      real(r8) veast(jfirst:jlast,ktot),unorth(ifirst:ilast,ktot)      real(r8) uvaglob(im,ktot,4),uvaloc(ifirst:ilast,ktot,4)      real(r8) uaglob(im),vaglob(im)#if defined( SPMD )      integer dest, src, incount, outcount#endif      itot = ilast-ifirst+1      jtot = jlast-jfirst+1      imh = im/2#if defined( SPMD )! Set ua on A-grid      incount  = 0      outcount = 0      if ( jfirst > 1 ) then         call bufferpack3d( u,ifirst,ilast,jfirst-ngus,jlast+ngun,1,ktot,&                             ifirst, ilast,jfirst,jfirst,1,ktot,buff_s )         incount  = itot*ktot      endif      if ( jlast < jm ) then         outcount = itot*ktot      endif      call mp_barrier()      call mp_send(iam-nprxy_x, iam+nprxy_x, incount, outcount,   &                   buff_s, buff_r)      call mp_barrier()      call mp_recv(iam+nprxy_x, outcount, buff_r)      if ( jlast .lt. jm ) then         call bufferunpack2d( unorth, ifirst, ilast, 1, ktot, ifirst,   &                              ilast, 1, ktot, buff_r)!$omp  parallel do private(i, k)         do k=1,ktot            do i=ifirst,ilast               ua(i,jlast,k) = 0.5 * ( u(i,jlast,k) + unorth(i,k) )            enddo         enddo      endif#endif!$omp  parallel do private(i,j,k)      do k=1,ktot        do j=jfirst, jlast-1          do i=ifirst,ilast            ua(i,j,k) = 0.5*(u(i,j,k) + u(i,j+1,k))          enddo        enddo      enddo! Set va on A-grid!$omp  parallel do private(j,k)      do k = 1,ktot         do j=jfirst,jlast            veast(j,k) = v(ifirst,j,k)         enddo      enddo#if defined( SPMD )      if (itot .ne. im) then         dest = myidxy_y*nprxy_x + MOD(iam+nprxy_x-1,nprxy_x)         src  = myidxy_y*nprxy_x + MOD(iam+1,nprxy_x)         call bufferpack3d(v,ifirst,ilast,jfirst-ngvs,jlast+ngvn,1,ktot,ifirst,ifirst,    &                           jfirst,jlast,1,ktot,buff_s)         call mp_barrier()         call mp_send(dest,src,jtot*ktot,jtot*ktot,buff_s,buff_r)         call mp_barrier()         call mp_recv(src,jtot*ktot,buff_r)         call bufferunpack2d(veast,jfirst,jlast,1,ktot,jfirst,jlast,1,ktot,buff_r)      endif#endif!$omp  parallel do private(i,j,k)      do k=1,ktot         do j=jfirst, jlast            do i=ifirst,ilast-1               va(i,j,k) = 0.5*(v(i,j,k) + v(i+1,j,k))            enddo            va(ilast,j,k) = 0.5*(v(ilast,j,k) + veast(j,k))         enddo      enddo!$omp  parallel do private(i,ik,k)      do ik=1,4         do k=1,ktot            do i=1,im               uvaglob(i,k,ik) = 0.            enddo         enddo      enddo      if (jfirst .eq. 1) then!$omp  parallel do private(i,k)         do k = 1,ktot            do i=ifirst,ilast               uvaloc(i,k,1) = ua(i,2,k)               uvaloc(i,k,2) = va(i,2,k)               uvaglob(i,k,1) = ua(i,2,k)               uvaglob(i,k,2) = va(i,2,k)            enddo         enddo         lbegin = 1         lend = 2      endif      if (jlast .eq. jm) then!$omp  parallel do private(i,k)         do k = 1,ktot            do i=ifirst,ilast               uvaloc(i,k,3) = ua(i,jm-1,k)               uvaloc(i,k,4) = va(i,jm-1,k)               uvaglob(i,k,3) = ua(i,jm-1,k)               uvaglob(i,k,4) = va(i,jm-1,k)            enddo         enddo         lbegin = 3         lend = 4      endif      if (jtot .eq. jm) lbegin=1#if defined( SPMD )      if (itot .ne. im) then         ltot = lend-lbegin+1         if (jfirst .eq. 1 .or. jlast .eq. jm) then            call parcollective3d(commxy_x, sumop, im, ktot, ltot, uvaglob(1,1,lbegin))         endif      endif#endif      if ( jfirst .eq. 1 ) then! Projection at SP!$omp  parallel do private(i,k,uaglob,vaglob)         do k=1,ktot            us(k) = 0.            vs(k) = 0.            do i=1,imh               us(k) = us(k) + (uvaglob(i+imh,k,1)-uvaglob(i,k,1))*sinlon(i)  &                     + (uvaglob(i,k,2)-uvaglob(i+imh,k,2))*coslon(i)               vs(k) = vs(k) + (uvaglob(i+imh,k,1)-uvaglob(i,k,1))*coslon(i)  &                      + (uvaglob(i+imh,k,2)-uvaglob(i,k,2))*sinlon(i)            enddo            us(k) = us(k)/im            vs(k) = vs(k)/im            do i=1,imh               uaglob(i)   = -us(k)*sinlon(i) - vs(k)*coslon(i)               vaglob(i)   =  us(k)*coslon(i) - vs(k)*sinlon(i)               uaglob(i+imh) = -uaglob(i)               vaglob(i+imh) = -vaglob(i)            enddo            do i=ifirst,ilast               ua(i,1,k) = uaglob(i)               va(i,1,k) = vaglob(i)            enddo         enddo      endif      if ( jlast .eq. jm ) then! Projection at NP!$omp  parallel do private(i,k,uaglob,vaglob)         do k=1,ktot            un(k) = 0.            vn(k) = 0.            do i=1,imh               un(k) = un(k) + (uvaglob(i+imh,k,3)-uvaglob(i,k,3))*sinlon(i) &                     + (uvaglob(i+imh,k,4)-uvaglob(i,k,4))*coslon(i)               vn(k) = vn(k) + (uvaglob(i,k,3)-uvaglob(i+imh,k,3))*coslon(i) &                     + (uvaglob(i+imh,k,4)-uvaglob(i,k,4))*sinlon(i)            enddo            un(k) = un(k)/im            vn(k) = vn(k)/im            do i=1,imh               uaglob(i) = -un(k)*sinlon(i) + vn(k)*coslon(i)               vaglob(i) = -un(k)*coslon(i) - vn(k)*sinlon(i)               uaglob(i+imh) = -uaglob(i)               vaglob(i+imh) = -vaglob(i)            enddo            do i=ifirst,ilast               ua(i,jm,k) = uaglob(i)               va(i,jm,k) = vaglob(i)            enddo         enddo      endif      return!EOC      end!-----------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -