123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !-----------------------------------------------------------------------
- ! CVS coupler.F90,v 1.8 2004-04-23 20:57:10 jacob Exp
- ! CVS MCT_2_8_0
- !BOP -------------------------------------------------------------------
- !
- ! !ROUTINE: coupler -- coupler for unit tester
- !
- ! !DESCRIPTION:
- ! A coupler subroutine to test functionality of MCT.
- !
- ! !INTERFACE:
- !
- subroutine coupler (comm,ncomps,compid)
- !
- ! !USES:
- !
- ! Get the things needed from MCT by "Use,only" with renaming:
- !
- ! ---------- first group is identical to what model.F90 uses ----
- !
- !---Component Model Registry
- use m_MCTWorld,only: MCTWorld_init => init
- use m_MCTWorld,only: MCTWorld_clean => clean
- !---Domain Decomposition Descriptor DataType and associated methods
- use m_GlobalSegMap,only: GlobalSegMap
- use m_GlobalSegMap,only: GlobalSegMap_init => init
- use m_GlobalSegMap,only: GlobalSegMap_lsize => lsize
- use m_GlobalSegMap,only: GlobalSegMap_clean => clean
- use m_GlobalSegMap,only: GlobalSegMap_Ordpnts => OrderedPoints
- !---Field Storage DataType and associated methods
- use m_AttrVect,only : AttrVect
- use m_AttrVect,only : AttrVect_init => init
- use m_AttrVect,only : AttrVect_clean => clean
- use m_AttrVect,only : AttrVect_importRAttr => importRAttr
- !---Intercomponent communications scheduler
- use m_Router,only: Router
- use m_Router,only: Router_init => init
- use m_Router,only: Router_clean => clean
- !---Intercomponent transfer
- use m_Transfer,only : MCT_Send => send
- use m_Transfer,only : MCT_Recv => recv
- ! ---------- because coupler will do the interpolation ---------
- ! it needs more methods
- !
- !---Sparse Matrix DataType and associated methods
- use m_SparseMatrix, only : SparseMatrix
- use m_SparseMatrix, only : SparseMatrix_init => init
- use m_SparseMatrix, only : SparseMatrix_importGRowInd => &
- importGlobalRowIndices
- use m_SparseMatrix, only : SparseMatrix_importGColInd => &
- importGlobalColumnIndices
- use m_SparseMatrix, only : SparseMatrix_importMatrixElts => &
- importMatrixElements
- use m_SparseMatrixPlus, only : SparseMatrixPlus
- use m_SparseMatrixPlus, only : SparseMatrixPlus_init => init
- use m_SparseMatrixPlus, only : SparseMatrixPlus_clean => clean
- use m_SparseMatrixPlus, only : Xonly ! Decompose matrix by row
- !---Matrix-Vector multiply methods
- use m_MatAttrVectMul, only: MCT_MatVecMul => sMatAvMult
- !---MPEU I/O utilities
- use m_stdio
- use m_ioutil
- implicit none
- include "mpif.h"
- ! !INPUT PARAMETERS:
- integer,intent(in) :: comm
- integer,intent(in) :: ncomps
- integer,intent(in) :: compid
- !
- !EOP ___________________________________________________________________
- ! Local variables
- character(len=*), parameter :: cplname='coupler.F90'
- integer :: nxa ! number of points in x-direction, atmos
- integer :: nya ! number of points in y-direction, atmos
- integer :: nxo ! number of points in x-direction, ocean
- integer :: nyo ! number of points in y-direction, ocean
- character(len=100),parameter :: &
- RemapMatrixFile='../../data/t42_to_popx1_c_mat.asc'
- ! Loop indicies
- integer :: i,j,k,n
- logical :: match
- ! MPI variables
- integer :: rank, nprocs, root, ierr
- ! MCTWorld variables
- integer :: AtmID
- ! Grid variables
- integer :: localsize
- ! GlobalSegMap variables
- type(GlobalSegMap) :: AtmGSMap, OcnGSMap
- integer,dimension(1) :: start,length
- integer, dimension(:), pointer :: points
- integer :: latsize, lonsize
- integer :: rowindex, colindex, boxvertex
- ! AttVect variables
- type(AttrVect) :: AtmAV, OcnAV
- integer :: aavsize,oavsize
- ! Router variables
- type(Router) :: Rout
- ! SparseMatrix variables
- integer :: mdev
- integer :: num_elements, nRows, nColumns
- integer, dimension(2) :: src_dims, dst_dims
- integer, dimension(:), pointer :: rows, columns
- real, dimension(:), pointer :: weights
- ! A2O SparseMatrix elements on root
- type(SparseMatrix) :: sMat
- ! A2O distributed SparseMatrixPlus variables
- type(SparseMatrixPlus) :: A2OMatPlus
- ! _____________________________________________________________________
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! INITIALIZATION PHASE
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- ! LOCAL RANK AND SIZE
- call MPI_COMM_RANK(comm,rank,ierr)
- call MPI_COMM_SIZE(comm,nprocs,ierr)
- root = 0
- if(rank==0) write(6,*) cplname,' MyID ', compid
- if(rank==0) write(6,*) cplname,' Num procs ', nprocs
- ! Initialize MCTworld
- call MCTWorld_init(ncomps,MPI_COMM_WORLD,comm,compid)
- ! Set the atm component id. Must be known to this
- ! component. (MCT doesn't handle that).
- AtmID=1
- ! Set grid dimensions for atmosphere and ocean grids.
- ! MCT could be used for this (by defining a GeneralGrid in
- ! each and sending them to the coupler) but for this simple
- ! example, we'll assume they're known to the coupler
- nxa = 128
- nya = 64
-
- nxo = 320
- nyo = 384
-
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Read matrix weights for interpolation from a file.
- if (rank == root) then
- mdev = luavail()
- open(mdev, file=trim(RemapMatrixFile), status="old")
- read(mdev,*) num_elements
- read(mdev,*) src_dims(1), src_dims(2)
- read(mdev,*) dst_dims(1), dst_dims(2)
-
- allocate(rows(num_elements), columns(num_elements), &
- weights(num_elements), stat=ierr)
- do n=1, num_elements
- read(mdev,*) rows(n), columns(n), weights(n)
- end do
-
- close(mdev)
- ! Initialize a Sparsematrix
- nRows = dst_dims(1) * dst_dims(2)
- nColumns = src_dims(1) * src_dims(2)
- call SparseMatrix_init(sMat,nRows,nColumns,num_elements)
- call SparseMatrix_importGRowInd(sMat, rows, size(rows))
- call SparseMatrix_importGColInd(sMat, columns, size(columns))
- call SparseMatrix_importMatrixElts(sMat, weights, size(weights))
- deallocate(rows, columns, weights, stat=ierr)
- endif
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Initialize a Global Segment Map for the Ocean
- ! Set up a 1-d decomposition.
- ! There is just 1 segment per processor
- localsize = nxo*nyo / nprocs
- ! we'll use the distributed init of GSMap so
- ! initialize start and length arrays for this processor
- start(1) = (rank*localsize) + 1
- length(1) = localsize
- ! initialize the GSMap
- call GlobalSegMap_init(OcnGSMap,start,length,root,comm,compid)
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Initialize a Global Segment Map for the Atmosphere
- ! Set up a 1-d decomposition.
- ! There is just 1 segment per processor
- localsize = nxa*nya / nprocs
- ! we'll use the distributed init of GSMap so
- ! initialize start and length arrays for this processor
- start(1) = (rank*localsize) + 1
- length(1) = localsize
- ! initialize the GSMap
- call GlobalSegMap_init(AtmGSMap,start,length,root,comm,compid)
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Use a GSMap function:
- ! return the points local to this processor
- ! in their assumed order.
- call GlobalSegMap_Ordpnts(AtmGSMap,rank,points)
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Build a SparseMatrixPlus for doing the interpolation
- ! Specify matrix decomposition to be by row.
- ! following the atmosphere's decomposition.
- call SparseMatrixPlus_init(A2OMatPlus, sMat, AtmGSMap, OcnGSMap, &
- Xonly, root, comm, compid)
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Initialize and Attribute vector the atmosphere grid
- aavsize = GlobalSegMap_lsize(AtmGSMap,comm)
- if(rank==0) write(6,*) cplname, ' localsize: Atm ', aavsize
- call AttrVect_init(AtmAV,rList="field1:field2",lsize=aavsize)
- ! Initialize and Attribute vector the ocean grid
- oavsize = GlobalSegMap_lsize(OcnGSMap,comm)
- if(rank==0) write(6,*) cplname, ' localsize: Ocn ', oavsize
- call AttrVect_init(OcnAV,rList="field1:field2",lsize=oavsize)
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Initialize a Router
- call Router_init(AtmID,AtmGSMap,comm,Rout)
- !!! END OF INIT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! RUN PHASE
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- do j=1,10 ! "timestep" loop
- ! coupler calculations here
- match=.TRUE.
- ! Receive the data
- call MCT_Recv(AtmAV,Rout)
- ! The 2nd attribute has the values of each gridpoint in
- ! the index numbering scheme. Check the received values
- ! against the points on the this processor. They should
- ! match exactly.
- do i=1,aavsize
- if( int(AtmAV%rAttr(2,i)) .ne. points(i)) then
- write(6,*) cplname,rank, " Data doesn't match ",i
- match=.FALSE.
- endif
- enddo
- if(match .and. j==10) &
- write(6,*) cplname," Last step, All points match on ",rank
- if(rank==0) write(6,*) cplname, " Received data step ",j
- ! Interpolate by doing a parallel sparsematrix-attrvect multiply
- ! Note: it doesn't make much sense to interpolate "field2" which
- ! is the grid point indicies but MatVecMul will interpolate all
- ! real attributes.
- call MCT_MatVecMul(AtmAV, A2OMatPlus, OcnAV)
- if(rank==0) write(6,*) cplname," Data transformed step ",j
- ! pass interpolated data on to ocean model and/or
- ! do more calculations
- enddo
- !!! END OF RUN !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! FINALIZE PHASE
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! deallocate memory
- call Router_clean(Rout)
- call AttrVect_clean(AtmAV)
- call AttrVect_clean(OcnAV)
- call GlobalSegMap_clean(AtmGSMap)
- call GlobalSegMap_clean(OcnGSMap)
- call MCTWorld_clean()
- if(rank==0) write(6,*) cplname, " done"
- end subroutine coupler
-
|