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

📄 bndexch.f90

📁 CCSM Research Tools: Community Atmosphere Model (CAM)
💻 F90
字号:
#include <misc.h>#include <params.h>subroutine bndexch!----------------------------------------------------------------------- ! ! Purpose: Pack and Exchange initial prognostic information among all the !          processors!! Method: ! ! Author: ! !-----------------------------------------------------------------------! $Id: bndexch.F90,v 1.5 2001/10/05 16:39:41 boville Exp $! $Author: boville $!!----------------------------Parameters---------------------------------#ifdef SPMD  use pmgrid, only: iam  use spmd_dyn, only: npes, cut, cutex, neighs, neighn  implicit none!! Local workspace!  integer ns, nn  integer inreg( 2 )  integer outreg( 2 )  integer others,othern   ! Other node!! Return if number of processors is less than 2!  if (npes .lt. 2) return!! For each partition (south and north) communicate boundaries! on each side of partition among however many neighbors necessary!! send south, receive north!  ns = 1  nn = 1  do while (ns .le. neighs .or. nn .le. neighn)     if (ns .le. neighs) then        others = iam - ns!! Intersection of my cuts and neighbor processor's extended! cuts tells if this node needs to send data to neighbor !        call intersct(cut(1,iam),cutex(1,others),outreg)          ns = ns + 1     else        others = -1        outreg(1) = 0        outreg(2) = 0     end if     if (nn .le. neighn) then        othern = iam + nn!! Intersection of neighbor cuts and this node's extended! cut tells if this node recieves data from neighbor !        call intersct(cut(1,othern),cutex(1,iam),inreg)          nn = nn + 1     else        othern = -1        inreg(1) = 0        inreg(2) = 0     end if     call bndexch_mpi(others,outreg,othern,inreg)  end do!! send north, receive south!  ns = 1  nn = 1  do while (ns .le. neighs .or. nn .le. neighn)     if (nn .le. neighn) then        othern = iam + nn!! Intersection of my cuts and neighbor processor's extended! cuts tells if this node needs to send data to neighbor !        call intersct(cut(1,iam),cutex(1,othern),outreg)          nn = nn + 1     else        othern = -1        outreg(1) = 0        outreg(2) = 0     end if     if (ns .le. neighs) then        others = iam - ns!! Intersection of neighbor cuts and this node's extended! cut tells if this node recieves data from neighbor !        call intersct(cut(1,others),cutex(1,iam),inreg)          ns = ns + 1     else        others = -1        inreg(1) = 0        inreg(2) = 0     end if     call bndexch_mpi(othern,outreg,others,inreg)  end do#endif  returnend subroutine bndexch#ifdef SPMDsubroutine bndexch_mpi(othero,outreg,otheri,inreg)!-----------------------------------------------------------------------! Send initial prognostic information to my peer process!-----------------------------------------------------------------------  use pmgrid, only: plat, plndlv, j1  use constituents, only: pcnst  use prognostics,  only: u3, v3, qminus, n3m1  use mpishorthand  implicit none  integer, parameter :: msgtype = 6000  integer, parameter :: j1m = j1 - 1  integer, parameter :: siz = (2 + pcnst)*plndlv  integer othero,outreg(2),otheri,inreg(2)  integer num  integer msg  integer reqs(3*(plat+1))  integer stats(MPI_STATUS_SIZE, 3*(plat+1))  integer reqr(3*(plat+1))  integer statr(MPI_STATUS_SIZE, 3*(plat+1))  integer i,j  integer reqs_i,reqr_i  reqs_i = 0  if (othero .ne. -1) then     do i = outreg(1), outreg(2)        j = 3*(i-outreg(1))        msg = msgtype + j        reqs_i = reqs_i + 1        call mpiisend (u3(1,1,j1m+i,n3m1),plndlv,mpir8, othero,msg,mpicom,reqs(reqs_i))        msg = msgtype + j + 1        reqs_i = reqs_i + 1        call mpiisend (v3(1,1,j1m+i,n3m1),plndlv,mpir8, othero,msg,mpicom,reqs(reqs_i))        msg = msgtype + j + 2        reqs_i = reqs_i + 1        num = pcnst*plndlv        call mpiisend (qminus(1,1,1,j1m+i),num,mpir8, othero,msg,mpicom,reqs(reqs_i))                  end do  end if  reqr_i = 0  if (otheri .ne. -1) then     do i = inreg(1), inreg(2)        j = 3*(i-inreg(1))        msg = msgtype + j        reqr_i = reqr_i + 1        call mpiirecv (u3(1,1,j1m+i,n3m1),plndlv,mpir8, otheri,msg,mpicom,reqr(reqr_i))        msg = msgtype + j + 1        reqr_i = reqr_i + 1        call mpiirecv (v3(1,1,j1m+i,n3m1),plndlv,mpir8, otheri,msg,mpicom,reqr(reqr_i))        msg = msgtype + j + 2        reqr_i = reqr_i + 1        num = pcnst*plndlv        call mpiirecv (qminus(1,1,1,j1m+i),num,mpir8, otheri,msg,mpicom,reqr(reqr_i))                  end do  end if  if (reqs_i .ne. 0) then     call mpiwaitall(reqs_i,reqs,stats)  end if  if (reqr_i .ne. 0) then     call mpiwaitall(reqr_i,reqr,statr)  end if  returnend subroutine bndexch_mpisubroutine intersct (regiona, regionb, regionc)!----------------------------------------------------------------------- ! ! Purpose: ! ! Method: ! Given two regions (a,b) output the intersection (common latitudes)  ! of these two sets.  The routine is used in bndexch to determine which! latitudes need to be communicated to neighboring processors.  Typically! this routine is invoked as the intersection of the set of resident ! latitudes on processor A with the set of extended latitudes (needed for ! the SLT) of processor B.  Any common latitudes will need to be ! communicated to B to complete SLT processing. ! ! Author: ! Original version:  CCM2! Standardized:      J. Rosinski, Oct 1995!                    J. Truesdale, Feb. 1996!-----------------------------------------------------------------------!! $Id: bndexch.F90,v 1.5 2001/10/05 16:39:41 boville Exp $! $Author: boville $!!----------------------------Commons------------------------------------  implicit none!!---------------------------Local workspace-----------------------------!  integer regiona( 2 ),regionb( 2 ),regionc( 2 )!!-----------------------------------------------------------------------!  regionc( 1 ) = max( regiona( 1 ), regionb( 1 ) )  regionc( 2 ) = min( regiona( 2 ), regionb( 2 ) )  returnend subroutine intersct#endif

⌨️ 快捷键说明

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