! $Id: ESMF_Grid.F90,v 1.246 2011/07/13 04:11:01 rokuingh Exp $ ! ! Earth System Modeling Framework ! Copyright 2002-2011, University Corporation for Atmospheric Research, ! Massachusetts Institute of Technology, Geophysical Fluid Dynamics ! Laboratory, University of Michigan, National Centers for Environmental ! Prediction, Los Alamos National Laboratory, Argonne National Laboratory, ! NASA Goddard Space Flight Center. ! Licensed under the University of Illinois-NCSA License. ! !============================================================================== ! #define ESMF_FILENAME "ESMF_Grid.F90" ! ! ESMF Grid Module module ESMF_GridMod ! !============================================================================== ! ! This file contains the Grid class definition and all Grid class ! methods. ! !------------------------------------------------------------------------------ ! INCLUDES #include "ESMF.h" !============================================================================== !BOPI ! !MODULE: ESMF_GridMod - Grid class ! ! !DESCRIPTION: ! ! The code in this file implements the {\tt ESMF\_Grid} class. ! !------------------------------------------------------------------------------ ! !USES: use ESMF_UtilTypesMod use ESMF_BaseMod ! ESMF base class use ESMF_LogErrMod use ESMF_ArrayMod use ESMF_ArrayBundleMod use ESMF_RHandleMod use ESMF_LocalArrayMod ! ESMF local array class use ESMF_InitMacrosMod ! ESMF initializer macros use ESMF_LogErrMod ! ESMF error handling use ESMF_VMMod use ESMF_DELayoutMod use ESMF_StaggerLocMod use ESMF_DistGridMod use ESMF_F90InterfaceMod ! ESMF F90-C++ interface helper use ESMF_ArraySpecMod use ESMF_IOScripMod ! NEED TO ADD MORE HERE implicit none !------------------------------------------------------------------------------ ! !PRIVATE TYPES: private !------------------------------------------------------------------------------ ! ! ESMF_Grid ! !------------------------------------------------------------------------------ ! F90 class type to hold pointer to C++ object type ESMF_Grid sequence type(ESMF_Pointer) :: this ESMF_INIT_DECLARE end type !------------------------------------------------------------------------------ ! ! ESMF_GridStatus_Flag ! !------------------------------------------------------------------------------ type ESMF_GridStatus_Flag sequence ! private integer :: gridstatus end type type(ESMF_GridStatus_Flag), parameter :: & ESMF_GRIDSTATUS_INVALID=ESMF_GridStatus_Flag(-1), & ESMF_GRIDSTATUS_UNINIT=ESMF_GridStatus_Flag(0), & ESMF_GRIDSTATUS_EMPTY=ESMF_GridStatus_Flag(1), & ESMF_GRIDSTATUS_COMPLETE=ESMF_GridStatus_Flag(2) !------------------------------------------------------------------------------ ! ! ESMF_GridItem_Flag ! !------------------------------------------------------------------------------ type ESMF_GridItem_Flag sequence ! private integer :: gridItem end type type(ESMF_GridItem_Flag), parameter :: & ESMF_GRIDITEM_INVALID=ESMF_GridItem_Flag(-2), & ESMF_GRIDITEM_UNINIT=ESMF_GridItem_Flag(-1), & ESMF_GRIDITEM_MASK=ESMF_GridItem_Flag(0), & ESMF_GRIDITEM_AREA=ESMF_GridItem_Flag(1), & DEPREC_ESMF_GRIDITEM_AREAM=ESMF_GridItem_Flag(2), & ! DEPRECATED: If using, please email esmf support. DEPREC_ESMF_GRIDITEM_FRAC=ESMF_GridItem_Flag(3) ! DEPRECATED: If using, please email esmf support. !------------------------------------------------------------------------------ ! ! ESMF_GridConn_Flag ! !------------------------------------------------------------------------------ type ESMF_GridConn_Flag sequence ! private integer :: gridconn end type type(ESMF_GridConn_Flag), parameter :: & ESMF_GRIDCONN_NONE = ESMF_GridConn_Flag(0), & ESMF_GRIDCONN_PERIODIC = ESMF_GridConn_Flag(1), & ESMF_GRIDCONN_POLE = ESMF_GridConn_Flag(2), & ESMF_GRIDCONN_BIPOLE = ESMF_GridConn_Flag(3) !------------------------------------------------------------------------------ ! ! ESMF_PoleKind_Flag ! !------------------------------------------------------------------------------ type ESMF_PoleKind_Flag sequence ! private integer :: polekind end type type(ESMF_PoleKind_Flag), parameter :: & ESMF_POLEKIND_NONE = ESMF_PoleKind_Flag(0), & ESMF_POLEKIND_MONOPOLE = ESMF_PoleKind_Flag(1), & ESMF_POLEKIND_BIPOLE = ESMF_PoleKind_Flag(2) !------------------------------------------------------------------------------ ! ! ESMF_CoordSys_Flag ! !------------------------------------------------------------------------------ type ESMF_CoordSys_Flag sequence ! private integer :: coordsys end type type(ESMF_CoordSys_Flag), parameter :: & ESMF_COORDSYS_CART = ESMF_CoordSys_Flag(0), & ESMF_COORDSYS_SPH_DEG = ESMF_CoordSys_Flag(1), & ESMF_COORDSYS_SPH_RAD = ESMF_CoordSys_Flag(2) !------------------------------------------------------------------------------ ! ! ESMF_DefaultFlag ! !------------------------------------------------------------------------------ ! TODO: eventually move this elsewhere (e.g. Util) type ESMF_DefaultFlag sequence ! private integer :: defaultflag end type !------------------------------------------------------------------------------ ! ! ESMF_GridDecompType ! !------------------------------------------------------------------------------ type ESMF_GridDecompType sequence ! private integer :: griddecomptype end type type (ESMF_GridDecompType), parameter :: & ESMF_GRID_INVALID = ESMF_GridDecompType(1), & ESMF_GRID_NONARBITRARY = ESMF_GridDecompType(2), & ESMF_GRID_ARBITRARY = ESMF_GridDecompType(3) !------------------------------------------------------------------------------ ! ! Special dimenaion for Arbitrarily distributed dimension ! !------------------------------------------------------------------------------ integer,parameter :: ESMF_DIM_ARB = -1 !------------------------------------------------------------------------------ ! ! ESMF_GridStatus_Flag ! !------------------------------------------------------------------------------ type ESMF_GridMatch_Flag sequence ! private integer :: gridmatch end type type(ESMF_GridMatch_Flag), parameter :: & ESMF_GRIDMATCH_INVALID=ESMF_GridMatch_Flag(0), & ESMF_GRIDMATCH_NONE=ESMF_GridMatch_Flag(1), & ESMF_GRIDMATCH_EXACT=ESMF_GridMatch_Flag(2), & ESMF_GRIDMATCH_ALIAS=ESMF_GridMatch_Flag(3) !------------------------------------------------------------------------------ ! ! !PUBLIC TYPES: ! public ESMF_Grid public ESMF_GridConn_Flag, ESMF_GRIDCONN_NONE, ESMF_GRIDCONN_PERIODIC, & ESMF_GRIDCONN_POLE, ESMF_GRIDCONN_BIPOLE public ESMF_GridStatus_Flag, ESMF_GRIDSTATUS_INVALID, ESMF_GRIDSTATUS_UNINIT, & ESMF_GRIDSTATUS_EMPTY, ESMF_GRIDSTATUS_COMPLETE public ESMF_GridMatch_Flag, ESMF_GRIDMATCH_INVALID, & ESMF_GRIDMATCH_NONE, ESMF_GRIDMATCH_EXACT, ESMF_GRIDMATCH_ALIAS public ESMF_PoleKind_Flag, ESMF_POLEKIND_NONE, ESMF_POLEKIND_MONOPOLE, & ESMF_POLEKIND_BIPOLE public ESMF_CoordSys_Flag, ESMF_COORDSYS_CART, & ESMF_COORDSYS_SPH_DEG, & ESMF_COORDSYS_SPH_RAD public ESMF_GridItem_Flag, ESMF_GRIDITEM_INVALID, ESMF_GRIDITEM_UNINIT, & ESMF_GRIDITEM_MASK, ESMF_GRIDITEM_AREA, & DEPREC_ESMF_GRIDITEM_AREAM, DEPREC_ESMF_GRIDITEM_FRAC public ESMF_DefaultFlag public ESMF_GridDecompType, ESMF_GRID_INVALID, ESMF_GRID_NONARBITRARY, ESMF_GRID_ARBITRARY !------------------------------------------------------------------------------ ! ! !PUBLIC MEMBER FUNCTIONS: ! ! ! - ESMF-public methods: public operator(==) public operator(/=) public operator(>) public operator(>=) public ESMF_GridAddCoord public ESMF_GridCommit public ESMF_GridCreate public ESMF_GridEmptyCreate public ESMF_GridEmptyComplete ! public ESMF_GridCreateShapeTile public ESMF_GridCreateNoPeriDim public ESMF_GridCreate1PeriDim public ESMF_GridCreate2PeriDim public ESMF_GridDestroy public ESMF_GridGet public ESMF_GridGetCoord public ESMF_GridGetCoordBounds ! public ESMF_GridGetCoordInd ! HOPEFULLY TEMPORARY SEPARATE INTERFACE public ESMF_GridGetDecompType public ESMF_GridSet public ESMF_GridSetCoord public ESMF_GridAddItem public ESMF_GridGetItem public ESMF_GridSetItem public ESMF_GridGetItemBounds ! public ESMF_GridSetCommitShapeTile public ESMF_GridSerialize public ESMF_GridDeserialize public ESMF_GridMatch public ESMF_GridValidate ! public ESMF_GridTest ! For debugging public ESMF_GridConvertIndex ! For Arbitrarily distributed grid only public ESMF_ArrayCreateFromGrid public ESMF_GridGetArrayInfo public ESMF_DIM_ARB ! - ESMF-internal methods: public ESMF_GridGetInit !EOPI !------------------------------------------------------------------------------ ! The following line turns the CVS identifier string into a printable variable. character(*), parameter, private :: version = & '$Id: ESMF_Grid.F90,v 1.246 2011/07/13 04:11:01 rokuingh Exp $' !============================================================================== ! ! INTERFACE BLOCKS ! !============================================================================== ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridAddCoord -- Generic interface ! !INTERFACE: interface ESMF_GridAddCoord ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridAddCoordNoValues ! module procedure ESMF_GridAddCoordArrayList ! Currently not public ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridAddCoord} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridAddItem -- Generic interface ! !INTERFACE: interface ESMF_GridAddItem ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridAddItemNoValues ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridAddItem} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridCreate -- Generic interface ! !INTERFACE: interface ESMF_GridCreate ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridCreateCopyFromReg module procedure ESMF_GridCreateCopyFromNewDG module procedure ESMF_GridCreateFrmDistGrid module procedure ESMF_GridCreateFrmDistGridArb module procedure ESMF_GridCreateFrmFile module procedure ESMF_GridCreateFrmScripDistGrd module procedure ESMF_GridCreateFrmScripReg module procedure ESMF_GridCreateEdgeConnR module procedure ESMF_GridCreateEdgeConnI module procedure ESMF_GridCreateEdgeConnA ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridCreate} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridEmptyComplete -- Generic interface ! !INTERFACE: interface ESMF_GridEmptyComplete ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridEmptyCompleteEConnR module procedure ESMF_GridEmptyCompleteEConnI module procedure ESMF_GridEmptyCompleteEConnA ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridCreateShapeTile} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridCreateShapeTile -- Generic interface ! !INTERFACE: interface ESMF_GridCreateShapeTile ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridCreateShapeTileReg module procedure ESMF_GridCreateShapeTileIrreg module procedure ESMF_GridCreateShapeTileArb ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridCreateShapeTile} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridCreateNoPeriDim -- Generic interface ! !INTERFACE: interface ESMF_GridCreateNoPeriDim ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridCreateNoPeriDimR module procedure ESMF_GridCreateNoPeriDimI module procedure ESMF_GridCreateNoPeriDimA ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridCreateNoPeriodic} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridCreate1PeriDim -- Generic interface ! !INTERFACE: interface ESMF_GridCreate1PeriDim ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridCreate1PeriDimR module procedure ESMF_GridCreate1PeriDimI module procedure ESMF_GridCreate1PeriDimA ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridCreate1Periodic} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridCreate2PeriDim -- Generic interface ! !INTERFACE: interface ESMF_GridCreate2PeriDim ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridCreate2PeriDimR module procedure ESMF_GridCreate2PeriDimI module procedure ESMF_GridCreate2PeriDimA ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridCreate2Periodic} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridGet -- Get information from a Grid ! !INTERFACE: interface ESMF_GridGet ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridGetDefault module procedure ESMF_GridGetPLocalDePSloc module procedure ESMF_GridGetPSloc module procedure ESMF_GridGetPLocalDe module procedure ESMF_GridGetPSlocPTile ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridGet} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridGetCoord -- Generic interface ! !INTERFACE: interface ESMF_GridGetCoord ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridGetCoord1DR4 module procedure ESMF_GridGetCoord2DR4 module procedure ESMF_GridGetCoord3DR4 module procedure ESMF_GridGetCoord1DR8 module procedure ESMF_GridGetCoord2DR8 module procedure ESMF_GridGetCoord3DR8 module procedure ESMF_GridGetCoordIntoArray module procedure ESMF_GridGetCoordR8 module procedure ESMF_GridGetCoordR4 ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridGetCoord} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridGetItem -- Generic interface ! !INTERFACE: interface ESMF_GridGetItem ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridGetItem1DI4 module procedure ESMF_GridGetItem2DI4 module procedure ESMF_GridGetItem3DI4 module procedure ESMF_GridGetItem1DR4 module procedure ESMF_GridGetItem2DR4 module procedure ESMF_GridGetItem3DR4 module procedure ESMF_GridGetItem1DR8 module procedure ESMF_GridGetItem2DR8 module procedure ESMF_GridGetItem3DR8 module procedure ESMF_GridGetItemIntoArray ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridGetItem} functions. !EOPI end interface #if 0 ! -------------------------- ESMF-public method ------------------------------- !TODO: Temporary until I work out the proper overloading !BOPI ! !IROUTINE: ESMF_GridGetIndCoord -- Generic interface ! !INTERFACE: interface ESMF_GridGetCoordInd ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridGetCoordR4 module procedure ESMF_GridGetCoordR8 ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridGetIndCoord} functions. !EOPI end interface #endif ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridSet -- Generic interface ! !INTERFACE: interface ESMF_GridSet ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridSetFromDistGrid ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridSet} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridSetCoord -- Generic interface ! !INTERFACE: interface ESMF_GridSetCoord ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridSetCoordFromArray ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridSetCoord} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridSetItem -- Generic interface ! !INTERFACE: interface ESMF_GridSetItem ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridSetItemFromArray ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridSetItem} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_GridSetCommitShapeTile -- Generic interface ! !INTERFACE: interface ESMF_GridSetCommitShapeTile ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_GridSetCmmitShapeTileReg module procedure ESMF_GridSetCmmitShapeTileIrreg module procedure ESMF_GridSetCmmitShapeTileArb ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_GridSetCommitShapeTile} functions. !EOPI end interface !============================================================================== !BOPI ! !INTERFACE: interface operator (==) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridConnEqual ! !DESCRIPTION: ! This interface overloads the equality operator for the specific ! ESMF GridConn. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface ! !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (/=) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridConnNotEqual ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF GridConn. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface !!============================================================================== !BOPI ! !INTERFACE: interface operator (==) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridDecompEqual ! !DESCRIPTION: ! This interface overloads the equality operator for the specific ! ESMF_GridDecompType. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface ! !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (/=) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridDecompNotEqual ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF_GridDecompType. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (==) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridStatusEqual ! !DESCRIPTION: ! This interface overloads the equality operator for the specific ! ESMF GridStatus. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface ! !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (/=) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridStatusNotEqual ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF GridStatus. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (>) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridStatusGreater ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF GridStatus. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (.lt.) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridStatusLess ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF GridStatus. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (>=) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridStatusGreaterEqual ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF GridStatus. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (.le.) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridStatusLessEqual ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF GridStatus. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface ! !============================================================================== !PoleType !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (==) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_PoleTypeEqual ! !DESCRIPTION: ! This interface overloads the equality operator for the specific ! ESMF PoleType. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface ! !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (/=) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_PoleTypeNotEqual ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF PoleType. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface !GRIDMATCH !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (==) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridMatchEqual ! !DESCRIPTION: ! This interface overloads the equality operator for the specific ! ESMF GridMatch. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface ! !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (/=) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridMatchNotEqual ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF GridMatch. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (>) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridMatchGreater ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF GridMatch. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (.lt.) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridMatchLess ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF GridMatch. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (>=) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridMatchGreaterEqual ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF GridMatch. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface !------------------------------------------------------------------------------ !BOPI ! !INTERFACE: interface operator (.le.) ! !PRIVATE MEMBER FUNCTIONS: module procedure ESMF_GridMatchLessEqual ! !DESCRIPTION: ! This interface overloads the inequality operator for the specific ! ESMF GridMatch. It is provided for easy comparisons of ! these types with defined values. ! !EOPI end interface ! !============================================================================== !=============================================================================== ! GridOperator() interfaces !=============================================================================== ! -------------------------- ESMF-public method ------------------------------- !BOP ! !IROUTINE: ESMF_GridAssignment(=) - Grid assignment ! ! !INTERFACE: ! interface assignment(=) ! grid1 = grid2 ! ! !ARGUMENTS: ! type(ESMF_Grid) :: grid1 ! type(ESMF_Grid) :: grid2 ! ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! Assign grid1 as an alias to the same ESMF Grid object in memory ! as grid2. If grid2 is invalid, then grid1 will be equally invalid after ! the assignment. ! ! The arguments are: ! \begin{description} ! \item[grid1] ! The {\tt ESMF\_Grid} object on the left hand side of the assignment. ! \item[grid2] ! The {\tt ESMF\_Grid} object on the right hand side of the assignment. ! \end{description} ! !EOP !------------------------------------------------------------------------------ ! -------------------------- ESMF-public method ------------------------------- !BOP ! !IROUTINE: ESMF_GridOperator(==) - Grid equality operator ! ! !INTERFACE: interface operator(==) ! if (grid1 == grid2) then ... endif ! OR ! result = (grid1 == grid2) ! !RETURN VALUE: ! logical :: result ! ! !ARGUMENTS: ! type(ESMF_Grid), intent(in) :: grid1 ! type(ESMF_Grid), intent(in) :: grid2 ! ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! Test whether grid1 and grid2 are valid aliases to the same ESMF ! Grid object in memory. For a more general comparison of two ESMF Grids, ! going beyond the simple alias test, the ESMF\_GridMatch() function (not yet ! fully implemented) must be used. ! ! The arguments are: ! \begin{description} ! \item[grid1] ! The {\tt ESMF\_Grid} object on the left hand side of the equality ! operation. ! \item[grid2] ! The {\tt ESMF\_Grid} object on the right hand side of the equality ! operation. ! \end{description} ! !EOP module procedure ESMF_GridEQ end interface !------------------------------------------------------------------------------ ! -------------------------- ESMF-public method ------------------------------- !BOP ! !IROUTINE: ESMF_GridOperator(/=) - Grid not equal operator ! ! !INTERFACE: interface operator(/=) ! if (grid1 /= grid2) then ... endif ! OR ! result = (grid1 /= grid2) ! !RETURN VALUE: ! logical :: result ! ! !ARGUMENTS: ! type(ESMF_Grid), intent(in) :: grid1 ! type(ESMF_Grid), intent(in) :: grid2 ! ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! Test whether grid1 and grid2 are {\it not} valid aliases to the ! same ESMF Grid object in memory. For a more general comparison of two ESMF ! Grids, going beyond the simple alias test, the ESMF\_GridMatch() function ! (not yet fully implemented) must be used. ! ! The arguments are: ! \begin{description} ! \item[grid1] ! The {\tt ESMF\_Grid} object on the left hand side of the non-equality ! operation. ! \item[grid2] ! The {\tt ESMF\_Grid} object on the right hand side of the non-equality ! operation. ! \end{description} ! !EOP module procedure ESMF_GridNE end interface !------------------------------------------------------------------------------ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! contains !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !------------------------------------------------------------------------------- #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridEQ()" !BOPI ! !IROUTINE: ESMF_GridEQ - Compare two Grids for equality ! ! !INTERFACE: function ESMF_GridEQ(grid1, grid2) ! ! !RETURN VALUE: logical :: ESMF_GridEQ ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid1 type(ESMF_Grid), intent(in) :: grid2 ! !DESCRIPTION: ! Test if both {\tt grid1} and {\tt grid2} alias the same ESMF Grid ! object. ! !EOPI !------------------------------------------------------------------------------- ESMF_INIT_TYPE ginit1, ginit2 integer :: localrc1, localrc2 logical :: lval1, lval2 ! Use the following logic, rather than "ESMF-INIT-CHECK-DEEP", to gain ! init checks on both args, and in the case where both are uninitialized, ! to distinguish equality based on uninitialized type (uncreated, ! deleted). ! TODO: Consider moving this logic to C++: use Base class? status? ! Or replicate logic for C interface also. ! check inputs ginit1 = ESMF_GridGetInit(grid1) ginit2 = ESMF_GridGetInit(grid2) ! TODO: this line must remain split in two for SunOS f90 8.3 127000-03 if (ginit1 == ESMF_INIT_CREATED .and. & ginit2 == ESMF_INIT_CREATED) then ESMF_GridEQ = grid1%this == grid2%this else ESMF_GridEQ = ESMF_FALSE endif end function ESMF_GridEQ !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridNE()" !BOPI ! !IROUTINE: ESMF_GridNE - Compare two Grids for non-equality ! ! !INTERFACE: function ESMF_GridNE(grid1, grid2) ! ! !RETURN VALUE: logical :: ESMF_GridNE ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid1 type(ESMF_Grid), intent(in) :: grid2 ! !DESCRIPTION: ! Test if both {\tt grid1} and {\tt grid2} alias the same ESMF Grid ! object. ! !EOPI !------------------------------------------------------------------------------- ESMF_INIT_TYPE ginit1, ginit2 integer :: localrc1, localrc2 logical :: lval1, lval2 ! Use the following logic, rather than "ESMF-INIT-CHECK-DEEP", to gain ! init checks on both args, and in the case where both are uninitialized, ! to distinguish equality based on uninitialized type (uncreated, ! deleted). ESMF_GridNE = .not.ESMF_GridEQ(grid1, grid2) end function ESMF_GridNE !------------------------------------------------------------------------------- !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridAddCoord" !BOP ! !IROUTINE: ESMF_GridAddCoord - Allocate coordinate arrays but don't set their values ! !INTERFACE: ! Private name; call using ESMF_GridAddCoord() subroutine ESMF_GridAddCoordNoValues(grid, keywordEnforcer, staggerloc, & staggerEdgeLWidth, staggerEdgeUWidth, staggerAlign, & staggerLBound,rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: staggerEdgeLWidth(:) integer, intent(in), optional :: staggerEdgeUWidth(:) integer, intent(in), optional :: staggerAlign(:) integer, intent(in), optional :: staggerLBound(:) integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! ! When a Grid is created all of its potential stagger locations can hold coordinate ! data, but none of them have storage allocated. This call allocates coordinate ! storage (creates internal ESMF\_Arrays and associated memory) for a particular ! stagger location. Note that this ! call doesn't assign any values to the storage, it only allocates it. The ! remaining options {\tt staggerEdgeLWidth}, etc. allow the user to adjust the ! padding on the coordinate arrays. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to allocate coordinate storage in. ! \item[{[staggerloc]}] ! The stagger location to add. Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! \item[{[staggerEdgeLWidth]}] ! This array should be the same dimCount as the grid. It specifies the lower corner of the stagger ! region with respect to the lower corner of the exclusive region. ! \item[{[staggerEdgeUWidth]}] ! This array should be the same dimCount as the grid. It specifies the upper corner of the stagger ! region with respect to the upper corner of the exclusive region. ! \item[{[staggerAlign]}] ! This array is of size grid dimCount. ! For this stagger location, it specifies which element ! has the same index value as the center. For example, ! for a 2D cell with corner stagger it specifies which ! of the 4 corners has the same index as the center. ! If this is set and either staggerEdgeUWidth or staggerEdgeLWidth is not, ! this determines the default array padding for a stagger. ! If not set, then this defaults to all negative. (e.g. ! The most negative part of the stagger in a cell is aligned with the ! center and the padding is all on the postive side.) ! \item[{[staggerLBound]}] ! Specifies the lower index range of the memory of every DE in this staggerloc in this Grid. ! Only used when Grid indexflag is {\tt ESMF\_INDEX\_USER}. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP integer :: tmp_staggerloc integer :: localrc ! local error status type(ESMF_GridDecompType) :: decompType ! Arbitrary or not type(ESMF_InterfaceInt) :: staggerEdgeLWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: staggerEdgeUWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: staggerAlignArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: staggerLBoundArg ! Language Interface Helper Var ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) ! Get Grid decomposition type call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! handle staggerloc if (present(staggerloc)) then if ((decompType == ESMF_GRID_ARBITRARY) .and. & (staggerloc /= ESMF_STAGGERLOC_CENTER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return else tmp_staggerloc=staggerloc%staggerloc endif else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif if (decompType == ESMF_GRID_ARBITRARY) then if (present(staggerEdgeLWidth) .or. present(staggerEdgeUWidth) .or. & present(staggerAlign)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- stagger arguments should not be set for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return else ! Call C++ Subroutine to do the create call c_ESMC_gridaddcoordarb(grid%this,tmp_staggerloc, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif else !! staggerEdgeLWidth staggerEdgeLWidthArg = ESMF_InterfaceIntCreate(staggerEdgeLWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! staggerEdgeUWidth staggerEdgeUWidthArg = ESMF_InterfaceIntCreate(staggerEdgeUWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! staggerAlign staggerAlignArg = ESMF_InterfaceIntCreate(staggerAlign, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! staggerMemLBound staggerLBoundArg = ESMF_InterfaceIntCreate(staggerLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call C++ Subroutine to do the create call c_ESMC_gridaddcoord(grid%this,tmp_staggerloc, & staggerEdgeLWidthArg, staggerEdgeUWidthArg, staggerAlignArg, staggerLBoundArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate helper variables call ESMF_InterfaceIntDestroy(staggerEdgeLWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(staggerEdgeUWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(staggerAlignArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(staggerLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridAddCoordNoValues !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridAddCoord" !BOPI ! !IROUTINE: ESMF_GridAddCoord - Set coordinates using an array of Arrays ! !INTERFACE: ! Private name; call using ESMF_GridAddCoord() subroutine ESMF_GridAddCoordArrayList(grid, staggerloc, & arrayList, datacopyflag, staggerEdgeLWidth, & staggerEdgeUWidth, staggerAlign, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_StaggerLoc), intent(in), optional :: staggerloc type(ESMF_Array), intent(in) :: arrayList(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag ! NOT IMPLEMENTED integer, intent(in), optional :: staggerEdgeLWidth(:) integer, intent(in), optional :: staggerEdgeUWidth(:) integer, intent(in), optional :: staggerAlign(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method sets the passed in Array as the holder of the coordinate data ! for stagger location {\tt staggerloc} and coordinate {\tt coord}. If the location ! already contains an Array, then this one overwrites it. ! ! The arguments are: !\begin{description} !\item[{staggerloc}] ! The stagger location into which to copy the arrays. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. !\item[{arrayList}] ! An array to set the grid coordinate information from. !\item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case the Grid ! coordinate Array will be set to a reference to {\tt array}. Please see ! Section~\ref{const:datacopyflag} for further description and a list of ! valid values. ! [THE ESMF\_DATACOPY\_VALUE OPTION IS CURRENTLY NOT IMPLEMENTED] ! \item[{[staggerEdgeLWidth]}] ! This array should be the same rank as the grid. It specifies the lower corner of the stagger ! region with respect to the lower corner of the exclusive region. ! \item[{[staggerEdgeUWidth]}] ! This array should be the same rank as the grid. It specifies the upper corner of the stagger ! region with respect to the upper corner of the exclusive region. ! \item[{[staggerAlign]}] ! This array is of size grid rank. ! For this stagger location, it specifies which element ! has the same index value as the center. For example, ! for a 2D cell with corner stagger it specifies which ! of the 4 corners has the same index as the center. ! If this is set and either staggerEdgeUWidth or staggerEdgeLWidth is not, ! this determines the default array padding for a stagger. ! If not set, then this defaults to all negative. (e.g. ! The most negative part of the stagger in a cell is aligned with the ! center and the padding is all on the postive side.) !\item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. !\end{description} ! !EOPI integer :: tmp_staggerloc integer :: localrc ! local error status type(ESMF_InterfaceInt) :: staggerEdgeLWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: staggerEdgeUWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: staggerAlignArg ! Language Interface Helper Var integer :: i,arrayCount type(ESMF_Pointer), allocatable :: arrayPointerList(:) ! helper variable ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Get size of array list arrayCount=size(arrayList) ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) do i=1, arrayCount ESMF_INIT_CHECK_DEEP_SHORT(ESMF_ArrayGetInit, arrayList(i), rc) enddo ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif !! staggerLWidth staggerEdgeLWidthArg = ESMF_InterfaceIntCreate(staggerEdgeLWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! staggerEdgeUWidth staggerEdgeUWidthArg = ESMF_InterfaceIntCreate(staggerEdgeUWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! staggeAlign staggerAlignArg = ESMF_InterfaceIntCreate(staggerAlign, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! staggerAlign staggerAlignArg = ESMF_InterfaceIntCreate(staggerAlign, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Copy C++ pointers of deep objects into a simple ESMF_Pointer array ! This is necessary in order to strip off the F90 init check members ! when passing into C++ allocate(arrayPointerList(arrayCount)) do i=1, arrayCount call ESMF_ArrayGetThis(arrayList(i), arrayPointerList(i), localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return enddo ! Call C++ Subroutine to do the create call c_ESMC_gridaddcoordarraylist(grid%this,tmp_staggerloc, & arrayCount, arrayPointerList, datacopyflag, staggerEdgeLWidthArg, & staggerEdgeUWidthArg, staggerAlignArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! cleanup deallocate(arrayPointerList) call ESMF_InterfaceIntDestroy(staggerEdgeLWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(staggerEdgeUWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(staggerAlignArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridAddCoordArrayList !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridAddItem" !BOP ! !IROUTINE: ESMF_GridAddItem - Allocate item array but don't set their values ! !INTERFACE: ! Private name; call using ESMF_GridAddItem() subroutine ESMF_GridAddItemNoValues(grid, itemflag, & keywordEnforcer, staggerloc, itemTypeKind, staggerEdgeLWidth, staggerEdgeUWidth, & staggerAlign, staggerLBound,rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc) , intent(in), optional :: staggerloc type (ESMF_TypeKind_Flag), intent(in), optional :: itemTypeKind integer, intent(in), optional :: staggerEdgeLWidth(:) integer, intent(in), optional :: staggerEdgeUWidth(:) integer, intent(in), optional :: staggerAlign(:) integer, intent(in), optional :: staggerLBound(:) integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! ! When a Grid is created all of its potential stagger locations can hold item ! data, but none of them have storage allocated. This call allocates item ! storage (creates an internal ESMF\_Array and associated memory) for a particular ! stagger location. Note that this ! call doesn't assign any values to the storage, it only allocates it. The ! remaining options {\tt staggerEdgeLWidth}, etc. allow the user to adjust the ! padding on the item array. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to allocate coordinate storage in. ! \item[{itemflag}] ! The grid item to add. Please see Section~\ref{const:griditem} for a list of valid items. ! \item[{[staggerloc]}] ! The stagger location to add. Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! \item[{[itemTypeKind]}] ! The typekind of the item to add. ! \item[{[staggerEdgeLWidth]}] ! This array should be the same dimCount as the grid. It specifies the lower corner of the stagger ! region with respect to the lower corner of the exclusive region. ! \item[{[staggerEdgeUWidth]}] ! This array should be the same dimCount as the grid. It specifies the upper corner of the stagger ! region with respect to the upper corner of the exclusive region. ! \item[{[staggerAlign]}] ! This array is of size grid dimCount. ! For this stagger location, it specifies which element ! has the same index value as the center. For example, ! for a 2D cell with corner stagger it specifies which ! of the 4 corners has the same index as the center. ! If this is set and either staggerEdgeUWidth or staggerEdgeLWidth is not, ! this determines the default array padding for a stagger. ! If not set, then this defaults to all negative. (e.g. ! The most negative part of the stagger in a cell is aligned with the ! center and the padding is all on the postive side.) ! \item[{[staggerLBound]}] ! Specifies the lower index range of the memory of every DE in this staggerloc in this Grid. ! Only used when Grid indexflag is {\tt ESMF\_INDEX\_USER}. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP integer :: tmp_staggerloc integer :: localrc ! local error status type(ESMF_InterfaceInt) :: staggerEdgeLWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: staggerEdgeUWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: staggerAlignArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: staggerLBoundArg ! Language Interface Helper Var type(ESMF_GridDecompType) :: decompType ! decompose type: arbitrary or non-arbitrary ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) ! Get Grid decomposition type call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif ! Check if the grid is arbitrary if (decompType == ESMF_GRID_ARBITRARY) then if (present(staggerEdgeLWidth) .or. present(staggerEdgeUWidth)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerEdgeLWidth and staggerEdigeUWidth are not allowed for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(staggerAlign)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerAlign is not allowed for arbitrarily distributed grid", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(staggerloc)) then if (staggerloc /= ESMF_STAGGERLOC_CENTER) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Call C++ Subroutine to do the create call c_ESMC_gridadditemarb(grid%this,tmp_staggerloc, itemflag, itemTypeKind, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return else !! staggerEdgeLWidth staggerEdgeLWidthArg = ESMF_InterfaceIntCreate(staggerEdgeLWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! staggerEdgeUWidth staggerEdgeUWidthArg = ESMF_InterfaceIntCreate(staggerEdgeUWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! staggerAlign staggerAlignArg = ESMF_InterfaceIntCreate(staggerAlign, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! staggerLBound staggerLBoundArg = ESMF_InterfaceIntCreate(staggerLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call C++ Subroutine to do the create call c_ESMC_gridadditem(grid%this,tmp_staggerloc, itemflag, itemTypeKind, & staggerEdgeLWidthArg, staggerEdgeUWidthArg, staggerAlignArg, & staggerLBoundArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate helper variables call ESMF_InterfaceIntDestroy(staggerEdgeLWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(staggerEdgeUWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(staggerAlignArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(staggerLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridAddItemNoValues !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCommit" !BOPI ! !IROUTINE: ESMF_GridCommit - Commit a Grid to a specified completion level ! !INTERFACE: subroutine ESMF_GridCommit(grid, status, defaultflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(inout) :: grid type(ESMF_GridStatus_Flag), optional :: status ! NOT IMPLEMENTED type(ESMF_DefaultFlag), optional :: defaultflag ! NOT IMPLEMENTED integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This call is used to complete the {\tt grid} so that it is usable at ! the level indicated by the {\tt status} flag. For example, once committed ! with a {\tt status} value of {\tt ESMF\_GRIDSTATUS\_SHAPE\_READY}, the ! {\tt grid} will have sufficient size, dimCount, and distribution information to be ! used as the basis for allocating Field data. (The integration of ! Field and Grid classes has't yet happened, so you can't currently ! allocate Fields based on Grids no matter what the status.) ! ! It is necessary to call the {\tt ESMF\_GridCommit()} method after ! creating a Grid object using the {\tt ESMF\_GridEmptyCreate()} method ! and incrementally filling it in with {\tt ESMF\_GridSet()} calls. The ! {\tt EMF\_GridCommit()} call is a signal to the Grid that it can combine ! the pieces of information that it's received and finish building any ! necessary internal structures. For example, an {\tt ESMF\_GridCommit()} ! call with the {\tt status} flag set to ! {\tt ESMF\_GRIDSTATUS\_SHAPE\_READY} will trigger the {\tt grid} to ! build an internal DistGrid object that contains topology and distribution ! information. ! ! It's possible using the {\tt ESMF\_GridEmptyCreate()/ESMF\_GridSet()} ! approach that not all information is present when the {\tt ESMF\_GridCommit} ! call is made. If this is the case and the {\tt defaultflag} is set to ! {\tt ESMF\_USE\_DEFAULTS} the Grid will attempt to build any internal ! objects necessary to get to the desired {\tt status} by using reasonable ! defaults. If the {\tt defaultflag} is set to {\tt ESMF\_NO\_DEFAULTS} and ! any information is missing, the {\tt ESMF\_GridCommit} call will fail. ! If the {\tt defaultflag} argument is not passed in, {\it no} defaults ! are used. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid object to commit. ! \item[{status}] ! Grid status to commit to. For valid values see section ! \ref{const:gridstatus}. [CURRENTLY NOT IMPLEMENTED] ! \item[{[defaultFlag]}] ! Indicates whether to use default values to achieve the desired ! grid status. The default value is {\tt ESMF\_NO\_DEFAULTS}. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc ! local error status ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) ! Check for Not Implemented options if (present(status)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- status not yet implemented", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(defaultflag)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- defaultflag not yet implemented", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Call C++ Subroutine to do the create call c_ESMC_gridcommit(grid%this, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridCommit !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "GridConvertIndex" !BOPI ! !IROUTINE: ESMF_GridConvertIndex - Convert Arbitrary Grid index into DistGrid index ! !INTERFACE: subroutine ESMF_GridConvertIndex(grid,gridindex, distgridindex, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer , intent(in) :: gridindex(:) integer , intent(out) :: distgridindex(:) integer , intent(out), optional :: rc ! ! !DESCRIPTION: ! ! Convert a multi-dimensional index of the arbitrarily distributed grid into the ! index of the 1D DistGrid. The associated DistGrid for an arbitrarily distributed ! grid is 1D plus any undistributed dimension. The function ! calculates the index of the DistGrid for a given index from the original Grid. ! ! The arguments are: ! \begin{description} !\item[{grid}] ! The grid to get the information from to create the Array. ! \item[{[gridindex]}] ! The Grid index to be converted. ! \item[{[distgridindex]}] ! The DistGrid index to be returned. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. !\end{description} ! !EOPI integer :: localrc integer :: DimCount, distDimCount, undistDimCount integer, pointer :: minIndex(:) integer, pointer :: maxIndex(:) integer, pointer :: distgridToGridMap(:) integer :: i,j,k integer :: index1D ! the return value type(ESMF_InterfaceInt) :: gridIndexArg type(ESMF_GridDecompType) :: decompType type(ESMF_DistGrid) :: distGrid integer, allocatable :: undistdim(:) logical :: found integer :: distGridDimCount, arbDim ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) ! Get Grid decomposition type call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Check if the grid is arbitrary if (decompType /= ESMF_GRID_ARBITRARY) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- ESMF_GridConvertIndex only works for arbritrarily distributed grid", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Get info from Grid call ESMF_GridGet(grid, distgrid= distGrid, DimCount=DimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! allocate minIndex and maxIndex allocate(minIndex(DimCount), maxIndex(DimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndex and maxIndex", & ESMF_CONTEXT, rcToReturn=rc)) return ! Get minIndex and maxIndex from the grid call ESMF_GridGetIndex(grid, minIndex= minIndex, maxIndex=maxIndex, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! find out how many dimensions are arbitrarily distributed call ESMF_DistGridGet(distGrid, dimcount = distGridDimCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (distGridDimCount > dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- distgrid dimension has to be less than or equal to dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! set distDimCount - number of dimensions arbitrarily distributed ! undistDimCount - number of dimensions not arbitrarily distributed if (distGridDimCount == 1) then ! all dimensions are arbitrarily distributed distDimCount = dimCount undistDimCount = 0 else undistDimCount = distGridDimCount - 1 distDimCount = dimCount - undistDimCount endif ! Check index dimension if (size(gridindex) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- gridindex dimension is different from the grid DimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Check index out of bound do i=1,dimCount if (gridindex(i) .lt. minIndex(i) .and. gridindex(i) > maxIndex(i)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- gridindex is out of bound", & ESMF_CONTEXT, rcToReturn=rc) return endif enddo ! clean up memory allocation deallocate(minIndex) deallocate(maxIndex) ! Call the C function to get the index of the 1D distgrid !! index gridIndexArg = ESMF_InterfaceIntCreate(gridindex, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call c_ESMC_gridconvertindex(grid%this, gridIndexArg, index1D, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (undistDimCount /= 0) then allocate(distgridToGridMap(dimCount), stat=localrc) call ESMF_GridGet(grid, arbDim=arbDim, & distgridToGridMap=distgridToGridMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return k=1 allocate(undistdim(undistDimCount)) do i=1,dimCount found = .false. do j=1,distDimCount if (i == distgridToGridMap(j)) found=.true. enddo if (.not. found) then undistdim(k)=i k=k+1 endif enddo k=1 do i=1,distGridDimCount if (i == arbDim) then distgridindex(i)=index1D else distgridindex(i)=gridindex(undistdim(k)) k=k+1 endif enddo deallocate(undistdim) deallocate(distgridToGridMap) else distgridindex(1)=index1D endif ! clean up memory allocation call ESMF_InterfaceIntDestroy(GridIndexArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS return end subroutine ESMF_GridConvertIndex !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ArrayCreateFromGrid" !BOPI ! !IROUTINE: ESMF_ArrayCreateFromGrid - Create an Array to hold data for a stagger location ! !INTERFACE: function ESMF_ArrayCreateFromGrid(grid,staggerloc, typekind, & gridToArrayMap, ungriddedLBound, ungriddedUBound, & totalLWidth, totalUWidth, name, rc) ! ! !RETURN VALUE: type(ESMF_Array) :: ESMF_ArrayCreateFromGrid ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type(ESMF_StaggerLoc), intent(in), optional :: staggerloc type(ESMF_TypeKind_Flag), intent(in), optional :: typekind integer, intent(in), optional :: gridToArrayMap(:) integer, intent(in), optional :: ungriddedLBound(:) integer, intent(in), optional :: ungriddedUBound(:) integer, intent(in), optional :: totalLWidth(:) integer, intent(in), optional :: totalUWidth(:) character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! Create an ESMF Array which is suitable to hold data for a particular ! stagger location in a Grid. The Array will have the correct bounds, distgridToGridMap, ! distgrid, etc. The {\tt totalWidth} variables can be used to add extra padding ! around the Array (e.g. for use as a halo). ! ! The arguments are: ! \begin{description} !\item[{grid}] ! The grid to get the information from to create the Array. !\item[{staggerloc}] ! The stagger location to build the Array for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{[typekind]}] ! The type/kind of the newly created array data. ! If not specified then the type/kind will be 8 byte reals. !\item[{[gridToArrayMap]}] ! Indicates where each grid dimension goes in the newly created Array. ! {\tt The array gridToArrayMap} should be at least of size equal to the grid's dimCount. ! If not set defaults to (1,2,3,....). An entry of 0 indicates the grid dimension ! won't be used in the creation of the Array. !\item[{[ungriddedLBound]}] ! The lower bounds of the non-grid Array dimensions. !\item[{[ungriddedUBound]}] ! The upper bounds of the non-grid array dimensions. !\item[{[totalLWidth]}] ! Extra padding to be added to the Array. {\tt totalLWidth} is the amount ! that the lower boundary of the Array should be dropped relative ! to the lower bound of the exclusive region. !\item[{[totalUWidth]}] ! Extra padding to be added to the Array. {\tt totalUWidth} is the amount ! that the upper boundary of the Array should be raised relative ! to the upper bound of the exclusive region. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc ! local error status type(ESMF_Array) :: array type(ESMF_ArraySpec) :: arrayspec type(ESMF_DistGrid) :: distgrid type(ESMF_Index_Flag) :: indexflag type(ESMF_TypeKind_Flag) :: localTypeKind type(ESMF_StaggerLoc) :: localStaggerLoc integer, pointer :: arrayLBound(:),arrayUBound(:) integer, pointer :: distgridToArrayMap(:) integer :: dimCount integer :: i,ungriddedDimCount, arrayDimCount, undistArrayDimCount logical :: contains_nonzero integer :: gridUsedDimCount ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) ! Set Default TypeKind if neccessary if (present(typekind)) then localTypeKind=typekind else localTypeKind=ESMF_TYPEKIND_R8 endif ! Set Default StaggerLoc if neccessary if (present(staggerloc)) then localStaggerLoc=staggerloc else localStaggerLoc=ESMF_STAGGERLOC_CENTER endif ! Both the bounds need to be present if either is. if ((present(ungriddedLBound) .or. present(ungriddedUBound)) .and. & .not. (present(ungriddedLBound) .and. present(ungriddedUBound))) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- if either ungriddedBound is present both need to be", & ESMF_CONTEXT, rcToReturn=rc) return endif ! The bounds need to be the same size if (present(ungriddedLBound) .and. present(ungriddedUBound)) then if (size(ungriddedLBound) /= size(ungriddedUBound)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- ungriddedLBound and ungriddedUBound must be the same size ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Get the ungridded dimCount ungriddedDimCount=0 if (present(ungriddedUBound)) then ungriddedDimCount=size(ungriddedUBound) endif ! Get info from Grid call ESMF_GridGet(grid, dimCount=dimCount, & indexflag=indexflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! calc undist Array DimCount undistArrayDimCount=ungriddedDimCount ! Make sure gridToArrayMap is correct size if (present(gridToArrayMap)) then if (size(gridToArrayMap) < dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridToArrayMap needs to at least be of the Grid's dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! calc the number of dimensions from the grid being used (e.g. with non-zero mapping) if (present(gridToArrayMap)) then gridUsedDimCount=0 do i=1,dimCount if (gridToArrayMap(i) > 0) then gridUsedDimCount=gridUsedDimCount+1 endif enddo else ! Default assumes all grid dims are used so add number of grid dims gridUsedDimCount=dimCount endif ! calc full Array DimCount ! Its the ungriddedDimCount + the number of non-zero entries in gridToArrayMap arrayDimCount=ungriddedDimCount+gridUsedDimCount ! Make sure gridToArrayMap is correct size if (present(gridToArrayMap)) then do i=1,dimCount if ((gridToArrayMap(i) <0) .or. (gridToArrayMap(i) > arrayDimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- gridToArrayMap value is outside range", & ESMF_CONTEXT, rcToReturn=rc) return endif enddo endif ! Make sure gridToArrayMap contains at least one non-zero entry if (present(gridToArrayMap)) then contains_nonzero=.false. do i=1,dimCount if (gridToArrayMap(i) >0) then contains_nonzero=.true. endif enddo if (.not. contains_nonzero) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- gridToArrayMap must contains at least one value greater than 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! construct ArraySpec call ESMF_ArraySpecSet(arrayspec,rank=arrayDimCount,typekind=localTypeKind, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! allocate distgridToArrayMap allocate(distgridToArrayMap(dimCount) , stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distgridToArrayMap", & ESMF_CONTEXT, rcToReturn=rc)) return ! allocate undistributed Bounds allocate(arrayLBound(undistArrayDimCount) , stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridLBound", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(arrayUBound(undistArrayDimCount) , stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridUBound", & ESMF_CONTEXT, rcToReturn=rc)) return ! Get dimmap and undistibuted bounds call ESMF_GridGetArrayInfo(grid, localstaggerloc, & gridToArrayMap, ungriddedLBound, ungriddedUBound, & distgrid, distgridToArrayMap, arrayLBound, arrayUBound, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! create Array array=ESMF_ArrayCreate(arrayspec=arrayspec, & distgrid=distgrid, distgridToArrayMap=distgridToArrayMap, & totalLWidth=totalLWidth, totalUWidth=totalUWidth, & indexflag=indexflag, & undistLBound=arrayLBound, undistUBound=arrayUBound, name=name, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set return value ESMF_ArrayCreateFromGrid = array ! cleanup deallocate(distgridToArrayMap) deallocate(arrayLBound) deallocate(arrayUBound) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_ArrayCreateFromGrid !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetArrayInfo" !BOPI ! !IROUTINE: ESMF_GridGetArrayInfo - get information to make an Array from a Grid ! !INTERFACE: subroutine ESMF_GridGetArrayInfo(grid, staggerloc, & gridToFieldMap, ungriddedLBound, ungriddedUBound, & staggerDistgrid, distgridToArrayMap, & undistLBound, undistUBound, & rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type(ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: gridToFieldMap(:) integer, intent(in), optional :: ungriddedLBound(:) integer, intent(in), optional :: ungriddedUBound(:) type(ESMF_DistGrid), intent(out), optional :: staggerDistgrid integer, intent(out) :: distgridToArrayMap(:) integer, intent(out) :: undistLBound(:) integer, intent(out) :: undistUBound(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This subroutine gets information from a Grid which is useful in creating an ! Array corresponding to a Field. This subroutine returns the distgridToArray map and ! undistBounds which can be used to create an Array the same size and shape as the Grid. ! Optionally, the user can pass in non-grid bounds, the subroutine then ! returns a map and undistbounds which include these non-grid bounds. ! ! The arguments are: ! \begin{description} !\item[{grid}] ! The grid to get the information from to create the Array. !\item[{staggerloc}] ! The stagger location to build the Array for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. !\item[staggerDistgrid] ! The class that describes the stagger locations in the grids distribution. !\item[{[gridToFieldMap]}] ! Indicates how the grid dimension map to the field that the newly created array ! is associated with. {\tt The array gridToFieldMap} should be at least of size equal ! to the grid's dimCount. If not set defaults to (1,2,3,....). An entry of 0 indicates ! the grid dimension isn't mapped to the Array. !\item[{[ungriddedLBound]}] ! The lower bounds of the non-grid Array dimensions. !\item[{[ungriddedUBound]}] ! The upper bounds of the non-grid array dimensions. !\item[{distgridToArrayMap}] ! The distgrid to Array dimension map (must be allocated to at least ! the number of dimensions of the distGrid). !\item[{undistLBound}] ! Undistributed lower bounds (must be of size grid undistDimCount+size(ungriddedUBound)) !\item[{undistUBound}] ! Undistributed upper bounds (must be of size grid undistDimCount+size(ungriddedUBound)) ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc ! local error status type(ESMF_StaggerLoc) :: localStaggerLoc type(ESMF_GridDecompType) :: decompType integer, pointer :: arrayDimType(:) integer, pointer :: arrayDimInd(:) integer, pointer :: distgridToGridMap(:) integer :: dimCount,distDimCount, arrayDimCount integer :: i,j,k,ungriddedDimCount, undistArrayDimCount, bndpos integer :: gridComputationalEdgeLWidth(ESMF_MAXDIM) integer :: gridComputationalEdgeUWidth(ESMF_MAXDIM) integer :: tmpArrayComputationalEdgeLWidth(ESMF_MAXDIM) integer :: tmpArrayComputationalEdgeUWidth(ESMF_MAXDIM) integer :: localGridToFieldMap(ESMF_MAXDIM) logical :: filled(ESMF_MAXDIM) logical :: contains_nonzero integer :: fieldDimCount integer :: gridUsedDimCount integer :: arbdim, rep_arb, rep_noarb logical :: found type(ESMF_DistGrid) :: distgrid ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) ! Get DecomposeType call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set Default StaggerLoc if neccessary if (present(staggerloc)) then localStaggerLoc=staggerloc else localStaggerLoc=ESMF_STAGGERLOC_CENTER endif ! Both the bounds need to be present if either is. if ((present(ungriddedLBound) .or. present(ungriddedUBound)) .and. & .not. (present(ungriddedLBound) .and. present(ungriddedUBound))) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- if either ungriddedBound is present both need to be", & ESMF_CONTEXT, rcToReturn=rc) return endif ! The bounds need to be the same size if (present(ungriddedLBound) .and. present(ungriddedUBound)) then if (size(ungriddedLBound) /= size(ungriddedUBound)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- ungriddedLBound and ungriddedUBound must be the same size ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Get the ungridded dimCount ungriddedDimCount=0 if (present(ungriddedUBound)) then ungriddedDimCount=size(ungriddedUBound) endif ! Get info from Grid call ESMF_GridGet(grid, dimCount=dimCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! calc undist Array DimCount undistArrayDimCount=ungriddedDimCount ! Make sure gridToFieldMap is correct size if (present(gridToFieldMap)) then if (size(gridToFieldMap) < dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridToFieldMap needs to at least be of the Grid's dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Get grid distgrid call ESMF_GridGet(grid, localStaggerLoc, distgrid=distgrid, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! if argument is present, then pass out distgrid if (present(staggerDistGrid)) then staggerDistGrid=distgrid endif ! if the Grid is arbitrary, the array dimension will be different depending on how many ! grid dimensions are arbitrarily distributed if (decompType == ESMF_GRID_NONARBITRARY) then ! calc the number of dimensions from the grid being used (e.g. with non-zero mapping) if (present(gridToFieldMap)) then gridUsedDimCount=0 do i=1,dimCount if (gridToFieldMap(i) > 0) then gridUsedDimCount=gridUsedDimCount+1 endif enddo else ! Default assumes all grid dims are used so add number of grid dims gridUsedDimCount=dimCount endif ! calc full Array DimCount ! Its the ungriddedDimCount + the number of non-zero entries in gridToFieldMap arrayDimCount=ungriddedDimCount+gridUsedDimCount ! Make sure gridToFieldMap is correct size if (present(gridToFieldMap)) then do i=1,dimCount if ((gridToFieldMap(i) <0) .or. (gridToFieldMap(i) > arrayDimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- gridToFieldMap value is outside range", & ESMF_CONTEXT, rcToReturn=rc) return endif enddo endif ! Take out the below test to allow Fields that don't have a dim that maps ! to the Grid. Take this code out for good after things have been tested for awhile. #if 0 ! Make sure gridToFieldMap contains at least one non-zero entry if (present(gridToFieldMap)) then contains_nonzero=.false. do i=1,dimCount if (gridToFieldMap(i) >0) then contains_nonzero=.true. endif enddo if (.not. contains_nonzero) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- gridToFieldMap must contains at least one value greater than 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif #endif ! Check distgridToArrayMap if (size(distgridToArrayMap) < dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- distgridToArrayMap is too small", & ESMF_CONTEXT, rcToReturn=rc) return endif ! set default GridToFieldMap if (present(gridToFieldMap)) then localGridToFieldMap(1:dimCount)=gridToFieldMap(1:dimCount) else do i=1,dimCount localGridToFieldMap(i)=i enddo endif ! allocate distgridToGridMap allocate(distgridToGridMap(dimCount) , stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distgridToGridMap", & ESMF_CONTEXT, rcToReturn=rc)) return ! Get info from Grid call ESMF_GridGet(grid, distgridToGridMap=distgridToGridMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! construct distgridToArrayMap do i=1,dimCount distgridToArrayMap(i)=localGridToFieldMap(distgridToGridMap(i)) enddo ! construct array based on the presence of distributed dimensions ! if there are undistributed dimensions ... if (undistArrayDimCount > 0) then !! allocate array dim. info arrays allocate(arrayDimType(arrayDimCount) , stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridUBound", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(arrayDimInd(arrayDimCount) , stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridUBound", & ESMF_CONTEXT, rcToReturn=rc)) return !! set which dimensions are used by the distgrid arrayDimType(:)=0 ! initialize to no type do i=1,dimCount if (distGridToArrayMap(i) > 0) then ! skip replicated dims arrayDimType(distGridToArrayMap(i))=1 ! set to distributed endif enddo ! TODO: make the below cleaner given no grid undistdim !! Fill in ungridded bound info bndpos=1 do i=1,arrayDimCount if (arrayDimType(i) == 0) then arrayDimInd(i)=bndpos arrayDimType(i)=2 ! set to undistributed Array bndpos=bndpos+1 endif enddo !! Finally setup new Array bounds based on info in arrayDimType and arrayDimInd bndpos=1 do i=1,arrayDimCount if (arrayDimType(i) == 2) then undistLBound(bndpos)=ungriddedLBound(arrayDimInd(i)) undistUBound(bndpos)=ungriddedUBound(arrayDimInd(i)) bndpos=bndpos+1 endif enddo !! cleanup deallocate(arrayDimType) deallocate(arrayDimInd) endif ! cleanup deallocate(distgridToGridMap) else ! Code for Arbitrarily Distributed Grid call ESMF_DistGridGet(distgrid, dimCount=distDimCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(gridToFieldMap)) then gridUsedDimCount=0 do i=1,dimCount if (gridToFieldMap(i) > 0) then gridUsedDimCount=gridUsedDimCount+1 endif enddo else ! Default assumes all grid dims are used so add number of grid dims gridUsedDimCount=dimCount endif ! calc full Array DimCount ! Its the ungriddedDimCount + the number of non-zero entries in gridToFieldMap fieldDimCount=ungriddedDimCount+gridUsedDimCount ! Make sure gridToFieldMap is correct size ! check for replicated dimension if (present(gridToFieldMap)) then do i=1,dimCount if ((gridToFieldMap(i) <0) .or. (gridToFieldMap(i) > fieldDimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- gridToFieldMap value is outside range", & ESMF_CONTEXT, rcToReturn=rc) return endif enddo endif ! set default GridToFieldMap if (present(gridToFieldMap)) then localGridToFieldMap(1:dimCount)=gridToFieldMap(1:dimCount) else do i=1,dimCount localGridToFieldMap(i)=i enddo endif ! If there is replicated dimension, check if they are arbitrarily distributed dimension ! The array dimension varies depends whether the replicated dimensions are arb. or not allocate(distgridToGridMap(dimCount)) call ESMF_GridGet(grid, distgridToGridMap=distgridToGridMap, & arbDim=arbdim, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Check distgridToArrayMap if (size(distgridToArrayMap) < distDimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- distgridToArrayMap is too small", & ESMF_CONTEXT, rcToReturn=rc) return endif ! count how many replicated dimensions are not arbitrary and if any of replicated dimension ! is arbitrary. Assuming if one arbitrary dim is replicated, all the arbitrary dimension ! should also be replicated. This check is done in ESMF_FieldCreate already ! initialze distgridToArrayMap do i=1,distDimCount distgridToArrayMap(i)= i enddo ! if there is any replicated dimensions, reassign distgridToArrayMap rep_arb = 0 rep_noarb = 0 if (gridUsedDimCount < dimCount) then k = 1 do i=1,dimCount found = .false. if (localGridToFieldMap(i) == 0) then do j=1,dimCount if (distgridToGridMap(j) == i) then found = .true. exit endif enddo if (found) then distgridToArrayMap(arbdim) = 0 rep_arb = 1 else rep_noarb = rep_noarb+1 if (k == arbdim) k = k + 1 distgridToArrayMap(k) = 0 k=k+1 endif endif enddo j=1 do i=1,distDimCount if (distgridToArrayMap(i) /= 0) then distgridToArrayMap(i)= j j=j+1 endif enddo endif arrayDimCount=ungriddedDimCount+distDimCount-rep_noarb-rep_arb deallocate(distgridToGridMap) ! construct array based on the presence of distributed dimensions ! if there are undistributed dimensions ... if (undistArrayDimCount > 0) then ! Copy ungriddedBound to undistBound do i=1,undistArrayDimCount undistLBound(i)=ungriddedLBound(i) undistUBound(i)=ungriddedUBound(i) enddo endif endif ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetArrayInfo !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreate" !BOP ! !IROUTINE: ESMF_GridCreate - Create a copy of a Grid with a new DistGrid ! !INTERFACE: ! Private name; call using ESMF_GridCreate() function ESMF_GridCreateCopyFromNewDG(grid, distgrid, keywordEnforcer, & name, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridCreateCopyFromNewDG ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type(ESMF_DistGrid), intent(in) :: distgrid type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This call allows the user to copy of an existing ESMF Grid, but with a new distribution. ! All internal data from the old Grid (coords, items) is redistributed to the new Grid. ! ! The arguments are: ! \begin{description} ! \item[grid] ! {\tt ESMF\_Grid} to copy. ! \item[distgrid] ! {\tt ESMF\_DistGrid} object which describes how the Grid is decomposed and ! distributed over DEs. ! \item[{[name]}] ! Name of the new Grid. If not specified, a new unique name will be created ! for the Grid. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP type(ESMF_Grid) :: newGrid integer :: localrc ! local error status type(ESMF_TypeKind_Flag) :: coordTypeKind integer :: distgridToGridMap(ESMF_MAXDIM) integer :: coordDimCount(ESMF_MAXDIM) integer :: coordDimMap(ESMF_MAXDIM,ESMF_MAXDIM) integer :: gridEdgeLWidth(ESMF_MAXDIM) integer :: gridEdgeUWidth(ESMF_MAXDIM) integer :: gridAlign(ESMF_MAXDIM) type(ESMF_Index_Flag) :: indexflag integer :: i, j, nStaggers type(ESMF_ArrayBundle) :: srcAB, dstAB type(ESMF_RouteHandle) :: routehandle type(ESMF_STAGGERLOC), allocatable :: srcStaggers(:) type(ESMF_Array), allocatable :: srcA(:), dstA(:) type(ESMF_Array), allocatable :: srcA2D(:), dstA2D(:) type(ESMF_DistGrid):: dg type(ESMF_TypeKind_Flag):: tk integer:: atodMap(1), k real(ESMF_KIND_R8), pointer:: farrayPtr(:), farrayPtr2d(:,:) integer:: rank, dimCount logical, allocatable:: srcRepl(:), dstRepl(:) ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_DistGridGetInit, distgrid, rc) ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) ! TODO: NEED TO MAKE SURE INCOMING DistGrid HAS SAME MinIndex, MaxIndex AS EXISTING ! Grid's DistGrid ! Get info from old grid to create new Grid. call ESMF_GridGet(grid, & dimCount=dimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Get info from old grid to create new Grid. call ESMF_GridGet(grid, & dimCount=dimCount, & coordTypeKind=coordTypeKind, & distgridToGridMap=distgridToGridMap(1:dimCount), & coordDimCount=coordDimCount(1:dimCount), & coordDimMap=coordDimMap(1:dimCount,1:dimCount), & gridEdgeLWidth=gridEdgeLWidth(1:dimCount), & gridEdgeUWidth=gridEdgeUWidth(1:dimCount), & gridAlign=gridAlign(1:dimCount), & indexFlag=indexFlag, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Create New Grid newGrid=ESMF_GridCreate(name=name, & coordTypeKind=coordTypeKind, & distgrid=distgrid, & distgridToGridMap=distgridToGridMap(1:dimCount), & coordDimCount=coordDimCount(1:dimCount), & coordDimMap=coordDimMap(1:dimCount,1:dimCount), & gridEdgeLWidth=gridEdgeLWidth(1:dimCount), & gridEdgeUWidth=gridEdgeUWidth(1:dimCount), & gridAlign=gridAlign(1:dimCount), & ! gridMemLBound=gridMemLBound, & ! TODO: NEED TO ADD THIS TO GET indexFlag=indexFlag, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! For Bob: ! please fill out nStaggers and srcStaggers list, rest of the code is ! is generic. nStaggers and srcStaggers are currently hardcoded for demo. nStaggers = 3 allocate(srcStaggers(nStaggers)) srcStaggers(1) = ESMF_STAGGERLOC_CENTER srcStaggers(2) = ESMF_STAGGERLOC_EDGE1 srcStaggers(3) = ESMF_STAGGERLOC_EDGE2 ! Add Coords to new grid do i = 1, nStaggers call ESMF_GridAddCoord(newGrid, staggerloc=srcStaggers(i), rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return enddo ! Create Arraybundle ! Pull coord Arrays out of old grid and put them into Arraybundle ! for each staggerloc added above allocate(srcA(dimCount*nStaggers), dstA(dimCount*nStaggers)) allocate(srcA2D(dimCount*nStaggers), dstA2D(dimCount*nStaggers)) allocate(srcRepl(dimCount*nStaggers), dstRepl(dimCount*nStaggers)) do i=1,dimCount do j = 1, nStaggers call ESMF_GridGetCoord(grid, coordDim=i, staggerloc=srcStaggers(j), & array=srcA((i-1)*nStaggers+j), rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return enddo enddo !TODO: gjt: The following is completely hacked for now, just to get the !TODO: gjt: demo working. Basically the problem is that we don't currently !TODO: gjt: support communication calls for Arrays with replicated dims. !TODO: gjt: So I create temporary 2D Arrays, put the coordinates from the !TODO: gjt: src Grid (1D replicated on 2D DistGrid) onto the 2D Arrays and !TODO: gjt: Redist() to another temporary set of 2D Arrays on the dst side. !TODO: gjt: From there it is finally copied into the 1D replicated dst side !TODO: gjt: coordinate Arrays. - nasty ha! ! construct temporary 2D Arrays and fill with data if necessary do k=1, dimCount*nStaggers call ESMF_ArrayGet(srcA(k), rank=rank, dimCount=dimCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (rank==dimCount) then ! branch that assumes no replicated dims in Array ! TODO: actually there may still be replication, only ! TODO: arrayToDistGridMap conclusively provides that indication srcRepl(k) = .false. srcA2D(k) = srcA(k) else ! this branch is hard-coded for 2D DistGrids with 1D replicated ! dim Arrays along one dimension srcRepl(k) = .true. call ESMF_ArrayGet(srcA(k), distgrid=dg, typekind=tk, & arrayToDistGridMap=atodMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return srcA2D(k) = ESMF_ArrayCreate(distgrid=dg, typekind=tk, & indexflag=ESMF_INDEX_GLOBAL, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(srcA(k), farrayPtr=farrayPtr, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(srcA2D(k), farrayPtr=farrayPtr2D, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (atodMap(1)==1) then do j=lbound(farrayPtr2D,2), ubound(farrayPtr2D,2) do i=lbound(farrayPtr2D,1), ubound(farrayPtr2D,1) farrayPtr2D(i,j) = farrayPtr(i) enddo enddo else do j=lbound(farrayPtr2D,2), ubound(farrayPtr2D,2) do i=lbound(farrayPtr2D,1), ubound(farrayPtr2D,1) farrayPtr2D(i,j) = farrayPtr(j) enddo enddo endif endif enddo srcAB = ESMF_ArrayBundleCreate(arrayList=srcA2D(1:nStaggers), rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Create 2nd Arraybundle ! Pull coord Arrays out of new grid and put them into Arraybundle ! for each staggerloc added above do i=1,dimCount do j = 1, nStaggers call ESMF_GridGetCoord(newGrid, coordDim=i, staggerloc=srcStaggers(j), & array=dstA((i-1)*nStaggers+j), rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return enddo enddo ! construct temporary 2D Arrays do k=1, dimCount*nStaggers call ESMF_ArrayGet(dstA(k), rank=rank, dimCount=dimCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (rank==dimCount) then ! branch that assumes no replicated dims in Array ! TODO: actually there may still be replication, only ! TODO: arrayToDistGridMap conclusively provides that indication dstRepl(k) = .false. dstA2D(k) = dstA(k) else dstRepl(k) = .true. call ESMF_ArrayGet(dstA(k), distgrid=dg, typekind=tk, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return dstA2D(k) = ESMF_ArrayCreate(distgrid=dg, typekind=tk, & indexflag=ESMF_INDEX_GLOBAL, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif enddo dstAB = ESMF_ArrayBundleCreate(arrayList=dstA2D(1:nStaggers), rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Redist between ArrayBundles ! call ESMF_ArrayBundleRedistStore(srcAB, dstAB, routehandle=routehandle, rc=localrc) ! if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ! ESMF_CONTEXT, rcToReturn=rc)) return ! call ESMF_ArrayBundleRedist(srcAB, dstAB, routehandle=routehandle, rc=localrc) ! if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ! ESMF_CONTEXT, rcToReturn=rc)) return !TODO: figure out why ArrayBundleRedist() does not seem to work right for !TODO: some of the Arrays -> use individual ArrayRedist() instead as work-around do k=1, dimCount*nStaggers call ESMF_ArrayRedistStore(srcA2D(k), dstA2D(k), routehandle=routehandle, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayRedist(srcA2D(k), dstA2D(k), routehandle=routehandle, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayRedistRelease(routehandle=routehandle, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return enddo ! Fill the replicated dimension Arrays from the 2D redist data do k=1, dimCount*nStaggers if (dstRepl(k)) then call ESMF_ArrayGet(dstA(k), arrayToDistGridMap=atodMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(dstA(k), farrayPtr=farrayPtr, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(dstA2D(k), farrayPtr=farrayPtr2D, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (atodMap(1)==1) then do i=lbound(farrayPtr2D,1), ubound(farrayPtr2D,1) farrayPtr(i) = farrayPtr2D(i,lbound(farrayPtr2D,2)) enddo else do j=lbound(farrayPtr2D,2), ubound(farrayPtr2D,2) farrayPtr(j) = farrayPtr2D(lbound(farrayPtr2D,1),j) enddo endif endif enddo ! clean up temporary Arrays do k=1, dimCount*nStaggers if (srcRepl(k)) then call ESMF_ArrayDestroy(srcA2D(k), rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif if (dstRepl(k)) then call ESMF_ArrayDestroy(dstA2D(k), rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif enddo deallocate(srcA) deallocate(srcA2D) deallocate(dstA) deallocate(dstA2D) deallocate(srcStaggers) deallocate(srcRepl) deallocate(dstRepl) ! Destroy ArrayBundles and release Routehandle ! call ESMF_ArrayBundleRedistRelease(routehandle=routehandle, rc=localrc) ! if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ! ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayBundleDestroy(srcAB, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayBundleDestroy(dstAB, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set return value ESMF_GridCreateCopyFromNewDG = newGrid ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateCopyFromNewDG !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreateCopyFromReg" !BOP ! !IROUTINE: ESMF_GridCreate - Create a copy of a Grid with a different regular distribution ! !INTERFACE: ! Private name; call using ESMF_GridCreate() function ESMF_GridCreateCopyFromReg(grid, keywordEnforcer, & regDecomp, decompFlag, name, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridCreateCopyFromReg ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(in), optional :: regDecomp(:) type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! ! This method creates a copy of an existing Grid, the new Grid is ! regularly distributed (see Figure \ref{fig:GridDecomps}). ! To specify the new distribution, the user passes in an array ! ({\tt regDecomp}) specifying the number of DEs to divide each ! dimension into. The array {\tt decompFlag} indicates how the division into DEs is to ! occur. The default is to divide the range as evenly as possible. ! ! The arguments are: ! \begin{description} ! \item[grid] ! {\tt ESMF\_Grid} to copy. ! \item[{[regDecomp]}] ! List that has the same number of elements as {\tt maxIndex}. ! Each entry is the number of decounts for that dimension. ! If not specified, the default decomposition will be petCountx1x1..x1. ! \item[{[decompflag]}] ! List of decomposition flags indicating how each dimension of the ! tile is to be divided between the DEs. The default setting ! is {\tt ESMF\_DECOMP\_BALANCED} in all dimensions. Please see ! Section~\ref{const:decompflag} for a full description of the ! possible options. ! \item[{[name]}] ! Name of the new Grid. If not specified, a new unique name will be ! created for the Grid. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP type(ESMF_DistGrid) :: distgrid type(ESMF_DistGrid) :: oldDistgrid type(ESMF_DELayout) :: delayout type(ESMF_VM) :: vm integer, pointer :: petList(:) integer :: localrc integer :: dimCount,i integer, pointer :: regDecompLocal(:) type(ESMF_Decomp_Flag), pointer :: decompflagLocal(:) integer :: deCount integer :: i1,i2,i3,k, tileCount integer,pointer :: minIndexPDimPTile(:,:) integer,pointer :: maxIndexPDimPTile(:,:) integer,pointer :: minIndexLocal(:) integer,pointer :: maxIndexLocal(:) type(ESMF_Index_Flag) :: indexflag ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Get the Grid DimCount --------------------------------------------------- call ESMF_GridGet(grid, dimCount=dimCount, indexflag=indexflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Argument Consistency Checking -------------------------------------------------------------- if (present(regDecomp)) then if (size(regDecomp) .lt. dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- regDecomp size doesn't match Grid dimCount ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(decompFlag)) then if (size(decompFlag) .lt. dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- decompFlag size doesn't match Grid dimCount ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Get min/max Index from old grid ------------------------------------------------------------------ ! Get old distgrid call ESMF_GridGet(grid, distgrid=oldDistgrid, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Get a couple of sizes call ESMF_DistgridGet(oldDistgrid, tileCount=tileCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Get Index info from DistGrid allocate(minIndexPDimPTile(dimCount,tileCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexPDimTile", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(maxIndexPDimPTile(dimCount,tileCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxIndexPDimTile", & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_DistgridGet(oldDistgrid, & minIndexPTile=minIndexPDimPTile, & maxIndexPTile=maxIndexPDimPTile, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! This doesn't work right now for Multitile Grids if (tileCount > 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- GridCopy with reg distribution not supported for multitile grids", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set minIndex allocate(minIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return minIndexLocal(1:dimCount)=minIndexPDimPTile(1:dimCount,1) ! Set maxIndex allocate(maxIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexLocal(1:dimCount)=maxIndexPDimPTile(1:dimCount,1) ! Free memory from distgrid get deallocate(minIndexPDimPTile) deallocate(maxIndexPDimPTile) ! Set default for regDecomp allocate(regDecompLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating regDecompLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(regDecomp)) then regDecompLocal(:)=regDecomp(:) else ! The default is 1D divided among all the Pets call ESMF_VMGetGlobal(vm,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_VMGet(vm,petCount=regDecompLocal(1),rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return do i=2,dimCount regDecompLocal(i)=1 enddo endif ! Set default for decomp flag based on gridEdgeWidths ----------------------------------- ! NOTE: This is a temporary fix until we have something better implemented in distGrid ! Set default for decompFlag allocate(decompFlagLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating decompFlagLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(decompFlag)) then decompFlagLocal(:)=decompFlag(:) else decompFlagLocal(:)=ESMF_DECOMP_BALANCED endif ! Process PetMap -------------------------------------------------------------- !! Calculate deCount deCount=1 do i=1,dimCount deCount=deCount*regDecompLocal(i) enddo #if 0 ! create DELayout based on presence of petMap if (present(petMap)) then !! Allocate petList allocate(petList(deCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, "Allocating petList", & ESMF_CONTEXT, rcToReturn=rc)) return !! copy petMap to petList if (dimCount > 2) then k=1 do i3=1,regDecompLocal(3) do i2=1,regDecompLocal(2) do i1=1,regDecompLocal(1) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo else k=1 do i3=1,1 do i2=1,regDecompLocal(2) do i1=1,regDecompLocal(1) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo endif !! create delayout from the petList delayout=ESMF_DELayoutCreate(petList=petList,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Get rid of list deallocate(petList) else #endif !! create a default delayout delayout=ESMF_DELayoutCreate(deCount=deCount,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return #if 0 endif #endif ! Create DistGrid -------------------------------------------------------------- distgrid=ESMF_DistGridCreate(minIndex=minIndexLocal, maxIndex=maxIndexLocal, & regDecomp=regDecompLocal, decompFlag=decompFlagLocal, delayout=delayout,& indexflag=indexflag, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ESMF_GridCreateCopyFromReg=ESMF_GridCreate(grid, distgrid, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid call ESMF_GridSetDestroyDistgrid(grid,destroy=.true., rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout(grid,destroy=.true., rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(regDecompLocal) deallocate(decompFlagLocal) deallocate(minIndexLocal) deallocate(maxIndexLocal) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateCopyFromReg !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreateEdgeConnI" !BOP ! !IROUTINE: ESMF_GridCreate - Create a Grid with user set edge connections and an irregular distribution ! !INTERFACE: ! Private name; call using ESMF_GridCreate() function ESMF_GridCreateEdgeConnI(minIndex, & countsPerDEDim1,countsPerDeDim2, keywordEnforcer, & countsPerDEDim3, & connflagDim1, connflagDim2, connflagDim3, & coordSys, coordTypeKind, & coordDep1, coordDep2, coordDep3, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridMemLBound, indexflag, petMap, name, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridCreateEdgeConnI ! ! !ARGUMENTS: integer, intent(in), optional :: minIndex(:) integer, intent(in) :: countsPerDEDim1(:) integer, intent(in) :: countsPerDEDim2(:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(in), optional :: countsPerDEDim3(:) type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim1(:) type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim2(:) type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim3(:) type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(in), optional :: gridEdgeLWidth(:) integer, intent(in), optional :: gridEdgeUWidth(:) integer, intent(in), optional :: gridAlign(:) integer, intent(in), optional :: gridMemLBound(:) type(ESMF_Index_Flag), intent(in), optional :: indexflag integer, intent(in), optional :: petMap(:,:,:) character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This method creates a single tile, irregularly distributed grid ! (see Figure \ref{fig:GridDecomps}) without a periodic dimension. ! To specify the irregular distribution, the user passes in an array ! for each grid dimension, where the length of the array is the number ! of DEs in the dimension. Up to three dimensions can be specified, ! using the countsPerDEDim1, countsPerDEDim2, countsPerDEDim3 arguments. ! The index of each array element corresponds to a DE number. The ! array value at the index is the number of grid cells on the DE in ! that dimension. The dimCount of the grid is equal to the number of ! countsPerDEDim arrays that are specified. ! ! Section \ref{example:2DIrregUniGrid} shows an example ! of using this method to create a 2D Grid with uniformly spaced ! coordinates. This creation method can also be used as the basis for ! grids with rectilinear coordinates or curvilinear coordinates. ! ! The arguments are: ! \begin{description} ! \item[{[minIndex]}] ! Tuple to start the index ranges at. If not present, defaults ! to /1,1,1,.../. ! \item[{countsPerDEDim1}] ! This arrays specifies the number of cells per DE for index dimension 1 ! for the exclusive region (the center stagger location). ! \item[{countsPerDEDim2}] ! This array specifies the number of cells per DE for index dimension 2 ! for the exclusive region (center stagger location). ! \item[{[countsPerDEDim3]}] ! This array specifies the number of cells per DE for index dimension 3 ! for the exclusive region (center stagger location). ! If not specified then grid is 2D. ! \item[{[connflagDim1]}] ! Fortran array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connflagDim2]}] ! Fortran array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connflagDim3]}] ! Fortran array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[coordSys]}] ! The coordinate system of the grid coordinate data. ! For a full list of options, please see Section~\ref{const:coordsys}. ! If not specified then defaults to ESMF\_COORDSYS\_SPH\_DEG. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[coordDep1]}] ! This array specifies the dependence of the first ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the first ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep2]}] ! This array specifies the dependence of the second ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the second ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep3]}] ! This array specifies the dependence of the third ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the third ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[gridEdgeLWidth]}] ! The padding around the lower edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. It is an error for this to be non-zero ! for a periodic dimension. ! \item[{[gridEdgeUWidth]}] ! The padding around the upper edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. It is an error for this to be non-zero ! for a periodic dimension. ! \item[{[gridAlign]}] ! Specification of how the stagger locations should align with the cell ! index space (can be overridden by the individual staggerAligns). If ! the {\tt gridEdgeWidths} are not specified than this parameter ! implies the EdgeWidths. ! \item[{[gridMemLBound]}] ! Specifies the lower index range of the memory of every DE in this Grid. ! Only used when indexflag is {\tt ESMF\_INDEX\_USER}. May be overridden ! by staggerMemLBound. ! \item[{[indexflag]}] ! Indicates the indexing scheme to be used in the new Grid. Please see ! Section~\ref{const:indexflag} for the list of options. If not present, ! defaults to ESMF\_INDEX\_DELOCAL. ! \item[{[petMap]}] ! \begin{sloppypar} ! Sets the mapping of pets to the created DEs. This 3D ! should be of size size(countsPerDEDim1) x size(countsPerDEDim2) x ! size(countsPerDEDim3). If countsPerDEDim3 isn't present, then ! the last dimension is of size 1. ! \end{sloppypar} ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP type(ESMF_DistGrid) :: distgrid integer, pointer :: coordDimCount(:) integer, pointer :: coordDimMap(:,:) integer :: localrc integer :: dimCount integer, pointer :: gridEdgeLWidthLocal(:) integer, pointer :: gridEdgeUWidthLocal(:) integer, pointer :: gridAlignLocal(:) integer, pointer :: minIndexLocal(:) integer, pointer :: maxIndexLocal(:) type(ESMF_DistgridConnection), pointer :: connList(:) type(ESMF_CoordSys_Flag) :: coordSysLocal ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Get the dimension and extent of the index space call GetIndexSpaceIrreg(minIndex, & countsPerDEDim1,countsPerDeDim2, & countsPerDEDim3, dimCount, minIndexLocal, maxIndexLocal, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Build connection list call SetupTileConn(dimCount, minIndexLocal, maxIndexLocal, & connflagDim1, connflagDim2, connflagDim3, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Create Irregular distgrid and error check associated input and set defaults distgrid=ESMF_GridCreateDistgridIrreg(dimCount, minIndexLocal, maxIndexLocal, & countsPerDEDim1,countsPerDeDim2, & countsPerDEDim3, indexflag, petMap, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set default widths and alignment and error check allocate(gridEdgeLWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeLWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridEdgeUWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeUWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridAlignLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridAlignLocal", & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridLUADefault(dimCount, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridEdgeLWidthLocal, gridEdgeUWidthLocal, gridAlignLocal, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Convert coordDeps to coordDimCount and coordDimMap allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return call CoordInfoFromCoordDep(dimCount, coordDep1, coordDep2, coordDep3,& coordDimCount, coordDimMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set Default coordSys if (present(coordSys)) then coordSysLocal=coordSys else coordSysLocal=ESMF_COORDSYS_SPH_DEG endif ! Create Grid from specification ESMF_GridCreateEdgeConnI=ESMF_GridCreateFrmDistGrid( & distgrid, & coordSys=coordSysLocal, & coordTypeKind=coordTypeKind, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & gridEdgeLWidth=gridEdgeLWidthLocal, & gridEdgeUWidth=gridEdgeUWidthLocal, & gridAlign=gridAlignLocal, & gridMemLBound=gridMemLBound, & indexflag=indexflag, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid Call ESMF_GridSetDestroyDistgrid( ESMF_GridCreateEdgeConnI,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout( ESMF_GridCreateEdgeConnI,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(connList) deallocate(minIndexLocal) deallocate(maxIndexLocal) deallocate(coordDimCount) deallocate(coordDimMap) deallocate(gridEdgeLWidthLocal) deallocate(gridEdgeUWidthLocal) deallocate(gridAlignLocal) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateEdgeConnI !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreateEdgeConnR" !BOP ! !IROUTINE: ESMF_GridCreate - Create a Grid with user set edge connections and a regular distribution ! !INTERFACE: ! Private name; call using ESMF_GridCreate() function ESMF_GridCreateEdgeConnR(regDecomp, decompFlag, & minIndex, maxIndex, keywordEnforcer, & connflagDim1, connflagDim2, connflagDim3, & coordSys, coordTypeKind, & coordDep1, coordDep2, coordDep3, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridMemLBound, indexflag, petMap, name, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridCreateEdgeConnR ! ! !ARGUMENTS: integer, intent(in), optional :: regDecomp(:) type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) integer, intent(in), optional :: minIndex(:) integer, intent(in) :: maxIndex(:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim1(:) type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim2(:) type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim3(:) type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(in), optional :: gridEdgeLWidth(:) integer, intent(in), optional :: gridEdgeUWidth(:) integer, intent(in), optional :: gridAlign(:) integer, intent(in), optional :: gridMemLBound(:) type(ESMF_Index_Flag), intent(in), optional :: indexflag integer, intent(in), optional :: petMap(:,:,:) character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This method creates a single tile, regularly distributed grid ! (see Figure \ref{fig:GridDecomps}). ! To specify the distribution, the user passes in an array ! ({\tt regDecomp}) specifying the number of DEs to divide each ! dimension into. The array {\tt decompFlag} indicates how the division into DEs is to ! occur. The default is to divide the range as evenly as possible. ! ! The arguments are: ! \begin{description} ! \item[{[regDecomp]}] ! List that has the same number of elements as {\tt maxIndex}. ! Each entry is the number of decounts for that dimension. ! If not specified, the default decomposition will be petCountx1x1..x1. ! \item[{[decompflag]}] ! List of decomposition flags indicating how each dimension of the ! tile is to be divided between the DEs. The default setting ! is {\tt ESMF\_DECOMP\_BALANCED} in all dimensions. Please see ! Section~\ref{const:decompflag} for a full description of the ! possible options. ! \item[{[minIndex]}] ! The bottom extent of the grid array. If not given then the value defaults ! to /1,1,1,.../. ! \item[{maxIndex}] ! The upper extent of the grid array. ! \item[{[connflagDim1]}] ! Fortran array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connflagDim2]}] ! Fortran array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connflagDim3]}] ! Fortran array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[coordSys]}] ! The coordinate system of the grid coordinate data. ! For a full list of options, please see Section~\ref{const:coordsys}. ! If not specified then defaults to ESMF\_COORDSYS\_SPH\_DEG. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[coordDep1]}] ! This array specifies the dependence of the first ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the first ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep2]}] ! This array specifies the dependence of the second ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the second ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep3]}] ! This array specifies the dependence of the third ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the third ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[gridEdgeLWidth]}] ! The padding around the lower edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. It is an error for this to be non-zero ! for a periodic dimension. ! \item[{[gridEdgeUWidth]}] ! The padding around the upper edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. It is an error for this to be non-zero ! for a periodic dimension. ! \item[{[gridAlign]}] ! Specification of how the stagger locations should align with the cell ! index space (can be overridden by the individual staggerAligns). If ! the {\tt gridEdgeWidths} are not specified than this parameter ! implies the EdgeWidths. ! \item[{[gridMemLBound]}] ! Specifies the lower index range of the memory of every DE in this Grid. ! Only used when indexflag is {\tt ESMF\_INDEX\_USER}. May be overridden ! by staggerMemLBound. ! \item[{[indexflag]}] ! Indicates the indexing scheme to be used in the new Grid. Please see ! Section~\ref{const:indexflag} for the list of options. If not present, ! defaults to ESMF\_INDEX\_DELOCAL. ! \item[{[petMap]}] ! Sets the mapping of pets to the created DEs. This 3D ! should be of size regDecomp(1) x regDecomp(2) x regDecomp(3) ! If the Grid is 2D, then the last dimension is of size 1. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP type(ESMF_DistGrid) :: distgrid integer, pointer :: coordDimCount(:) integer, pointer :: coordDimMap(:,:) integer, pointer :: gridEdgeLWidthLocal(:) integer, pointer :: gridEdgeUWidthLocal(:) integer, pointer :: gridAlignLocal(:) integer :: dimCount integer, pointer :: minIndexLocal(:) integer, pointer :: maxIndexLocal(:) integer :: localrc type(ESMF_DistgridConnection), pointer :: connList(:) type(ESMF_CoordSys_Flag) :: coordSysLocal !XX ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Get IndexSpace call GetIndexSpaceReg(minIndex, maxIndex, & dimCount, minIndexLocal, maxIndexLocal, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Build connection list call SetupTileConn(dimCount, minIndexLocal, maxIndexLocal, & connflagDim1, connflagDim2, connflagDim3, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Compute regular distgrid and error check associated input and set defaults distgrid=ESMF_GridCreateDistgridReg(dimCount, minIndexLocal, maxIndexLocal, & regDecomp, decompFlag, indexflag, petMap, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set default widths and alignment and error check allocate(gridEdgeLWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeLWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridEdgeUWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeUWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridAlignLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridAlignLocal", & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridLUADefault(dimCount, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridEdgeLWidthLocal, gridEdgeUWidthLocal, gridAlignLocal, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Convert coordDeps to coordDimCount and coordDimMap allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return call CoordInfoFromCoordDep(dimCount, coordDep1, coordDep2, coordDep3,& coordDimCount, coordDimMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! XMRKX ! Set Default coordSys if (present(coordSys)) then coordSysLocal=coordSys else coordSysLocal=ESMF_COORDSYS_SPH_DEG endif ! Create Grid from specification ESMF_GridCreateEdgeConnR=ESMF_GridCreateFrmDistGrid(& distgrid, & coordSys=coordSysLocal, & coordTypeKind=coordTypeKind, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & gridEdgeLWidth=gridEdgeLWidthLocal, & gridEdgeUWidth=gridEdgeUWidthLocal, & gridAlign=gridAlignLocal, & gridMemLBound=gridMemLBound, & indexflag=indexflag, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid call ESMF_GridSetDestroyDistgrid(ESMF_GridCreateEdgeConnR,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout(ESMF_GridCreateEdgeConnR,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(connList) deallocate(coordDimCount) deallocate(coordDimMap) deallocate(gridEdgeLWidthLocal) deallocate(gridEdgeUWidthLocal) deallocate(gridAlignLocal) deallocate(minIndexLocal) deallocate(maxIndexLocal) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateEdgeConnR !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreateEdgeConnA" !BOP ! !IROUTINE: ESMF_GridCreate - Create a Grid with user set edge connections and an arbitrary distribution ! !INTERFACE: ! Private name; call using ESMF_GridCreate() function ESMF_GridCreateEdgeConnA(minIndex, maxIndex, & arbIndexCount, arbIndexList, keywordEnforcer, & connflagDim1, connflagDim2, connflagDim3, & coordSys, coordTypeKind, & coordDep1, coordDep2, coordDep3, & distDim, name, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridCreateEdgeConnA ! ! !ARGUMENTS: integer, intent(in), optional :: minIndex(:) integer, intent(in) :: maxIndex(:) integer, intent(in) :: arbIndexCount integer, intent(in) :: arbIndexList(:,:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim1(:) type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim2(:) type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim3(:) type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(in), optional :: distDim(:) character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This method creates a single tile, arbitrarily distributed grid ! (see Figure \ref{fig:GridDecomps}). ! To specify the arbitrary distribution, the user passes in an 2D array ! of local indices, where the first dimension is the number of local grid cells ! specified by {\tt localArbIndexCount} and the second dimension is the number of distributed ! dimensions. ! ! {\tt distDim} specifies which grid dimensions are arbitrarily distributed. The ! size of {\tt distDim} has to agree with the size of the second dimension of ! {\tt localArbIndex}. ! ! The arguments are: ! \begin{description} ! \item[{[minIndex]}] ! Tuple to start the index ranges at. If not present, defaults ! to /1,1,1,.../. ! \item[{[maxIndex]}] ! The upper extend of the grid index ranges. ! \item[{arbIndexCount}] ! The number of grid cells in the local DE. It is okay to have 0 ! grid cell in a local DE. ! \item[{[arbIndexList]}] ! This 2D array specifies the indices of the PET LOCAL grid cells. The ! dimensions should be arbIndexCount * number of Distributed grid dimensions ! where arbIndexCount is the input argument specified below ! \item[{[connflagDim1]}] ! Fortran array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connflagDim2]}] ! Fortran array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connflagDim3]}] ! Fortran array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[coordSys]}] ! The coordinate system of the grid coordinate data. ! For a full list of options, please see Section~\ref{const:coordsys}. ! If not specified then defaults to ESMF\_COORDSYS\_SPH\_DEG. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[coordDep1]}] ! The size of the array specifies the number of dimensions of the ! first coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_DIM\_ARB/ where ! /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_DIM\_ARB/ if the first dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=1) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB. ! \item[{[coordDep2]}] ! The size of the array specifies the number of dimensions of the ! second coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_DIM\_ARB/ where ! /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_DIM\_ARB/ if this dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=2) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB. ! \item[{[coordDep3]}] ! The size of the array specifies the number of dimensions of the ! third coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_DIM\_ARB/ where ! /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_DIM\_ARB/ if this dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=3) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB. ! \item[{[distDim]}] ! This array specifies which dimensions are arbitrarily distributed. ! The size of the array specifies the total distributed dimensions. ! if not specified, defaults is all dimensions will be arbitrarily ! distributed. The size has to agree with the size of the second ! dimension of {\tt localArbIndex}. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP type(ESMF_DistGrid) :: distgrid integer, pointer :: coordDimCount(:) integer, pointer :: coordDimMap(:,:) integer :: localrc integer :: dimCount,distDimCount integer :: i integer, pointer :: indexArray(:,:) logical, pointer :: isDistLocal(:) integer, pointer :: distDimLocal(:) integer, pointer :: minIndexLocal(:) integer, pointer :: maxIndexLocal(:) type(ESMF_DistgridConnection), pointer :: connList(:) type(ESMF_CoordSys_Flag) :: coordSysLocal ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Get description of index space and what's undistributed call GetIndexSpaceArb(minIndex, maxIndex, & arbIndexCount, arbIndexList, distDim, & dimCount, distDimCount, isDistLocal, distDimLocal, & minIndexLocal, maxIndexLocal, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Build connection list call SetupTileConn(dimCount, minIndexLocal, maxIndexLocal, & connflagDim1, connflagDim2, connflagDim3, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Create arbitrary distgrid distgrid= ESMF_GridCreateDistgridArb(dimCount, distDimCount, isDistLocal, distDimLocal, & minIndexLocal, maxIndexLocal, arbIndexCount, arbIndexList, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Convert coordDeps to coordDimCount and coordDimMap allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return call CoordInfoFromCoordDepArb(dimCount, isDistLocal, coordDep1, coordDep2, coordDep3,& coordDimCount, coordDimMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Put minIndex, maxIndex into indexArray for create from distgrid allocate(indexArray(2,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating indexArray", & ESMF_CONTEXT, rcToReturn=rc)) return indexArray(1,:)=minIndexLocal(:) indexArray(2,:)=maxIndexLocal(:) ! Set Default coordSys if (present(coordSys)) then coordSysLocal=coordSys else coordSysLocal=ESMF_COORDSYS_SPH_DEG endif ! Create Grid from specification ----------------------------------------------- ESMF_GridCreateEdgeConnA=ESMF_GridCreateFrmDistGridArb( & distgrid, indexArray, & distDim=distDimLocal, & coordSys=coordSysLocal, & coordTypeKind=coordTypeKind, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid call ESMF_GridSetDestroyDistgrid(ESMF_GridCreateEdgeConnA,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout(ESMF_GridCreateEdgeConnA,destroy=.false., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(connList) deallocate(minIndexLocal) deallocate(maxIndexLocal) deallocate(isDistLocal) deallocate(indexArray) deallocate(distDimLocal) deallocate(coordDimCount) deallocate(coordDimMap) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateEdgeConnA !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreate" !BOP ! !IROUTINE: ESMF_GridCreate - Create a Grid from a DistGrid ! !INTERFACE: ! Private name; call using ESMF_GridCreate() function ESMF_GridCreateFrmDistGrid(distgrid, & distgridToGridMap, & coordSys, coordTypeKind, coordDimCount, coordDimMap, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridMemLBound, indexflag, name, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridCreateFrmDistGrid ! ! !ARGUMENTS: type(ESMF_DistGrid), intent(in) :: distgrid integer, intent(in), optional :: distgridToGridMap(:) type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: coordDimCount(:) integer, intent(in), optional :: coordDimMap(:,:) integer, intent(in), optional :: gridEdgeLWidth(:) integer, intent(in), optional :: gridEdgeUWidth(:) integer, intent(in), optional :: gridAlign(:) integer, intent(in), optional :: gridMemLBound(:) type(ESMF_Index_Flag), intent(in), optional :: indexflag character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This is the most general form of creation for an {\tt ESMF\_Grid} ! object. It allows the user to fully specify the topology and index space ! using the DistGrid methods and then build a grid out ! of the resulting DistGrid. Note that since the Grid created by this call ! uses {\tt distgrid} as a description of its index space, the resulting Grid ! will have exactly the same number of dimensions (i.e. the same dimCount) as ! {\tt distgrid}. The {\tt distgridToGridMap} argument ! specifies how the Grid dimensions are mapped to the {\tt distgrid}. ! The {\tt coordDimCount} and {\tt coordDimMap} arguments ! allow the user to specify how the coordinate arrays should map to the grid ! dimensions. (Note, though, that creating a grid does not allocate coordinate ! storage. A method such as {\tt ESMF\_GridAddCoord()} must be called ! before adding coordinate values.) ! ! The arguments are: ! \begin{description} ! \item[distgrid] ! {\tt ESMF\_DistGrid} object that describes how the array is decomposed and ! distributed over DEs. ! \item[{[distgridToGridMap]}] ! List that has dimCount elements. ! The elements map each dimension of distgrid to a dimension in the grid. ! (i.e. the values should range from 1 to dimCount). If not specified, the default ! is to map all of distgrid's dimensions against the dimensions of the ! grid in sequence. ! \item[{[coordSys]}] ! The coordinate system of the grid coordinate data. ! For a full list of options, please see Section~\ref{const:coordsys}. ! If not specified then defaults to ESMF\_COORDSYS\_CART. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[coordDimCount]}] ! List that has dimCount elements. ! Gives the dimension of each component (e.g. x) array. This is ! to allow factorization of the coordinate arrays. If not specified ! all arrays are the same size as the grid. ! \item[{[coordDimMap]}] ! 2D list of size dimCount x dimCount. This array describes the ! map of each component array's dimensions onto the grids ! dimensions. Each entry {\tt coordDimMap(i,j)} tells which ! grid dimension component i's, jth dimension maps to. ! Note that if j is bigger than {\tt coordDimCount(i)} it is ignored. ! The default for each row i is {\tt coordDimMap(i,:)=(1,2,3,4,...)}. ! \item[{[gridEdgeLWidth]}] ! The padding around the lower edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. ! \item[{[gridEdgeUWidth]}] ! The padding around the upper edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. ! \item[{[gridAlign]}] ! Specification of how the stagger locations should align with the cell ! index space (can be overridden by the individual staggerAligns). If ! the {\tt gridEdgeWidths} are not specified than this parameter ! implies the EdgeWidths. ! \item[{[gridMemLBound]}] ! Specifies the lower index range of the memory of every DE in this Grid. ! Only used when indexflag is {\tt ESMF\_INDEX\_USER}. May be overridden ! by staggerMemLBound. ! \item[{[indexflag]}] ! Indicates the indexing scheme to be used in the new Grid. Please see ! Section~\ref{const:indexflag} for the list of options. If not present, ! defaults to ESMF\_INDEX\_DELOCAL. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP integer :: localrc ! local error status type(ESMF_Grid) :: grid integer :: nameLen type(ESMF_InterfaceInt) :: gridEdgeLWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: gridEdgeUWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: gridAlignArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: gridMemLBoundArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: distgridToGridMapArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: coordDimCountArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: coordDimMapArg ! Language Interface Helper Var integer :: intDestroyDistgrid,intDestroyDELayout integer, allocatable :: collocation(:) logical :: arbSeqIndexFlag integer :: i, deCount, distDimCount, arbDim type(ESMF_DELayout) :: delayout ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_DistGridGetInit, distgrid, rc) ! Translate F90 arguments to C++ friendly form !! name nameLen=0 if (present(name)) then nameLen=len_trim(name) endif !! Check if the DistGrid is an arbitrary distgrid arbDim = -1 call ESMF_DistGridGet(distgrid, delayout=delayout, dimCount=distDimCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_DELayoutGet(delayout, localDeCount=deCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (deCount > 0) then allocate(collocation(distDimCount)) ! dimCount call ESMF_DistGridGet(distgrid, & collocation=collocation, rc=localrc) do i=1,distDimCount call ESMF_DistGridGet(distgrid, localDe=0, collocation=collocation(i), & arbSeqIndexFlag=arbSeqIndexFlag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (arbSeqIndexFlag) arbDim = i enddo deallocate(collocation) endif if (arbDim /= -1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- distgrid should not contain arbitrary sequence indices", & ESMF_CONTEXT, rcToReturn=rc) return endif !! coordTypeKind ! It doesn't look like it needs to be translated, but test to make sure !! staggerWidths gridEdgeLWidthArg = ESMF_InterfaceIntCreate(gridEdgeLWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return gridEdgeUWidthArg = ESMF_InterfaceIntCreate(gridEdgeUWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return gridAlignArg = ESMF_InterfaceIntCreate(gridAlign, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return gridMemLBoundArg = ESMF_InterfaceIntCreate(gridMemLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! distgridToGridMap distgridToGridMapArg = ESMF_InterfaceIntCreate(distgridToGridMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Description of array factorization coordDimCountArg = ESMF_InterfaceIntCreate(coordDimCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return coordDimMapArg = ESMF_InterfaceIntCreate(farray2D=coordDimMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Initialize this grid object as invalid grid%this = ESMF_NULL_POINTER !! Convert destroyDistGrid flag ! default to don't destroy, subroutine used to actually set flags in other creates intDestroyDistgrid=0 intDestroyDELayout=0 ! Call C++ Subroutine to do the create call c_ESMC_gridcreatefromdistgrid(grid%this, nameLen, name, & coordTypeKind, distgrid, distgridToGridMapArg, coordsys, & coordDimCountArg, coordDimMapArg, & gridEdgeLWidthArg, gridEdgeUWidthArg, gridAlignArg, gridMemLBoundArg,& indexflag, intDestroyDistGrid, intDestroyDELayout, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate helper variables call ESMF_InterfaceIntDestroy(gridEdgeLWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(gridEdgeUWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(gridAlignArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(gridMemLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(distgridToGridMapArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(coordDimCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(coordDimMapArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set return value ESMF_GridCreateFrmDistGrid = grid ! Set init status ESMF_INIT_SET_CREATED(ESMF_GridCreateFrmDistGrid) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateFrmDistGrid !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreate" !BOP ! !IROUTINE: ESMF_GridCreate - Create a Arbitrary Grid from a DistGrid ! !INTERFACE: ! Private name; call using ESMF_GridCreate() function ESMF_GridCreateFrmDistGridArb(distgrid, & indexArray, distDim, & coordSys, coordTypeKind, coordDimCount, coordDimMap, & name, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridCreateFrmDistGridArb ! ! !ARGUMENTS: type(ESMF_DistGrid), intent(in) :: distgrid integer, intent(in) :: indexArray(:,:) integer, intent(in), optional :: distDim(:) type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: coordDimCount(:) integer, intent(in), optional :: coordDimMap(:,:) character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This is the lower level function to create an arbitrailiy distributed {\tt ESMF\_Grid} ! object. It allows the user to fully specify the topology and index space ! (of the distributed dimensions) using the DistGrid methods and then build a grid out ! of the resulting {\tt distgrid}. The {\tt indexArray(2,dimCount)}, ! argument is required to specifies the topology of the grid. ! ! The arguments are: ! \begin{description} ! \item[distgrid] ! {\tt ESMF\_DistGrid} object that describes how the array is decomposed and ! distributed over DEs. ! \item[{[indexArray]}] ! The minIndex and maxIndex array of size {\tt 2} x {\tt dimCount} ! {\tt indexArray(1,:)} is the minIndex and {\tt indexArray(2,:)} is the maxIndex ! \item[{[distDim]}] ! This array specifies which dimensions are arbitrarily distributed. ! The size of the array specifies the total distributed dimensions. ! if not specified, the default is that all dimensions will be arbitrarily ! distributed. ! \item[{[coordSys]}] ! The coordinate system of the grid coordinate data. ! For a full list of options, please see Section~\ref{const:coordsys}. ! If not specified then defaults to ESMF\_COORDSYS\_CART. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[coordDimCount]}] ! List that has dimCount elements. ! Gives the dimension of each component (e.g. x) array. This is ! to allow factorization of the coordinate arrays. If not specified ! each component is assumed to be size 1. Note, the default value is different ! from the same argument for a non-arbitrarily distributed grid. ! \item[{[coordDimMap]}] ! 2D list of size dimCount x dimCount. This array describes the ! map of each coordinate array's dimensions onto the grids ! dimensions. {\tt coordDimMap(i,j)} is the grid dimension of the jth dimension ! of the i'th coordinate array. If not specified, the default value of ! {\tt coordDimMap(i,1)} is /ESMF\_DIM\_ARB/ if the ith dimension of the grid is ! arbitrarily distributed, or {\tt i} if the ith dimension is not distributed. ! Note that if j is bigger than {\tt coordDimCount(i)} then it's ignored. ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP integer :: localrc ! local error status type(ESMF_Grid) :: grid integer :: nameLen type(ESMF_InterfaceInt) :: minIndexArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: maxIndexArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: localArbIndexArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: distDimArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: coordDimCountArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: coordDimMapArg ! Language Interface Helper Var integer :: intDestroyDistgrid,intDestroyDELayout integer :: dimCount, distDimCount, undistDimCount, dimCount1 integer, pointer :: local1DIndices(:), localArbIndex(:,:), distSize(:) integer, pointer :: undistMinIndex(:), undistMaxIndex(:) integer, pointer :: minIndexPTile(:,:), maxIndexPTile(:,:) integer :: tileCount, localCounts integer, pointer :: minIndexLocal(:), maxIndexLocal(:) logical, pointer :: isDistDim(:) integer :: i, j, k, arbDim, deCount integer, allocatable :: distDimLocal(:) integer, allocatable :: collocation(:) logical :: arbSeqIndexFlag type(ESMF_DELayout) :: delayout ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_DistGridGetInit, distgrid, rc) ! Translate F90 arguments to C++ friendly form !! name nameLen=0 if (present(name)) then nameLen=len_trim(name) endif !! find out grid dimension dimCount = size(indexArray,2) !! find out undistDimCount and distDimCount call ESMF_DistGridGet(distgrid, dimCount=dimCount1, tileCount=tileCount, & rc=localrc) !! dimCount1 should be equal or less than dimCount if (dimCount1 > dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- distgrid dimension has to be less or equal to dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif if (tileCount /= 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- distgrid tile count has to be 1", & ESMF_CONTEXT, rcToReturn=rc) return endif distDimCount = dimCount - dimCount1 + 1 undistDimCount = dimCount - distDimCount !! distDim is a 1D array of size distDimCount. The values are the !! Grid dimensions that are arbitrarily distributed. if (present(distDim)) then if (size(distDim) /= distDimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- dimension of distDim has to be the same as the arbitrary distributed dim", & ESMF_CONTEXT, rcToReturn=rc) return endif endif !! fill minIndexLocal allocate(minIndexLocal(dimCount), maxIndexLocal(dimCount)) do i=1,dimCount minIndexLocal(i) = indexArray(1,i) maxIndexLocal(i) = indexArray(2,i) enddo !! set distSize allocate(distSize(distDimCount)) allocate(isDistDim(dimCount)) allocate(distDimLocal(distDimCount)) isDistDim(:) = .false. if (present(distDim)) then do i=1,distDimCount distSize(i)=maxIndexLocal(distDim(i))-minIndexLocal(distDim(i))+1 isDistDim(distDim(i))=.true. distDimLocal(i)=distDim(i) enddo else do i=1,distDimCount distSize(i)=maxIndexLocal(i)-minIndexLocal(i)+1 isDistDim(i)=.true. distDimLocal(i)=i enddo endif !! Arbitrary grid indices minIndexArg = ESMF_InterfaceIntCreate(minIndexLocal, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexArg = ESMF_InterfaceIntCreate(maxIndexLocal, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! distDim distDimArg = ESMF_InterfaceIntCreate(distDimLocal, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_DistGridGet(distgrid,localDe=0, elementCount=localCounts, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! reconstruct the localArbIndex from local1DIndices allocate(local1DIndices(localCounts)) call ESMF_DistGridGet(distgrid,localDe=0, seqIndexList=local1DIndices, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! find out the dimension allocate(localArbIndex(localCounts,distDimCount)) !! I hope this is correct.... !! This is kind of redundant. Because if we create the grid using shapetile API, the local1DIndices !! were calculated by the input localArbIndex and we should not need to re-calculate the localArbIndex. !! We only need this when user creates an arbitrary grid from a distgrid. The question is (1) do we need !! to store the localArbIndex in the Grid data structure or not? (2) shall we allow user to pass localArbIndex !! to the ESMF_CreateGridFromDistGrid()? If we do, we have to check if the distgrid indices matches with !! the input localArbIndex do i=1,localCounts !! make it 0-based first before calculations local1DIndices(i)=local1DIndices(i)-1 if (distDimCount >= 2) then do j=distDimCount,2 !! add 1 to make the result 1-based localArbIndex(i,j) = mod(local1DIndices(i),distSize(j))+1 local1DIndices(i)=local1DIndices(i)/distSize(j) enddo endif localArbIndex(i,1) = local1DIndices(i)+1 enddo localArbIndexArg = ESMF_InterfaceIntCreate(farray2D=localArbIndex, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Check the non-arbitrary dimensions in DistGrid and make sure they are !! consistent with the minIndex and maxIndex !! First, find out which dimension in DistGrid is arbitrary arbDim = -1 call ESMF_DistGridGet(distgrid, delayout=delayout, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_DELayoutGet(delayout, localDeCount=deCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (deCount > 0) then allocate(collocation(dimCount1)) ! dimCount call ESMF_DistGridGet(distgrid, & collocation=collocation, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return do i=1,dimCount1 call ESMF_DistGridGet(distgrid, localDe=0, collocation=collocation(i), & arbSeqIndexFlag=arbSeqIndexFlag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (arbSeqIndexFlag) arbDim = i enddo deallocate(collocation) endif if (arbDim == -1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- distgrid should contain arbitrary sequence indices", & ESMF_CONTEXT, rcToReturn=rc) return endif if (undistDimCount /= 0) then allocate(minIndexPTile(dimCount1,1)) allocate(maxIndexPTile(dimCount1,1)) call ESMF_DistGridGet(distgrid, minIndexPTile=minIndexPTile, & maxIndexPTile=maxIndexPTile, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return allocate(undistMinIndex(undistDimCount)) allocate(undistMaxIndex(undistDimCount)) k = 1 do j=1,dimCount if (.not. isDistDim(j)) then undistMinIndex(k) = minIndexLocal(j) undistMaxIndex(k) = maxIndexLocal(j) k = k+1 endif enddo k = 1 do i=1,dimCount1 if (arbDim /= i) then if ((undistMinIndex(k) /= minIndexPTile(i,1)) .or. & (undistMaxIndex(k) /= maxIndexPTile(i,1))) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- Grid min/max index does not match with DistGrid min/max index", & ESMF_CONTEXT, rcToReturn=rc) return endif k = k + 1 endif enddo endif !! Description of array factorization coordDimCountArg = ESMF_InterfaceIntCreate(coordDimCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return coordDimMapArg = ESMF_InterfaceIntCreate(farray2D=coordDimMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! DEfault to don't destroy, subroutine used to set actual values in other creates intDestroyDistgrid=0 intDestroyDELayout=0 ! Initialize this grid object as invalid grid%this = ESMF_NULL_POINTER ! Call C++ Subroutine to do the create call c_ESMC_gridcreatedistgridarb(grid%this, nameLen, name, & coordTypeKind, distgrid, distDimArg, arbDim, & coordSys, coordDimCountArg, coordDimMapArg, & minIndexArg, maxIndexArg, localArbIndexArg, localCounts, & intDestroyDistGrid, intDestroyDELayout, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate helper variables deallocate(minIndexLocal) deallocate(maxIndexLocal) deallocate(distSize) deallocate(isDistDim) deallocate(distDimLocal) deallocate(local1DIndices) deallocate(localArbIndex) if (undistDimCount /= 0) then deallocate(minIndexPTile) deallocate(maxIndexPTile) deallocate(undistMinIndex) deallocate(undistMaxIndex) endif call ESMF_InterfaceIntDestroy(distDimArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(minIndexArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(maxIndexArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(localArbIndexArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(coordDimCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(coordDimMapArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set return value ESMF_GridCreateFrmDistGridArb = grid ! Set init status ESMF_INIT_SET_CREATED(ESMF_GridCreateFrmDistGridArb) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateFrmDistGridArb !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreateFrmFile" !BOP ! !IROUTINE: ESMF_GridCreate - Create a Grid from a file ! !INTERFACE: ! Private name; call using ESMF_GridCreate() function ESMF_GridCreateFrmFile(fileName, keywordEnforcer, & convention, purpose, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridCreateFrmFile ! ! !ARGUMENTS: character (len=*), intent(in) :: fileName type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below character (len=*), intent(in), optional :: convention character (len=*), intent(in), optional :: purpose integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! Create an {\tt ESMF\_Grid} object from specifications in a file ! containing an ESMF GridSpec Attribute package in XML format. Currently limited ! to creating a 2D regularly distributed rectilinear Grid; in the future more ! dimensions, grid types and distributions will be supported. ! See Section~\ref{example:GridCrFromFile} for an example, as well as the ! accompanying file ! ESMF\_DIR/src/Infrastructure/Grid/etc/esmf\_grid\_shape\_tile.xml. ! ! Requires the third party Xerces C++ XML Parser library to be installed. ! For more details, see the "ESMF Users Guide", ! "Building and Installing the ESMF, Third Party Libraries, Xerces" and ! the website http://xerces.apache.org/xerces-c. ! ! The arguments are: ! \begin{description} ! \item[fileName] ! The name of the XML file to be read, containing ESMF GridSpec Attributes. ! \item [{[convention]}] ! The convention of a grid Attribute package. [CURRENTLY NOT IMPLEMENTED] ! \item [{[purpose]}] ! The purpose of a grid Attribute package. [CURRENTLY NOT IMPLEMENTED] ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! Equals {\tt ESMF\_RC\_LIB\_NOT\_PRESENT} if Xerces is not present. ! \end{description} ! !EOP type(ESMF_Grid) :: grid integer, dimension(1) :: lens character(ESMF_MAXSTR) :: attrName, attrValue, attPackInstanceName integer :: maxIndex(2), regDecomp(2) ! TODO: allow more dimensions integer :: fileNameLen, localrc, count logical :: xercesPresent ! Initialize return code; assume failure until success is certain if (present(rc)) rc = ESMF_RC_NOT_IMPL localrc = ESMF_RC_NOT_IMPL !DUMMY TEST TO QUIET DOWN COMPILER WARNINGS !TODO: Remove the following test when dummy argument actually used if (present(convention)) then if (convention==convention) continue; endif !DUMMY TEST TO QUIET DOWN COMPILER WARNINGS !TODO: Remove the following test when dummy argument actually used if (present(purpose)) then if (purpose==purpose) continue; endif ! get length of given fileName for C++ validation fileNameLen = len_trim(fileName) ! assume Xerces XML C++ API library present until proven otherwise xercesPresent = .true. ! Initialize this grid object as invalid grid%this = ESMF_NULL_POINTER grid = ESMF_GridEmptyCreate(rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) then call ESMF_GridDestroy(grid) return endif ! Read the attribute file; place attributes onto grid base ! TODO: use convention, purpose ! use C call rather than F90, to circumvent mutually dependency ! between Grid and Attribute ! Do not pass a schema file; forces use of ESMF standard GridSpec schema call c_ESMC_AttributeRead(grid, fileNameLen, fileName, 0, "", localrc) if (localrc==ESMF_RC_LIB_NOT_PRESENT) xercesPresent = .false. if (localrc /= ESMF_SUCCESS .and. xercesPresent) localrc = ESMF_FAILURE if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) then call ESMF_GridDestroy(grid) return endif ! Get the GridSpec "NX" and "NY" Attributes set from file ! (required, for maxIndex in GriCreate()) ! use C calls rather than F90, to circumvent mutually dependency ! between Grid and Attribute attPackInstancename = "" ! get the 1st AttPack of type (conv, purp) on 'grid' attrName = "NX" lens(1) = len(attrName) count = 1 call c_ESMC_AttPackGetCharList(grid, attrName, ESMF_TYPEKIND_CHARACTER, count, lens, & attrValue, 'GridSpec', 'General', 'grid', & attPackInstanceName, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) then call ESMF_GridDestroy(grid) return endif ! convert from character to integer read(attrValue, *, iostat=localrc) maxIndex(1) if (localrc/=0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_VAL_WRONG, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc) call ESMF_GridDestroy(grid) return end if attrName = "NY" lens(1) = len(attrName) call c_ESMC_AttPackGetCharList(grid, 'NY', ESMF_TYPEKIND_CHARACTER, count, lens, & attrValue, 'GridSpec', 'General', 'grid', & attPackInstanceName, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) then call ESMF_GridDestroy(grid) return endif ! convert from character to integer read(attrValue, *, iostat=localrc) maxIndex(2) if (localrc/=0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_VAL_WRONG, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc) call ESMF_GridDestroy(grid) return end if ! Get the ESMF "RegDecompX" and "RegDecompY" Attributes set from file ! TODO: make optional ! use C calls rather than F90, to circumvent mutually dependency ! between Grid and Attribute attrName = 'RegDecompX' lens(1) = len(attrName) call c_ESMC_AttributeGetCharList(grid, attrName, ESMF_TYPEKIND_CHARACTER, & count, lens, attrValue, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) then call ESMF_GridDestroy(grid) return endif ! convert from character to integer read(attrValue, *, iostat=localrc) regDecomp(1) if (localrc/=0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_VAL_WRONG, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc) call ESMF_GridDestroy(grid) return end if attrName = 'RegDecompY' lens(1) = len(attrName) call c_ESMC_AttributeGetCharList(grid, attrName, ESMF_TYPEKIND_CHARACTER, & count, lens, attrValue, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) then call ESMF_GridDestroy(grid) return endif ! convert from character to integer read(attrValue, *, iostat=localrc) regDecomp(2) if (localrc/=0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_VAL_WRONG, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc) call ESMF_GridDestroy(grid) return end if ! Create single tile grid with global indices, and with specified ! regular distribution ! TODO: when RegDecompX,Y optional and not specified, don't pass regDecomp call ESMF_GridSetCommitShapeTile(grid, maxIndex=maxIndex, & regDecomp=regDecomp, & indexflag=ESMF_INDEX_GLOBAL, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) then call ESMF_GridDestroy(grid) return endif ! TODO: Add coordinates ! call ESMF_GridAddCoord(grid, staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) ! Set return value ESMF_GridCreateFrmFile = grid ! Set init status ESMF_INIT_SET_CREATED(ESMF_GridCreateFrmFile) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateFrmFile !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreateFrmScripDistGrd" !BOP ! !IROUTINE: ESMF_GridCreate - Create a Grid from a SCRIP grid file and a DistGrid ! !INTERFACE: ! Private name; call using ESMF_GridCreate() function ESMF_GridCreateFrmScripDistGrd(distgrid, filename, & keywordEnforcer, rc) ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridCreateFrmScripDistGrd ! ! !ARGUMENTS: type(ESMF_DistGrid), intent(in) :: distgrid character(len=*), intent(in) :: filename type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! !DESCRIPTION: ! This function creates a {\tt ESMF\_Grid} object using the grid definition from ! a SCRIP grid file. The grid distribution is defined by a DistGrid object. The ! distrgrid has to match the grid defined in the file. This means the distgrid ! should consist of one 2D tile with the same size in each dimension as the grid in the file. ! The grid defined in the file has to be a 2D logically rectangular grid (i.e. {\tt grid\_rank} ! in the file needs to be 2). ! ! This call is {\em collective} across the current VM. ! ! The arguments are: ! \begin{description} ! \item[distgrid] ! {\tt ESMF\_DistGrid} object that describes how the array is decomposed and ! distributed over DEs. ! \item[{[filename]}] ! The SCRIP Grid filename. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP #ifdef ESMF_NETCDF integer :: ncid integer :: ncStatus integer :: totalpoints,totaldims integer, pointer :: dims(:) integer :: DimId, VarId real(ESMF_KIND_R8), allocatable:: coordX(:),coordY(:) integer, allocatable:: imask(:), mask2D(:,:) type(ESMF_Grid) :: grid type(ESMF_Array) :: array real(ESMF_KIND_R8), allocatable :: coord2D(:,:) type(ESMF_VM) :: vm integer :: numDim, minInd(2,1), maxInd(2,1), buf(1) integer :: localrc integer :: PetNo, PetCnt ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! get global vm information ! call ESMF_VMGetGlobal(vm, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! set up local pet info call ESMF_VMGet(vm, localPet=PetNo, petCount=PetCnt, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! get dimension from distgrid call ESMF_DistGridGet(distgrid, dimCount=numDim, minIndexPTile=minInd,& maxIndexPTile=maxInd, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (numDim /=2) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_RANK, & msg="- The distgrid dimCount has to be 2", ESMF_CONTEXT, rcToReturn=rc) return endif if (minInd(1,1) /= 1 .and. minInd(2,1) /=1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_RANK, & msg="- The minIndex of distgrip has to be 1", ESMF_CONTEXT, rcToReturn=rc) return endif if (PetNo == 0) then call ESMF_ScripInq(filename, grid_dims=dims, grid_rank=totaldims, & grid_size=totalpoints, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! check if the grid_dim matches with the distgrid dimension if (dims(1) /= maxInd(1,1) .and. dims(2) /= maxInd(2,1) ) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- The grid_dims does not match with distgrid dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif ! if grid_rank is not equal to 2, return error ! Does SCRIP allow 3D datasets? What will be the format?? if (totaldims /= 2) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_RANK,msg="- The grip has to be 2D", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Get the cell_center lat and lan, if in radians, convert to degree allocate(coordX(totalpoints), coordY(totalpoints)) allocate(imask(totalpoints), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating imask", & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ScripGetVar(filename, grid_center_lon=coordX, & grid_center_lat=coordY, grid_imask=imask, & convertToDeg=.TRUE., rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Create Grid based on the input distgrid grid = ESMF_GridCreate(distgrid=distgrid, & gridEdgeLWidth=(/0,0/), gridEdgeUWidth=(/0,0/), & indexflag=ESMF_INDEX_GLOBAL, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set coordinate tables ! Longitude call ESMF_GridAddCoord(grid, staggerloc=ESMF_STAGGERLOC_CENTER, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridGetCoord(grid, staggerloc=ESMF_STAGGERLOC_CENTER, coordDim=1, & array = array, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (PetNo == 0) then allocate(coord2D(dims(1),dims(2))) coord2D = RESHAPE(coordX,(/dims(1), dims(2)/)) endif call ESMF_ArrayScatter(array, coord2D, rootPet=0, rc=localrc) !print *, "Finish ArrayScatter 1st dim coord" if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Latitude call ESMF_GridGetCoord(grid, staggerloc=ESMF_STAGGERLOC_CENTER, coordDim=2, & array = array, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (PetNo == 0) then coord2D = RESHAPE(coordY,(/dims(1), dims(2)/)) endif call ESMF_ArrayScatter(array, coord2D, rootPet=0, rc=localrc) !print *, "Finish ArrayScatter 1st dim coord" if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (PetNo == 0) deallocate(coord2D, coordX, coordY) ! Mask call ESMF_GridAddItem(grid, staggerloc=ESMF_STAGGERLOC_CENTER, & itemflag=ESMF_GRIDITEM_MASK, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridGetItem(grid, staggerloc=ESMF_STAGGERLOC_CENTER, & itemflag=ESMF_GRIDITEM_MASK, array = array, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (PetNo == 0) then allocate(mask2D(dims(1),dims(2))) mask2D = RESHAPE(imask,(/dims(1), dims(2)/)) endif call ESMF_ArrayScatter(array, mask2D, rootPet=0, rc=localrc) !print *, "Finish ArrayScatter 1st dim coord" if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (PetNo == 0) deallocate(imask, mask2D) ESMF_GridCreateFrmScripDistGrd = grid if (present(rc)) rc=ESMF_SUCCESS return #else if (present(rc)) rc = ESMF_RC_LIB_NOT_PRESENT #endif return end function ESMF_GridCreateFrmScripDistGrd ! Internal subroutine to convert the 2D corner coordinate arrays which contain all the corners ! surrounding each center point into a 1D Array without repeats. ! This assumes that all the corners are in the same order around each center subroutine convert_corner_arrays_to_1D(isSphere,dim1,dim2,cornerX2D,cornerY2D,cornerX,cornerY, rc) logical :: isSphere integer :: dim1,dim2 real(ESMF_KIND_R8) :: cornerX2D(:,:),cornerY2D(:,:) real(ESMF_KIND_R8) :: cornerX(:),cornerY(:) integer :: rc integer :: i,j real(ESMF_KIND_R8) :: tol=0.000000000001 integer :: topCorner integer :: topRightCorner integer :: BtmRightCorner integer :: btmCorner logical :: matches integer :: count,inPos,outPos ! Figure out which corner indice is the top row of corners ! It won't match any of the neighbors corners TopCorner=-1 do i=1,4 ! See if it matches nbr to the right matches=.false. do j=1,4 if ((abs(cornerX2D(i,1)-cornerX2D(j,2))dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep1 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep2)) then if ((size(coordDep2) < 1) .or. (size(coordDep2)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep2 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep3)) then if ((size(coordDep3) < 1) .or. (size(coordDep3)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep3 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(minIndex)) then if (size(minIndex) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- minIndex size must equal grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(petMap)) then if (dimCount > 2) then if ((size(petMap,1) /= size(countsPerDEDim1)) .or. & (size(petMap,2) /= size(countsPerDEDim2)) .or. & (size(petMap,3) /= size(countsPerDEDim3))) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif else if ((size(petMap,1) /= size(countsPerDEDim1)) .or. & (size(petMap,2) /= size(countsPerDEDim2)) .or. & (size(petMap,3) /= 1)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif ! Check DimCount of gridWidths and Aligns if (present(gridEdgeLWidth)) then if (size(gridEdgeLWidth) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeLWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (size(gridEdgeUWidth) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeUWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridAlign)) then if (size(gridAlign) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridAlign must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim1)) then if (size(connflagDim1) == 1) then if (connflagDim1(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim1) == 2) then if (connflagDim1(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim1(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim2)) then if (size(connflagDim2) == 1) then if (connflagDim2(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim2) == 2) then if (connflagDim2(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim2(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim3)) then if (size(connflagDim3) == 1) then if (connflagDim3(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim3) == 2) then if (connflagDim3(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim3(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! check for gridMemLBound issues if (present(gridMemLBound)) then if (.not. present(indexflag)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using gridMemLBound must specify indexflag=ESMF_INDEX_USER ", & ESMF_CONTEXT, rcToReturn=rc) return else if (.not. (indexflag == ESMF_INDEX_USER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using gridMemLBound must specify indexflag=ESMF_INDEX_USER ", & ESMF_CONTEXT, rcToReturn=rc) return endif else if (present(indexflag)) then if (indexflag == ESMF_INDEX_USER) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using indexflag=ESMF_INDEX_USER must provide gridMemLBound ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif ! Check for non-valid connection types here !TODO: Consider making some of these a separate local subroutine (particularly if you're going to ! have 3 of these ShapeCreate subroutines with only minor changes ! Copy vales for countsPerDEDim -------------------------------------------- allocate(countsPerDEDim1Local(size(countsPerDEDim1)), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating countsPerDEDim1Local", & ESMF_CONTEXT, rcToReturn=rc)) return countsPerDEDim1Local=countsPerDEDim1 allocate(countsPerDEDim2Local(size(countsPerDEDim2)), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating countsPerDEDim2Local", & ESMF_CONTEXT, rcToReturn=rc)) return countsPerDEDim2Local=countsPerDEDim2 if (dimCount > 2) then allocate(countsPerDEDim3Local(size(countsPerDEDim3)), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating countsPerDEDim3Local", & ESMF_CONTEXT, rcToReturn=rc)) return countsPerDEDim3Local=countsPerDEDim3 endif ! Set Defaults ------------------------------------------------------------- ! Set default for minIndex allocate(minIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(minIndex)) then minIndexLocal(:)=minIndex(:) else do i=1,dimCount minIndexLocal(i)=1 enddo endif ! Set Default for connections (although they don't work yet in distgrid/array, so they aren't really used anywhere yet.) if (present(connflagDim1)) then if (size(connflagDim1) == 1) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim1) >= 2) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(2) endif else connflagDim1Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim1Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim2)) then if (size(connflagDim2) == 1) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim2) >= 2) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(2) endif else connflagDim2Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim2Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim3)) then if (size(connflagDim3) == 1) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim3) >= 2) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(2) endif else connflagDim3Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim3Local(2)=ESMF_GRIDCONN_NONE endif ! check for not implemented functionality if (connflagDim1Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim1Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim2Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim2Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim3Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim3Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Make alterations to size due to GridEdgeWidths ---------------------------- allocate(gridEdgeLWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeLWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridEdgeUWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeUWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridAlignLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridAlignLocal", & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridLUADefault(dimCount, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridEdgeLWidthLocal, gridEdgeUWidthLocal, gridAlignLocal, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return #if 0 ! Modify lower bound do i=1,dimCount minIndexLocal(i)=minIndexLocal(i)-gridEdgeLWidthLocal(i) enddo ! Modify lower size countsPerDEDim1Local(1)=countsPerDEDim1Local(1)+gridEdgeLWidthLocal(1) countsPerDEDim2Local(1)=countsPerDEDim2Local(1)+gridEdgeLWidthLocal(2) if (dimCount > 2) then countsPerDEDim3Local(1)=countsPerDEDim3Local(1)+gridEdgeLWidthLocal(3) endif ! Modify upper size top=size(countsPerDEDim1Local) countsPerDEDim1Local(top)=countsPerDEDim1Local(top)+gridEdgeUWidthLocal(1) top=size(countsPerDEDim2Local) countsPerDEDim2Local(top)=countsPerDEDim2Local(top)+gridEdgeUWidthLocal(2) if (dimCount > 2) then top=size(countsPerDEDim3Local) countsPerDEDim3Local(top)=countsPerDEDim3Local(top)+gridEdgeUWidthLocal(3) endif #endif ! Calc minIndex,maxIndex,distgridToGridMap for DistGrid ----------------------------------- ! Set default for maxIndex allocate(maxIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexLocal(1)=sum(countsPerDEDim1Local)+minIndexLocal(1)-1 maxIndexLocal(2)=sum(countsPerDEDim2Local)+minIndexLocal(2)-1 if (dimCount > 2) then maxIndexLocal(3)=sum(countsPerDEDim3Local)+minIndexLocal(3)-1 endif allocate(distgridToGridMap(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distgridToGridMap", & ESMF_CONTEXT, rcToReturn=rc)) return do i=1,dimCount distgridToGridMap(i)=i enddo ! Setup deBlockList for DistGrid ------------------------------------------------ ! count de blocks deCount=1 deCount=deCount*size(countsPerDEDim1Local) deCount=deCount*size(countsPerDEDim2Local) if (dimCount > 2) then deCount=deCount*size(countsPerDEDim3Local) endif ! Calc the max size of a DEDim maxSizeDEDim=1 if (size(countsPerDEDim1Local) > maxSizeDEDim) then maxSizeDEDim=size(countsPerDEDim1Local) endif if (size(countsPerDEDim2Local) > maxSizeDEDim) then maxSizeDEDim=size(countsPerDEDim2Local) endif if (dimCount > 2) then if (size(countsPerDEDim3Local) > maxSizeDEDim) then maxSizeDEDim=size(countsPerDEDim3Local) endif endif ! generate deblocklist allocate(maxPerDEDim(dimCount,maxSizeDEDim), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxPerDEDim", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(minPerDEDim(dimCount,maxSizeDEDim), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minPerDEDim", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(deDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxPerDEDim", & ESMF_CONTEXT, rcToReturn=rc)) return ! Calc the maximum end of each DE in a Dim, and the size of each DEDim d=1 deDimCount(d)=size(countsPerDEDim1Local) minPerDeDim(d,1)=minIndexLocal(d) maxPerDeDim(d,1)=minIndexLocal(d)+countsPerDEDim1Local(1)-1 do i=2,deDimCount(d) minPerDEDim(d,i)=maxPerDEDim(d,i-1)+1 maxPerDEDim(d,i)=minPerDEDim(d,i)+countsPerDEDim1Local(i)-1 enddo d=2 deDimCount(d)=size(countsPerDEDim2Local) minPerDeDim(d,1)=minIndexLocal(d) maxPerDeDim(d,1)=minIndexLocal(d)+countsPerDEDim2Local(1)-1 do i=2,deDimCount(d) minPerDEDim(d,i)=maxPerDEDim(d,i-1)+1 maxPerDEDim(d,i)=minPerDEDim(d,i)+countsPerDEDim2Local(i)-1 enddo if (dimCount > 2) then d=3 deDimCount(d)=size(countsPerDEDim3Local) minPerDeDim(d,1)=minIndexLocal(d) maxPerDeDim(d,1)=minIndexLocal(d)+countsPerDEDim3Local(1)-1 do i=2,deDimCount(d) minPerDEDim(d,i)=maxPerDEDim(d,i-1)+1 maxPerDEDim(d,i)=minPerDEDim(d,i)+countsPerDEDim3Local(i)-1 enddo endif ! allocate deblocklist allocate(deBlockList(dimCount,2,deCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating deBlockList", & ESMF_CONTEXT, rcToReturn=rc)) return ! Fill in DeBlockList if (dimCount == 2) then k=1 do i2=1,deDimCount(2) do i1=1,deDimCount(1) deBlockList(1,1,k)=minPerDEDim(1,i1) deBlockList(1,2,k)=maxPerDEDim(1,i1) deBlockList(2,1,k)=minPerDEDim(2,i2) deBlockList(2,2,k)=maxPerDEDim(2,i2) k=k+1 enddo enddo else if (dimCount == 3) then k=1 do i3=1,deDimCount(3) do i2=1,deDimCount(2) do i1=1,deDimCount(1) deBlockList(1,1,k)=minPerDEDim(1,i1) deBlockList(1,2,k)=maxPerDEDim(1,i1) deBlockList(2,1,k)=minPerDEDim(2,i2) deBlockList(2,2,k)=maxPerDEDim(2,i2) deBlockList(3,1,k)=minPerDEDim(3,i3) deBlockList(3,2,k)=maxPerDEDim(3,i3) k=k+1 enddo enddo enddo endif ! do i=1,deCount ! write(*,*) i,"min=",deBlockList(:,1,i)," max=",deBlockList(:,2,i) ! enddo ! Setup Connections between tile sides ---------------------------------------- ! CONNECTIONS DON'T WORK YET SO NOT IMPLEMENTED ! Process PetMap -------------------------------------------------------------- if (present(petMap)) then !! Allocate petList allocate(petList(deCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating petList", & ESMF_CONTEXT, rcToReturn=rc)) return !! copy petMap to petList if (dimCount > 2) then k=1 do i3=1,size(countsPerDEDim3Local) do i2=1,size(countsPerDEDim2Local) do i1=1,size(countsPerDEDim1Local) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo else k=1 do i3=1,1 do i2=1,size(countsPerDEDim2Local) do i1=1,size(countsPerDEDim1Local) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo endif !! create delayout from the petList delayout=ESMF_DELayoutCreate(petList=petList,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Get rid of list deallocate(petList) else !! create a default delayout delayout=ESMF_DELayoutCreate(deCount=deCount,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Create DistGrid -------------------------------------------------------------- distgrid=ESMF_DistGridCreate(minIndex=minIndexLocal, maxIndex=maxIndexLocal, & deBlockList=deBlockList, delayout=delayout, indexflag=indexflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Convert coordDeps to coordDimCount and coordDimMap ------------------------------- allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(coordDep1)) then coordDimCount(1)=size(coordDep1) coordDimMap(1,:)=0 do i=1,size(coordDep1) coordDimMap(1,i)=coordDep1(i) enddo else coordDimCount(1)=dimCount do i=1,dimCount coordDimMap(1,i)=i enddo endif if (present(coordDep2)) then coordDimCount(2)=size(coordDep2) coordDimMap(2,:)=0 do i=1,size(coordDep2) coordDimMap(2,i)=coordDep2(i) enddo else coordDimCount(2)=dimCount do i=1,dimCount coordDimMap(2,i)=i enddo endif if (dimCount > 2) then if (present(coordDep3)) then coordDimCount(3)=size(coordDep3) coordDimMap(3,:)=0 do i=1,size(coordDep3) coordDimMap(3,i)=coordDep3(i) enddo else coordDimCount(3)=dimCount do i=1,dimCount coordDimMap(3,i)=i enddo endif endif ! Create Grid from specification ----------------------------------------------- ESMF_GridCreateShapeTileIrreg=ESMF_GridCreateFrmDistGrid(distgrid, & distgridToGridMap=distgridToGridMap, coordTypeKind=coordTypeKind, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & gridEdgeLWidth=gridEdgeLWidthLocal, & gridEdgeUWidth=gridEdgeUWidthLocal, & gridAlign=gridAlignLocal, & gridMemLBound=gridMemLBound, & indexflag=indexflag, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid call ESMF_GridSetDestroyDistgrid( ESMF_GridCreateShapeTileIrreg,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout( ESMF_GridCreateShapeTileIrreg,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(coordDimCount) deallocate(coordDimMap) deallocate(minIndexLocal) deallocate(maxIndexLocal) deallocate(distgridToGridMap) deallocate(maxPerDEDim) deallocate(minPerDEDim) deallocate(deDimCount) deallocate(deBlockList) deallocate(gridEdgeLWidthLocal) deallocate(gridEdgeUWidthLocal) deallocate(gridAlignLocal) deallocate(countsPerDEDim1Local) deallocate(countsPerDEDim2Local) if (dimCount > 2) then deallocate(countsPerDEDim3Local) endif ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateShapeTileIrreg !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreateShapeTileReg" !BOPI ! !IROUTINE: ESMF_GridCreateShapeTile - Create a Grid with a regular distribution ! !INTERFACE: ! Private name; call using ESMF_GridCreateShapeTile() function ESMF_GridCreateShapeTileReg(coordTypeKind, & regDecomp, decompFlag, minIndex, maxIndex, & keywordEnforcer, connflagDim1, connflagDim2, connflagDim3, & poleStaggerLoc1, poleStaggerLoc2, poleStaggerLoc3, & bipolePos1, bipolePos2, bipolePos3, & coordDep1, coordDep2, coordDep3, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridMemLBound, indexflag, petMap, name, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridCreateShapeTileReg ! ! !ARGUMENTS: type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: regDecomp(:) type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) integer, intent(in), optional :: minIndex(:) integer, intent(in) :: maxIndex(:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim1(:) !N. IMP. type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim2(:) !N. IMP. type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim3(:) !N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc1(2)!N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc2(2)!N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc3(2)!N. IMP. integer, intent(in), optional :: bipolePos1(2)!N. IMP. integer, intent(in), optional :: bipolePos2(2)!N. IMP. integer, intent(in), optional :: bipolePos3(2)!N. IMP. integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(in), optional :: gridEdgeLWidth(:) integer, intent(in), optional :: gridEdgeUWidth(:) integer, intent(in), optional :: gridAlign(:) integer, intent(in), optional :: gridMemLBound(:) type(ESMF_Index_Flag), intent(in), optional :: indexflag integer, intent(in), optional :: petMap(:,:,:) character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This method creates a single tile, regularly distributed grid ! (see Figure \ref{fig:GridDecomps}). ! To specify the distribution, the user passes in an array ! ({\tt regDecomp}) specifying the number of DEs to divide each ! dimension into. The array {\tt decompFlag} indicates how the division into DEs is to ! occur. The default is to divide the range as evenly as possible. ! ! The arguments are: ! \begin{description} ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[regDecomp]}] ! List that has the same number of elements as {\tt maxIndex}. ! Each entry is the number of decounts for that dimension. ! If not specified, the default decomposition will be petCountx1x1..x1. ! \item[{[decompflag]}] ! List of decomposition flags indicating how each dimension of the ! tile is to be divided between the DEs. The default setting ! is {\tt ESMF\_DECOMP\_BALANCED} in all dimensions. Please see ! Section~\ref{const:decompflag} for a full description of the ! possible options. ! \item[{[minIndex]}] ! The bottom extent of the grid array. If not given then the value defaults ! to /1,1,1,.../. ! \item[{maxIndex}] ! The upper extent of the grid array. ! \item[{[connflagDim1]}] ! Fortran array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[connflagDim2]}] ! Fortran array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[connflagDim3]}] ! Fortran array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc1]}] ! Two element array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc2]}] ! Two element array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc3]}] ! Two element array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos1]}] ! Two element array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos2]}] ! Two element array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos3]}] ! Two element array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[coordDep1]}] ! This array specifies the dependence of the first ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the first ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep2]}] ! This array specifies the dependence of the second ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the second ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep3]}] ! This array specifies the dependence of the third ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the third ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[gridEdgeLWidth]}] ! The padding around the lower edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. ! \item[{[gridEdgeUWidth]}] ! The padding around the upper edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. ! \item[{[gridAlign]}] ! Specification of how the stagger locations should align with the cell ! index space (can be overridden by the individual staggerAligns). If ! the {\tt gridEdgeWidths} are not specified than this parameter ! implies the EdgeWidths. ! \item[{[gridMemLBound]}] ! Specifies the lower index range of the memory of every DE in this Grid. ! Only used when indexflag is {\tt ESMF\_INDEX\_USER}. May be overridden ! by staggerMemLBound. ! \item[{[indexflag]}] ! Indicates the indexing scheme to be used in the new Grid. Please see ! Section~\ref{const:indexflag} for the list of options. If not present, ! defaults to ESMF\_INDEX\_DELOCAL. ! \item[{[petMap]}] ! Sets the mapping of pets to the created DEs. This 3D ! should be of size regDecomp(1) x regDecomp(2) x regDecomp(3) ! If the Grid is 2D, then the last dimension is of size 1. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI type(ESMF_DistGrid) :: distgrid type(ESMF_DELayout) :: delayout type(ESMF_VM) :: vm integer, pointer :: petList(:) integer, pointer :: coordDimCount(:) integer, pointer :: coordDimMap(:,:) integer :: localrc integer :: dimCount,i integer, pointer :: regDecompLocal(:) type(ESMF_Decomp_Flag), pointer :: decompflagLocal(:) integer, pointer :: distgridToGridMap(:) integer, pointer :: minIndexLocal(:), maxIndexLocal(:) integer, pointer :: gridEdgeLWidthLocal(:) integer, pointer :: gridEdgeUWidthLocal(:) integer, pointer :: gridAlignLocal(:) integer :: deCount integer :: i1,i2,i3,k type(ESMF_GridConn_Flag) :: connflagDim1Local(2) type(ESMF_GridConn_Flag) :: connflagDim2Local(2) type(ESMF_GridConn_Flag) :: connflagDim3Local(2) ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL !DUMMY TEST TO QUIET DOWN COMPILER WARNINGS !TODO: Remove the following test when dummy argument actually used if (present(polestaggerloc1)) then if (polestaggerloc1(1)==polestaggerloc1(1)) continue; endif !DUMMY TEST TO QUIET DOWN COMPILER WARNINGS !TODO: Remove the following test when dummy argument actually used if (present(polestaggerloc2)) then if (polestaggerloc2(1)==polestaggerloc2(1)) continue; endif !DUMMY TEST TO QUIET DOWN COMPILER WARNINGS !TODO: Remove the following test when dummy argument actually used if (present(bipolepos1)) then if (bipolepos1(1)==bipolepos1(1)) continue; endif !DUMMY TEST TO QUIET DOWN COMPILER WARNINGS !TODO: Remove the following test when dummy argument actually used if (present(bipolepos2)) then if (bipolepos2(1)==bipolepos2(1)) continue; endif ! Compute the Grid DimCount and Derivatives --------------------------------------------------- ! dimCount dimCount=size(maxIndex) if ((dimCount < 2) .or. (dimCount > 3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- maxIndex size and thus Grid dimCount must be either 2 or 3 when using create shape ", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Argument Consistency Checking -------------------------------------------------------------- if (present(regDecomp)) then if (size(regDecomp) .lt. dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- regDecomp size doesn't match Grid dimCount ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(decompFlag)) then if (size(decompFlag) .lt. dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- decompFlag size doesn't match Grid dimCount ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if ((dimCount .lt. 3) .and. present(connflagDim3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- connflagDim3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(poleStaggerLoc3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- poleStaggerLoc3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(bipolePos3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- bipolePos3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(coordDep3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(coordDep1)) then if ((size(coordDep1) < 1) .or. (size(coordDep1)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep1 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep2)) then if ((size(coordDep2) < 1) .or. (size(coordDep2)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep2 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep3)) then if ((size(coordDep3) < 1) .or. (size(coordDep3)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep3 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(minIndex)) then if (size(minIndex) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- minIndex size must equal grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Check DimCount of gridWidths and Aligns if (present(gridEdgeLWidth)) then if (size(gridEdgeLWidth) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeLWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (size(gridEdgeUWidth) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeUWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridAlign)) then if (size(gridAlign) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridAlign must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim1)) then if (size(connflagDim1) == 1) then if (connflagDim1(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim1) == 2) then if (connflagDim1(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim1(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim2)) then if (size(connflagDim2) == 1) then if (connflagDim2(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim2) == 2) then if (connflagDim2(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim2(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim3)) then if (size(connflagDim3) == 1) then if (connflagDim3(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim3) == 2) then if (connflagDim3(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim3(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! check for gridMemLBound issues if (present(gridMemLBound)) then if (.not. present(indexflag)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using gridMemLBound must specify indexflag=ESMF_INDEX_USER ", & ESMF_CONTEXT, rcToReturn=rc) return else if (.not.(indexflag == ESMF_INDEX_USER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using gridMemLBound must specify indexflag=ESMF_INDEX_USER ", & ESMF_CONTEXT, rcToReturn=rc) return endif else if (present(indexflag)) then if (indexflag == ESMF_INDEX_USER) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using indexflag=ESMF_INDEX_USER must provide gridMemLBound ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif ! Check for non-valid connection types here !TODO: Consider making some of these a separate local subroutine (particularly if you're going to ! have 3 of these ShapeCreate subroutines with only minor changes ! Set Defaults ------------------------------------------------------------------ ! Set default for minIndex allocate(minIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(minIndex)) then minIndexLocal(:)=minIndex(:) else do i=1,dimCount minIndexLocal(i)=1 enddo endif ! Set default for maxIndex allocate(maxIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexLocal(:)=maxIndex(:) ! Set default for regDecomp allocate(regDecompLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating regDecompLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(regDecomp)) then regDecompLocal(:)=regDecomp(:) else ! The default is 1D divided among all the Pets call ESMF_VMGetGlobal(vm,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_VMGet(vm,petCount=regDecompLocal(1),rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return do i=2,dimCount regDecompLocal(i)=1 enddo endif ! Set Default for connections (although they don't work yet in distgrid/array, so they aren't really used anywhere yet.) if (present(connflagDim1)) then if (size(connflagDim1) == 1) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim1) >= 2) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(2) endif else connflagDim1Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim1Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim2)) then if (size(connflagDim2) == 1) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim2) >= 2) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(2) endif else connflagDim2Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim2Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim3)) then if (size(connflagDim3) == 1) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim3) >= 2) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(2) endif else connflagDim3Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim3Local(2)=ESMF_GRIDCONN_NONE endif ! check for not implemented functionality if (connflagDim1Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim1Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim2Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim2Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim3Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim3Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(petMap)) then if (dimCount > 2) then if ((size(petMap,1) /= regDecompLocal(1)) .or. & (size(petMap,2) /= regDecompLocal(2)) .or. & (size(petMap,3) /= regDecompLocal(3))) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif else if ((size(petMap,1) /= regDecompLocal(1)) .or. & (size(petMap,2) /= regDecompLocal(2)) .or. & (size(petMap,3) /= 1)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif ! Modify Bounds by GridEdgeUWidth and GridEdgeLWidth ------------------------- ! setup maxIndexLocal to hold modified bounds allocate(gridEdgeLWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeLWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridEdgeUWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeUWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridAlignLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridAlignLocal", & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridLUADefault(dimCount, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridEdgeLWidthLocal, gridEdgeUWidthLocal, gridAlignLocal, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return #if 0 ! Modify lower bound do i=1,dimCount minIndexLocal(i)=minIndexLocal(i)-gridEdgeLWidthLocal(i) enddo ! Modify upper bound do i=1,dimCount maxIndexLocal(i)=maxIndexLocal(i)+gridEdgeUWidthLocal(i) enddo #endif ! Set default for decomp flag based on gridEdgeWidths ----------------------------------- ! NOTE: This is a temporary fix until we have something better implemented in distGrid ! Set default for decompFlag allocate(decompFlagLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating decompFlagLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(decompFlag)) then decompFlagLocal(:)=decompFlag(:) else decompFlagLocal(:)=ESMF_DECOMP_BALANCED endif allocate(distgridToGridMap(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distgridToGridMap", & ESMF_CONTEXT, rcToReturn=rc)) return do i=1,dimCount distgridToGridMap(i)=i enddo ! Setup Connections between tile sides ---------------------------------------- ! CONNECTIONS DON'T WORK YET SO NOT IMPLEMENTED ! Process PetMap -------------------------------------------------------------- !! Calculate deCount deCount=1 do i=1,dimCount deCount=deCount*regDecompLocal(i) enddo ! create DELayout based on presence of petMap if (present(petMap)) then !! Allocate petList allocate(petList(deCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating petList", & ESMF_CONTEXT, rcToReturn=rc)) return !! copy petMap to petList if (dimCount > 2) then k=1 do i3=1,regDecompLocal(3) do i2=1,regDecompLocal(2) do i1=1,regDecompLocal(1) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo else k=1 do i3=1,1 do i2=1,regDecompLocal(2) do i1=1,regDecompLocal(1) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo endif !! create delayout from the petList delayout=ESMF_DELayoutCreate(petList=petList,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Get rid of list deallocate(petList) else !! create a default delayout delayout=ESMF_DELayoutCreate(deCount=deCount,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Create DistGrid -------------------------------------------------------------- distgrid=ESMF_DistGridCreate(minIndex=minIndexLocal, maxIndex=maxIndexLocal, & regDecomp=regDecompLocal, decompFlag=decompFlagLocal, delayout=delayout,& indexflag=indexflag, & #if 0 regDecompFirstExtra=gridEdgeLWidthLocal, & regDecompLastExtra=gridEdgeUWidthLocal, & #endif rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Convert coordDeps to coordDimCount and coordDimMap ------------------------------- allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(coordDep1)) then coordDimCount(1)=size(coordDep1) coordDimMap(1,:)=0 do i=1,size(coordDep1) coordDimMap(1,i)=coordDep1(i) enddo else coordDimCount(1)=dimCount do i=1,dimCount coordDimMap(1,i)=i enddo endif if (present(coordDep2)) then coordDimCount(2)=size(coordDep2) coordDimMap(2,:)=0 do i=1,size(coordDep2) coordDimMap(2,i)=coordDep2(i) enddo else coordDimCount(2)=dimCount do i=1,dimCount coordDimMap(2,i)=i enddo endif if (dimCount > 2) then if (present(coordDep3)) then coordDimCount(3)=size(coordDep3) coordDimMap(3,:)=0 do i=1,size(coordDep3) coordDimMap(3,i)=coordDep3(i) enddo else coordDimCount(3)=dimCount do i=1,dimCount coordDimMap(3,i)=i enddo endif endif ESMF_GridCreateShapeTileReg=ESMF_GridCreateFrmDistGrid(distgrid, & distgridToGridMap=distgridToGridMap, & coordTypeKind=coordTypeKind, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & gridEdgeLWidth=gridEdgeLWidthLocal, & gridEdgeUWidth=gridEdgeUWidthLocal, & gridAlign=gridAlignLocal, & gridMemLBound=gridMemLBound, & indexflag=indexflag, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid call ESMF_GridSetDestroyDistgrid(ESMF_GridCreateShapeTileReg,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout(ESMF_GridCreateShapeTileReg,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(regDecompLocal) deallocate(decompFlagLocal) deallocate(coordDimCount) deallocate(coordDimMap) deallocate(minIndexLocal) deallocate(maxIndexLocal) deallocate(distgridToGridMap) deallocate(gridEdgeLWidthLocal) deallocate(gridEdgeUWidthLocal) deallocate(gridAlignLocal) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateShapeTileReg !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreateShapeTileArb" !BOPI ! !IROUTINE: ESMF_GridCreateShapeTile - Create a Grid with an arbitrary distribution ! !INTERFACE: ! Private name; call using ESMF_GridCreateShapeTile() function ESMF_GridCreateShapeTileArb(coordTypeKind, minIndex, & maxIndex, arbIndexCount, arbIndexList, & keywordEnforcer, connflagDim1, connflagDim2, connflagDim3, & poleStaggerLoc1, poleStaggerLoc2, poleStaggerLoc3, & bipolePos1, bipolePos2, bipolePos3, & coordDep1, coordDep2, coordDep3, & distDim, name, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridCreateShapeTileArb ! ! !ARGUMENTS: type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: minIndex(:) integer, intent(in) :: maxIndex(:) integer, intent(in) :: arbIndexCount integer, intent(in) :: arbIndexList(:,:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim1(:) ! N. IMP. type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim2(:) ! N. IMP. type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim3(:) ! N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc1(2)! N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc2(2)! N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc3(2)! N. IMP. integer, intent(in), optional :: bipolePos1(2)! N. IMP. integer, intent(in), optional :: bipolePos2(2)! N. IMP. integer, intent(in), optional :: bipolePos3(2)! N. IMP. integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(in), optional :: distDim(:) character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This method creates a single tile, arbitrarily distributed grid ! (see Figure \ref{fig:GridDecomps}). ! To specify the arbitrary distribution, the user passes in an 2D array ! of local indices, where the first dimension is the number of local grid cells ! specified by {\tt localArbIndexCount} and the second dimension is the number of distributed ! dimensions. ! ! {\tt distDim} specifies which grid dimensions are arbitrarily distributed. The ! size of {\tt distDim} has to agree with the size of the second dimension of ! {\tt localArbIndex}. ! ! The arguments are: ! \begin{description} ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[minIndex]}] ! Tuple to start the index ranges at. If not present, defaults ! to /1,1,1,.../. ! \item[{[maxIndex]}] ! The upper extend of the grid index ranges. ! \item[{arbIndexCount}] ! The number of grid cells in the local DE. It is okay to have 0 ! grid cell in a local DE. ! \item[{[arbIndexList]}] ! This 2D array specifies the indices of the PET LOCAL grid cells. The ! dimensions should be arbIndexCount * number of Distributed grid dimensions ! where arbIndexCount is the input argument specified below ! \item[{[connflagDim1]}] ! Fortran array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[connflagDim2]}] ! Fortran array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[connflagDim3]}] ! Fortran array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc1]}] ! Two element array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc2]}] ! Two element array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc3]}] ! Two element array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos1]}] ! Two element array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos2]}] ! Two element array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos3]}] ! Two element array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[coordDep1]}] ! The size of the array specifies the number of dimensions of the ! first coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_DIM\_ARB/ where ! /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_DIM\_ARB/ if the first dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=1) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB. ! \item[{[coordDep2]}] ! The size of the array specifies the number of dimensions of the ! second coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_DIM\_ARB/ where ! /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_DIM\_ARB/ if this dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=2) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB. ! \item[{[coordDep3]}] ! The size of the array specifies the number of dimensions of the ! third coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_DIM\_ARB/ where ! /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_DIM\_ARB/ if this dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=3) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB. ! \item[{[distDim]}] ! This array specifies which dimensions are arbitrarily distributed. ! The size of the array specifies the total distributed dimensions. ! if not specified, defaults is all dimensions will be arbitrarily ! distributed. The size has to agree with the size of the second ! dimension of {\tt localArbIndex}. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI type(ESMF_DistGrid) :: distgrid integer, pointer :: undistLBound(:) integer, pointer :: undistUBound(:) integer, pointer :: coordDimCount(:) integer, pointer :: coordDimMap(:,:) integer :: localrc integer :: dimCount,distDimCount,undistDimCount integer, pointer :: indexArray(:,:) integer :: i,j,ud type(ESMF_GridConn_Flag) :: connflagDim1Local(2) type(ESMF_GridConn_Flag) :: connflagDim2Local(2) type(ESMF_GridConn_Flag) :: connflagDim3Local(2) integer, pointer :: distSize(:) integer, pointer :: distDimLocal(:) logical, pointer :: isDist(:) integer, pointer :: local1DIndices(:) integer :: ind logical :: found ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL !DUMMY TEST TO QUIET DOWN COMPILER WARNINGS !TODO: Remove the following test when dummy argument actually used if (present(polestaggerloc1)) then if (polestaggerloc1(1)==polestaggerloc1(1)) continue; endif !DUMMY TEST TO QUIET DOWN COMPILER WARNINGS !TODO: Remove the following test when dummy argument actually used if (present(polestaggerloc2)) then if (polestaggerloc2(1)==polestaggerloc2(1)) continue; endif !DUMMY TEST TO QUIET DOWN COMPILER WARNINGS !TODO: Remove the following test when dummy argument actually used if (present(bipolepos1)) then if (bipolepos1(1)==bipolepos1(1)) continue; endif !DUMMY TEST TO QUIET DOWN COMPILER WARNINGS !TODO: Remove the following test when dummy argument actually used if (present(bipolepos2)) then if (bipolepos2(1)==bipolepos2(1)) continue; endif ! Compute the Grid DimCount and Derivatives --------------------------------------------------- ! dimCount dimCount=size(maxIndex) if ((dimCount < 2) .or. (dimCount > 3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- maxIndex size and thus Grid dimCount must be either 2 or 3 when using create shape ", & ESMF_CONTEXT, rcToReturn=rc) return endif ! number of distributed dimension, distDimCount, is determined by the second dim of ! localArbIndex distDimCount = size(arbIndexList,2) if (distDimCount > dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- the second dim of localArbIndex must be equal or less than grid dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif allocate(distDimLocal(distDimCount), stat=localrc) allocate(isDist(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distDimLocal or isDist", & ESMF_CONTEXT, rcToReturn=rc)) return isDist(:)=.false. ! check distribution info if (present(distDim)) then if (size(distDim) /= distDimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- distDim must match with the second dimension of localArbIndex", & ESMF_CONTEXT, rcToReturn=rc) return endif distDimLocal(:)=distDim(:) do i=1,distDimCount isDist(distDimLocal(i))=.true. enddo else do i=1,distDimCount distDimLocal(i)=i enddo isDist(1:distDimCount)=.true. endif ! Argument Consistency Checking -------------------------------------------------------------- if ((dimCount .lt. 3) .and. present(connflagDim3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- connflagDim3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(poleStaggerLoc3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- poleStaggerLoc3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(bipolePos3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- bipolePos3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(minIndex)) then if (size(minIndex) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- minIndex size must equal grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Check for non-valid connection types here ! Set Defaults ------------------------------------------------------------- ! Set default for minIndex allocate(indexArray(2,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(minIndex)) then indexArray(1,:)=minIndex(:) else indexArray(1,:)=1 endif ! Set default for maxIndex indexArray(2,:)=maxIndex(:) ! dimCount of distributed part allocate(distSize(distDimCount),stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distSize", & ESMF_CONTEXT, rcToReturn=rc)) return do i=1,distDimCount ind = distDimLocal(i) distSize(i)=indexArray(2,ind)-indexArray(1,ind)+1 enddo ! dimCounts of the undistributed part of the grid undistDimCount=dimCount-distDimCount ! can't have all undistributed dimensions if (distDimCount == 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Need to have at least one distributed dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif ! convert localArbIndex into 1D index array for DistGrid ! Check localArbIndex dimension matched with localArbIndexCount and diskDimCount if (size(arbIndexList, 1) /= arbIndexCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- localArbIndex 1st dimension has to match with localArbIndexCount", & ESMF_CONTEXT, rcToReturn=rc) return endif allocate(local1DIndices(arbIndexCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating local1DIndices", & ESMF_CONTEXT, rcToReturn=rc)) return if (arbIndexCount > 0) then ! use 0-based index to calculate the 1D index and add 1 back at the end do i = 1, arbIndexCount local1DIndices(i) = arbIndexList(i,1)-1 if (distDimCount >= 2) then do j = 2,distDimCount local1DIndices(i) = local1DIndices(i)*distSize(j) + arbIndexList(i,j)-1 enddo endif local1DIndices(i) = local1DIndices(i)+1 enddo endif ! Set Default for connections (although they don't work yet in distgrid/array, so they aren't really used anywhere yet.) if (present(connflagDim1)) then if (size(connflagDim1) == 1) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim1) >= 2) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(2) endif else connflagDim1Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim1Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim2)) then if (size(connflagDim2) == 1) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim2) >= 2) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(2) endif else connflagDim2Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim2Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim3)) then if (size(connflagDim3) == 1) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim3) >= 2) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(2) endif else connflagDim3Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim3Local(2)=ESMF_GRIDCONN_NONE endif ! check for not implemented functionality if (connflagDim1Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim1Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim2Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim2Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim3Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim3Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Setup Connections between tile sides ---------------------------------------- ! CONNECTIONS DON'T WORK YET SO NOT IMPLEMENTED ! Convert coordDeps to coordDimCount and coordDimMap ------------------------------- allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(coordDep1)) then ! error checking, if this dimension is arbitrary, one of the ! coordinate dimension has to be be ESMF_DIM_ARB if (isDist(1)) then found = .false. do i=1,size(coordDep1) if (coordDep1(i) == ESMF_DIM_ARB) found = .true. enddo if (.not. found) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep1 does not contain ESMF_DIM_ARB", & ESMF_CONTEXT, rcToReturn=rc) return endif endif coordDimCount(1)=size(coordDep1) coordDimMap(1,:)=0 do i=1,size(coordDep1) coordDimMap(1,i)=coordDep1(i) enddo else coordDimCount(1)=1 ! ESMF_DIM_ARB if 1 is distributed, otherwise 1 if (isDist(1)) then coordDimMap(1,1)=ESMF_DIM_ARB else coordDimMap(1,1)=1 endif endif if (present(coordDep2)) then ! error checking, one of the dimensions has to be ESMF_DIM_ARB ! if dimension 2 is arbitrary if (isDist(2)) then found = .false. do i=1,size(coordDep2) if (coordDep2(i) == ESMF_DIM_ARB) found = .true. enddo if (.not. found) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep2 does not contain ESMF_DIM_ARB", & ESMF_CONTEXT, rcToReturn=rc) return endif endif coordDimCount(2)=size(coordDep2) coordDimMap(2,:)=0 do i=1,size(coordDep2) coordDimMap(2,i)=coordDep2(i) enddo else coordDimCount(2)=1 ! ESMF_DIM_ARB if 1 is distributed, otherwise 1 if (isDist(2)) then coordDimMap(2,1)=ESMF_DIM_ARB else coordDimMap(2,1)=2 endif endif if (dimCount > 2) then if (present(coordDep3)) then ! error checking, one of the dimensions has to be ESMF_DIM_ARB ! if dimension 3 is arbitrary if (isDist(3)) then found = .false. do i=1,size(coordDep3) if (coordDep3(i) == ESMF_DIM_ARB) found = .true. enddo if (.not. found) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep3 does not contain ESMF_DIM_ARB", & ESMF_CONTEXT, rcToReturn=rc) return endif endif coordDimCount(3)=size(coordDep3) coordDimMap(3,:)=0 do i=1,size(coordDep3) coordDimMap(3,i)=coordDep3(i) enddo else coordDimCount(3)=1 ! ESMF_DIM_ARB if 1 is distributed, otherwise 1 if (isDist(3)) then coordDimMap(3,1)=ESMF_DIM_ARB else coordDimMap(3,1)=3 endif endif endif ! Calc undistLBound, undistUBound for Grid ----------------------------------------------- if (undistDimCount > 0) then allocate(undistLBound(undistDimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating undistLBound", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(undistUBound(undistDimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating undistUBound", & ESMF_CONTEXT, rcToReturn=rc)) return ! Fill in undistLBound, undistUBound ud=1 do i=1,dimCount if (.not. isDist(i)) then undistLBound(ud)=indexArray(1,i) undistUBound(ud)=indexArray(2,i) ud=ud+1 endif enddo endif ! Create DistGrid -------------------------------------------------------------- if (undistDimCount > 0) then distgrid=ESMF_DistGridCreate(local1DIndices, 1, undistLBound, undistUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return else distgrid=ESMF_DistGridCreate(local1DIndices, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Create Grid from specification ----------------------------------------------- ESMF_GridCreateShapeTileArb=ESMF_GridCreateFrmDistGridArb( & distgrid, indexArray, & distDim=distDimLocal, & coordTypeKind=coordTypeKind, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid call ESMF_GridSetDestroyDistgrid(ESMF_GridCreateShapeTileArb,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout(ESMF_GridCreateShapeTileArb,destroy=.false., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(indexArray) deallocate(local1DIndices) deallocate(isDist) deallocate(distDimLocal) deallocate(coordDimCount) deallocate(coordDimMap) if (undistDimCount > 0) then deallocate(undistLBound) deallocate(undistUBound) endif deallocate(distSize) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateShapeTileArb !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridDestroy" !BOP ! !IROUTINE: ESMF_GridDestroy - Release resources associated with a Grid ! !INTERFACE: subroutine ESMF_GridDestroy(grid, keywordEnforcer, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(inout) :: grid type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! Destroys an {\tt ESMF\_Grid} object and related internal structures. ! This call does destroy internally created DistGrid and DELayout classes, ! for example those created by {\tt ESMF\_GridCreateShapeTile()}. It also ! destroys internally created coordinate/item Arrays, for example those ! created by {\tt ESMF\_GridAddCoord()}. However, if the user uses an ! externally created class, for example creating an Array and setting it ! using {\tt ESMF\_GridSetCoord()}, then that class is not destroyed by ! this method. ! ! The arguments are: ! \begin{description} ! \item[grid] ! {\tt ESMF\_Grid} to be destroyed. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP integer :: localrc ! local error status ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Call F90/C++ interface subroutine call c_ESMC_GridDestroy(grid, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Mark this Grid object as invalid grid%this = ESMF_NULL_POINTER ! Set init code ESMF_INIT_SET_DELETED(grid) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridDestroy !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridEmptyCompleteEConnI" !BOP ! !IROUTINE: ESMF_GridEmptyComplete - Complete a Grid with user set edge connections and an irregular distribution ! !INTERFACE: ! Private name; call using ESMF_GridEmptyComplete() subroutine ESMF_GridEmptyCompleteEConnI(grid, minIndex, & countsPerDEDim1,countsPerDeDim2, keywordEnforcer, & countsPerDEDim3, & connDim1, connDim2, connDim3, & coordSys, coordTypeKind, & coordDep1, coordDep2, coordDep3, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridMemLBound, indexflag, petMap, name, rc) ! !ARGUMENTS: type (ESMF_Grid) :: grid integer, intent(in), optional :: minIndex(:) integer, intent(in) :: countsPerDEDim1(:) integer, intent(in) :: countsPerDEDim2(:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(in), optional :: countsPerDEDim3(:) type(ESMF_GridConn_Flag), intent(in), optional :: connDim1(:) type(ESMF_GridConn_Flag), intent(in), optional :: connDim2(:) type(ESMF_GridConn_Flag), intent(in), optional :: connDim3(:) type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(in), optional :: gridEdgeLWidth(:) integer, intent(in), optional :: gridEdgeUWidth(:) integer, intent(in), optional :: gridAlign(:) integer, intent(in), optional :: gridMemLBound(:) type(ESMF_Index_Flag), intent(in), optional :: indexflag integer, intent(in), optional :: petMap(:,:,:) character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This method takes in an empty Grid created by {\tt ESMF\_GridEmptyCreate()}. ! It then completes the grid to form a single tile, irregularly distributed grid ! (see Figure \ref{fig:GridDecomps}). To specify the irregular distribution, the user passes in an array ! for each grid dimension, where the length of the array is the number ! of DEs in the dimension. Up to three dimensions can be specified, ! using the countsPerDEDim1, countsPerDEDim2, countsPerDEDim3 arguments. ! The index of each array element corresponds to a DE number. The ! array value at the index is the number of grid cells on the DE in ! that dimension. The dimCount of the grid is equal to the number of ! countsPerDEDim arrays that are specified. ! ! Section \ref{example:2DIrregUniGrid} shows an example ! of using this method to create a 2D Grid with uniformly spaced ! coordinates. This creation method can also be used as the basis for ! grids with rectilinear coordinates or curvilinear coordinates. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! The empty {\tt ESMF\_Grid} to set information into and then commit. ! \item[{[minIndex]}] ! Tuple to start the index ranges at. If not present, defaults ! to /1,1,1,.../. ! \item[{countsPerDEDim1}] ! This arrays specifies the number of cells per DE for index dimension 1 ! for the exclusive region (the center stagger location). ! \item[{countsPerDEDim2}] ! This array specifies the number of cells per DE for index dimension 2 ! for the exclusive region (center stagger location). ! \item[{[countsPerDEDim3]}] ! This array specifies the number of cells per DE for index dimension 3 ! for the exclusive region (center stagger location). ! If not specified then grid is 2D. ! \item[{[connDim1]}] ! Fortran array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connDim2]}] ! Fortran array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connDim3]}] ! Fortran array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[coordSys]}] ! The coordinate system of the grid coordinate data. ! For a full list of options, please see Section~\ref{const:coordsys}. ! If not specified then defaults to ESMF\_COORDSYS\_SPH\_DEG. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[coordDep1]}] ! This array specifies the dependence of the first ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the first ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep2]}] ! This array specifies the dependence of the second ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the second ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep3]}] ! This array specifies the dependence of the third ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the third ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[gridEdgeLWidth]}] ! The padding around the lower edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. It is an error for this to be non-zero ! for a periodic dimension. ! \item[{[gridEdgeUWidth]}] ! The padding around the upper edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. It is an error for this to be non-zero ! for a periodic dimension. ! \item[{[gridAlign]}] ! Specification of how the stagger locations should align with the cell ! index space (can be overridden by the individual staggerAligns). If ! the {\tt gridEdgeWidths} are not specified than this parameter ! implies the EdgeWidths. ! \item[{[gridMemLBound]}] ! Specifies the lower index range of the memory of every DE in this Grid. ! Only used when indexflag is {\tt ESMF\_INDEX\_USER}. May be overridden ! by staggerMemLBound. ! \item[{[indexflag]}] ! Indicates the indexing scheme to be used in the new Grid. Please see ! Section~\ref{const:indexflag} for the list of options. If not present, ! defaults to ESMF\_INDEX\_DELOCAL. ! \item[{[petMap]}] ! \begin{sloppypar} ! Sets the mapping of pets to the created DEs. This 3D ! should be of size size(countsPerDEDim1) x size(countsPerDEDim2) x ! size(countsPerDEDim3). If countsPerDEDim3 isn't present, then ! the last dimension is of size 1. ! \end{sloppypar} ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP type(ESMF_DistGrid) :: distgrid integer, pointer :: coordDimCount(:) integer, pointer :: coordDimMap(:,:) integer :: localrc integer :: dimCount integer, pointer :: gridEdgeLWidthLocal(:) integer, pointer :: gridEdgeUWidthLocal(:) integer, pointer :: gridAlignLocal(:) integer, pointer :: minIndexLocal(:) integer, pointer :: maxIndexLocal(:) type(ESMF_DistgridConnection), pointer :: connList(:) type(ESMF_CoordSys_Flag) :: coordSysLocal ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Get the dimension and extent of the index space call GetIndexSpaceIrreg(minIndex, & countsPerDEDim1,countsPerDeDim2, & countsPerDEDim3, dimCount, minIndexLocal, maxIndexLocal, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Build connection list call SetupTileConn(dimCount, minIndexLocal, maxIndexLocal, & connDim1, connDim2, connDim3, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Create Irregular distgrid and error check associated input and set defaults distgrid=ESMF_GridCreateDistgridIrreg(dimCount, minIndexLocal, maxIndexLocal, & countsPerDEDim1,countsPerDeDim2, & countsPerDEDim3, indexflag, petMap, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set default widths and alignment and error check allocate(gridEdgeLWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeLWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridEdgeUWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeUWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridAlignLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridAlignLocal", & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridLUADefault(dimCount, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridEdgeLWidthLocal, gridEdgeUWidthLocal, gridAlignLocal, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Convert coordDeps to coordDimCount and coordDimMap allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return call CoordInfoFromCoordDep(dimCount, coordDep1, coordDep2, coordDep3,& coordDimCount, coordDimMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set Default coordSys if (present(coordSys)) then coordSysLocal=coordSys else coordSysLocal=ESMF_COORDSYS_SPH_DEG endif ! Create Grid from specification call ESMF_GridSetFromDistGrid( grid, & distgrid=distgrid, & coordSys=coordSysLocal, & coordTypeKind=coordTypeKind, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & gridEdgeLWidth=gridEdgeLWidthLocal, & gridEdgeUWidth=gridEdgeUWidthLocal, & gridAlign=gridAlignLocal, & gridMemLBound=gridMemLBound, & indexflag=indexflag, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Commit Grid ----------------------------------------------------------------- call ESMF_GridCommit(grid, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid Call ESMF_GridSetDestroyDistgrid(grid,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout(grid,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(connList) deallocate(minIndexLocal) deallocate(maxIndexLocal) deallocate(coordDimCount) deallocate(coordDimMap) deallocate(gridEdgeLWidthLocal) deallocate(gridEdgeUWidthLocal) deallocate(gridAlignLocal) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridEmptyCompleteEConnI !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridEmptyCompleteEConnR" !BOP ! !IROUTINE: ESMF_GridEmptyComplete - Complete a Grid with user set edge connections and a regular distribution ! !INTERFACE: ! Private name; call using ESMF_GridEmptyComplete() subroutine ESMF_GridEmptyCompleteEConnR(grid, regDecomp, decompFlag, & minIndex, maxIndex, keywordEnforcer, & connDim1, connDim2, connDim3, & coordSys, coordTypeKind, & coordDep1, coordDep2, coordDep3, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridMemLBound, indexflag, petMap, name, rc) !! ! !ARGUMENTS: type (ESMF_Grid) :: grid integer, intent(in), optional :: regDecomp(:) type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) integer, intent(in), optional :: minIndex(:) integer, intent(in) :: maxIndex(:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_GridConn_Flag), intent(in), optional :: connDim1(:) type(ESMF_GridConn_Flag), intent(in), optional :: connDim2(:) type(ESMF_GridConn_Flag), intent(in), optional :: connDim3(:) type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(in), optional :: gridEdgeLWidth(:) integer, intent(in), optional :: gridEdgeUWidth(:) integer, intent(in), optional :: gridAlign(:) integer, intent(in), optional :: gridMemLBound(:) type(ESMF_Index_Flag), intent(in), optional :: indexflag integer, intent(in), optional :: petMap(:,:,:) character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This method takes in an empty Grid created by {\tt ESMF\_GridEmptyCreate()}. ! It then completes the grid to form a single tile, regularly distributed grid ! (see Figure \ref{fig:GridDecomps}). ! To specify the distribution, the user passes in an array ! ({\tt regDecomp}) specifying the number of DEs to divide each ! dimension into. The array {\tt decompFlag} indicates how the division into DEs is to ! occur. The default is to divide the range as evenly as possible. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! The empty {\tt ESMF\_Grid} to set information into and then commit. ! \item[{[regDecomp]}] ! List that has the same number of elements as {\tt maxIndex}. ! Each entry is the number of decounts for that dimension. ! If not specified, the default decomposition will be petCountx1x1..x1. ! \item[{[decompflag]}] ! List of decomposition flags indicating how each dimension of the ! tile is to be divided between the DEs. The default setting ! is {\tt ESMF\_DECOMP\_HOMOGEN} in all dimensions. Please see ! Section~\ref{const:decompflag} for a full description of the ! possible options. ! \item[{[minIndex]}] ! The bottom extent of the grid array. If not given then the value defaults ! to /1,1,1,.../. ! \item[{maxIndex}] ! The upper extent of the grid array. ! \item[{[connDim1]}] ! Fortran array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connDim2]}] ! Fortran array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connDim3]}] ! Fortran array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[coordSys]}] ! The coordinate system of the grid coordinate data. ! For a full list of options, please see Section~\ref{const:coordsys}. ! If not specified then defaults to ESMF\_COORDSYS\_SPH\_DEG. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[coordDep1]}] ! This array specifies the dependence of the first ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the first ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep2]}] ! This array specifies the dependence of the second ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the second ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep3]}] ! This array specifies the dependence of the third ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the third ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[gridEdgeLWidth]}] ! The padding around the lower edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. It is an error for this to be non-zero ! for a periodic dimension. ! \item[{[gridEdgeUWidth]}] ! The padding around the upper edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. It is an error for this to be non-zero ! for a periodic dimension. ! \item[{[gridAlign]}] ! Specification of how the stagger locations should align with the cell ! index space (can be overridden by the individual staggerAligns). If ! the {\tt gridEdgeWidths} are not specified than this parameter ! implies the EdgeWidths. ! \item[{[gridMemLBound]}] ! Specifies the lower index range of the memory of every DE in this Grid. ! Only used when indexflag is {\tt ESMF\_INDEX\_USER}. May be overridden ! by staggerMemLBound. ! \item[{[indexflag]}] ! Indicates the indexing scheme to be used in the new Grid. Please see ! Section~\ref{const:indexflag} for the list of options. If not present, ! defaults to ESMF\_INDEX\_DELOCAL. ! \item[{[petMap]}] ! Sets the mapping of pets to the created DEs. This 3D ! should be of size regDecomp(1) x regDecomp(2) x regDecomp(3) ! If the Grid is 2D, then the last dimension is of size 1. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP type(ESMF_DistGrid) :: distgrid integer, pointer :: coordDimCount(:) integer, pointer :: coordDimMap(:,:) integer, pointer :: gridEdgeLWidthLocal(:) integer, pointer :: gridEdgeUWidthLocal(:) integer, pointer :: gridAlignLocal(:) integer :: dimCount integer, pointer :: minIndexLocal(:) integer, pointer :: maxIndexLocal(:) integer :: localrc type(ESMF_DistgridConnection), pointer :: connList(:) type(ESMF_CoordSys_Flag) :: coordSysLocal ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Get IndexSpace call GetIndexSpaceReg(minIndex, maxIndex, & dimCount, minIndexLocal, maxIndexLocal, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Build connection list call SetupTileConn(dimCount, minIndexLocal, maxIndexLocal, & connDim1, connDim2, connDim3, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Compute regular distgrid and error check associated input and set defaults distgrid=ESMF_GridCreateDistgridReg(dimCount, minIndexLocal, maxIndexLocal, & regDecomp, decompFlag, indexflag, petMap, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set default widths and alignment and error check allocate(gridEdgeLWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeLWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridEdgeUWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeUWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridAlignLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridAlignLocal", & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridLUADefault(dimCount, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridEdgeLWidthLocal, gridEdgeUWidthLocal, gridAlignLocal, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Convert coordDeps to coordDimCount and coordDimMap allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return call CoordInfoFromCoordDep(dimCount, coordDep1, coordDep2, coordDep3,& coordDimCount, coordDimMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set Default coordSys if (present(coordSys)) then coordSysLocal=coordSys else coordSysLocal=ESMF_COORDSYS_SPH_DEG endif ! Create Grid from specification call ESMF_GridSetFromDistGrid( grid, & distgrid=distgrid, & coordSys=coordSysLocal, & coordTypeKind=coordTypeKind, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & gridEdgeLWidth=gridEdgeLWidthLocal, & gridEdgeUWidth=gridEdgeUWidthLocal, & gridAlign=gridAlignLocal, & gridMemLBound=gridMemLBound, & indexflag=indexflag, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Commit Grid ----------------------------------------------------------------- call ESMF_GridCommit(grid, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid call ESMF_GridSetDestroyDistgrid(grid,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout(grid,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(connList) deallocate(coordDimCount) deallocate(coordDimMap) deallocate(gridEdgeLWidthLocal) deallocate(gridEdgeUWidthLocal) deallocate(gridAlignLocal) deallocate(minIndexLocal) deallocate(maxIndexLocal) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridEmptyCompleteEConnR !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridEmptyCompleteEConnA" !BOP ! !IROUTINE: ESMF_GridEmptyComplete - Complete a Grid with user set edge connections and an arbitrary distribution ! !INTERFACE: ! Private name; call using ESMF_GridEmptyComplete() subroutine ESMF_GridEmptyCompleteEConnA(grid, minIndex, maxIndex, & arbIndexCount, arbIndexList, keywordEnforcer, & connDim1, connDim2, connDim3, & coordSys, coordTypeKind, & coordDep1, coordDep2, coordDep3, & distDim, name, rc) !! ! !ARGUMENTS: type (ESMF_Grid) :: grid integer, intent(in), optional :: minIndex(:) integer, intent(in) :: maxIndex(:) integer, intent(in) :: arbIndexCount integer, intent(in) :: arbIndexList(:,:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_GridConn_Flag), intent(in), optional :: connDim1(:) type(ESMF_GridConn_Flag), intent(in), optional :: connDim2(:) type(ESMF_GridConn_Flag), intent(in), optional :: connDim3(:) type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(in), optional :: distDim(:) character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This method takes in an empty Grid created by {\tt ESMF\_GridEmptyCreate()}. ! It then completes the grid to form a single tile, arbitrarily distributed grid ! (see Figure \ref{fig:GridDecomps}). ! To specify the arbitrary distribution, the user passes in an 2D array ! of local indices, where the first dimension is the number of local grid cells ! specified by {\tt localArbIndexCount} and the second dimension is the number of distributed ! dimensions. ! ! {\tt distDim} specifies which grid dimensions are arbitrarily distributed. The ! size of {\tt distDim} has to agree with the size of the second dimension of ! {\tt localArbIndex}. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! The empty {\tt ESMF\_Grid} to set information into and then commit. ! \item[{[minIndex]}] ! Tuple to start the index ranges at. If not present, defaults ! to /1,1,1,.../. ! \item[{[maxIndex]}] ! The upper extend of the grid index ranges. ! \item[{arbIndexCount}] ! The number of grid cells in the local DE. It is okay to have 0 ! grid cell in a local DE. ! \item[{[arbIndexList]}] ! This 2D array specifies the indices of the PET LOCAL grid cells. The ! dimensions should be arbIndexCount * number of Distributed grid dimensions ! where arbIndexCount is the input argument specified below ! \item[{[connDim1]}] ! Fortran array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connDim2]}] ! Fortran array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[connDim3]}] ! Fortran array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! \item[{[coordSys]}] ! The coordinate system of the grid coordinate data. ! For a full list of options, please see Section~\ref{const:coordsys}. ! If not specified then defaults to ESMF\_COORDSYS\_SPH\_DEG. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[coordDep1]}] ! The size of the array specifies the number of dimensions of the ! first coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_GRID\_ARBDIM/ where ! /ESMF\_GRID\_ARBDIM/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_GRID\_ARBDIM/ if the first dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=1) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_GRID\_ARBDIM. ! \item[{[coordDep2]}] ! The size of the array specifies the number of dimensions of the ! second coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_GRID\_ARBDIM/ where ! /ESMF\_GRID\_ARBDIM/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_GRID\_ARBDIM/ if this dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=2) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_GRID\_ARBDIM. ! \item[{[coordDep3]}] ! The size of the array specifies the number of dimensions of the ! third coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_GRID\_ARBDIM/ where ! /ESMF\_GRID\_ARBDIM/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_GRID\_ARBDIM/ if this dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=3) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_GRID\_ARBDIM. ! \item[{[distDim]}] ! This array specifies which dimensions are arbitrarily distributed. ! The size of the array specifies the total distributed dimensions. ! if not specified, defaults is all dimensions will be arbitrarily ! distributed. The size has to agree with the size of the second ! dimension of {\tt localArbIndex}. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP type(ESMF_DistGrid) :: distgrid integer, pointer :: coordDimCount(:) integer, pointer :: coordDimMap(:,:) integer :: localrc integer :: dimCount,distDimCount integer :: i integer, pointer :: indexArray(:,:) logical, pointer :: isDistLocal(:) integer, pointer :: distDimLocal(:) integer, pointer :: minIndexLocal(:) integer, pointer :: maxIndexLocal(:) type(ESMF_DistgridConnection), pointer :: connList(:) type(ESMF_CoordSys_Flag) :: coordSysLocal ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Get description of index space and what's undistributed call GetIndexSpaceArb(minIndex, maxIndex, & arbIndexCount, arbIndexList, distDim, & dimCount, distDimCount, isDistLocal, distDimLocal, & minIndexLocal, maxIndexLocal, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Build connection list call SetupTileConn(dimCount, minIndexLocal, maxIndexLocal, & connDim1, connDim2, connDim3, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Create arbitrary distgrid distgrid= ESMF_GridCreateDistgridArb(dimCount, distDimCount, isDistLocal, distDimLocal, & minIndexLocal, maxIndexLocal, arbIndexCount, arbIndexList, connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Convert coordDeps to coordDimCount and coordDimMap allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return call CoordInfoFromCoordDepArb(dimCount, isDistLocal, coordDep1, coordDep2, coordDep3,& coordDimCount, coordDimMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Put minIndex, maxIndex into indexArray for create from distgrid allocate(indexArray(2,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating indexArray", & ESMF_CONTEXT, rcToReturn=rc)) return indexArray(1,:)=minIndexLocal(:) indexArray(2,:)=maxIndexLocal(:) ! Set Default coordSys if (present(coordSys)) then coordSysLocal=coordSys else coordSysLocal=ESMF_COORDSYS_SPH_DEG endif ! Create Grid from specification ----------------------------------------------- call ESMF_GridSetFromDistGrid(grid, coordTypeKind=coordTypeKind, & distgrid=distgrid, & minIndex=minIndexLocal, maxIndex=maxIndexLocal, & distDim=distDimLocal, & coordSys=coordSysLocal, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & localArbIndexCount=arbIndexCount, localArbIndex=arbIndexList, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Commit Grid ----------------------------------------------------------------- call ESMF_GridCommit(grid, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid call ESMF_GridSetDestroyDistgrid(grid,destroy=.true., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout(grid,destroy=.false., & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(connList) deallocate(minIndexLocal) deallocate(maxIndexLocal) deallocate(isDistLocal) deallocate(indexArray) deallocate(distDimLocal) deallocate(coordDimCount) deallocate(coordDimMap) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridEmptyCompleteEConnA !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridEmptyCreate" !BOP ! !IROUTINE: ESMF_GridEmptyCreate - Create a Grid that has no contents ! !INTERFACE: function ESMF_GridEmptyCreate(keywordEnforcer, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridEmptyCreate ! ! !ARGUMENTS: type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! Partially create an {\tt ESMF\_Grid} object. This function allocates ! an {\tt ESMF\_Grid} object, but doesn't allocate any coordinate storage or other ! internal structures. The {\tt ESMF\_GridEmptyComplete()} calls ! can be used to set the values in the grid object and to construct the ! internal structure. ! ! The arguments are: ! \begin{description} ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP integer :: localrc ! local error status type(ESMF_Grid) :: grid ! Initialize this grid object as invalid grid%this = ESMF_NULL_POINTER ! Call C++ Subroutine to do the create call c_ESMC_gridcreateempty(grid%this, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set return value ESMF_GridEmptyCreate = grid ! Set init status ESMF_INIT_SET_CREATED(ESMF_GridEmptyCreate) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridEmptyCreate !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetDefault" !BOP ! !IROUTINE: ESMF_GridGet - Get information about a Grid ! !INTERFACE: ! Private name; call using ESMF_GridGet() subroutine ESMF_GridGetDefault(grid, keywordEnforcer, coordTypeKind, & dimCount, tileCount, staggerlocCount, localDECount, distgrid, & distgridToGridMap, coordDimCount, coordDimMap, arbDim, & rank, arbDimCount, gridEdgeLWidth, gridEdgeUWidth, gridAlign, & indexFlag, status, name, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_TypeKind_Flag), intent(out), optional :: coordTypeKind integer, intent(out), optional :: dimCount integer, intent(out), optional :: tileCount integer, intent(out), optional :: staggerlocCount integer, intent(out), optional :: localDECount type(ESMF_DistGrid), intent(out), optional :: distgrid integer, target, intent(out), optional :: distgridToGridMap(:) integer, target, intent(out), optional :: coordDimCount(:) integer, target, intent(out), optional :: coordDimMap(:,:) integer, intent(out), optional :: arbDim integer, intent(out), optional :: rank integer, intent(out), optional :: arbDimCount integer, target, intent(out), optional :: gridEdgeLWidth(:) integer, target, intent(out), optional :: gridEdgeUWidth(:) integer, target, intent(out), optional :: gridAlign(:) type(ESMF_Index_Flag), intent(out), optional :: indexflag type(ESMF_GridStatus_Flag), intent(out), optional :: status character (len=*), intent(out), optional :: name integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! Gets various types of information about a grid. ! !The arguments are: !\begin{description} !\item[{grid}] ! Grid to get the information from. !\item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. !\item[{[dimCount]}] ! DimCount of the Grid object. !\item[{[tileCount]}] ! The number of logically rectangular tiles in the grid. !\item[{[staggerlocCount]}] ! The number of stagger locations. !\item[{[localDECount]}] ! The number of DEs in this grid on this PET. !\item[{[distgrid]}] ! The structure describing the distribution of the grid. !\item[{[distgridToGridMap]}] ! List that has as many elements as the distgrid dimCount. This array describes ! mapping between the grids dimensions and the distgrid. ! \item[{[coordDimCount]}] ! List that has as many elements as the grid dimCount (from arrayspec). ! Gives the dimension of each component (e.g. x) array. This is ! to allow factorization of the coordinate arrays. If not specified ! all arrays are the same size as the grid. !\item[{[coordDimMap]}] ! 2D list of size grid dimCount x grid dimCount. This array describes the ! map of each component array's dimensions onto the grids ! dimensions. ! \item[{[arbDim]}] ! The distgrid dimension that is mapped by the arbitrarily distributed grid dimensions. ! \item[{[rank]}] ! The count of the memory dimensions, it is the same as dimCount for a non-arbitrarily distributed grid, ! and equal or less for a arbitrarily distributed grid. ! \item[{[arbDimCount]}] ! The number of dimensions distributed arbitrarily for an arbitrary grid, 0 if the grid is non-arbitrary. ! \item[{[gridEdgeLWidth]}] ! The padding around the lower edges of the grid. The array should ! be of size greater or equal to the Grid dimCount. ! \item[{[gridEdgeUWidth]}] ! The padding around the upper edges of the grid. The array should ! be of size greater or equal to the Grid dimCount. ! \item[{[gridAlign]}] ! Specification of how the stagger locations should align with the cell ! index space. The array should be of size greater or equal to the Grid dimCount. ! \item[{[indexflag]}] ! Flag indicating the indexing scheme being used in the Grid. Please ! see Section~\ref{const:indexflag} for the list of options. ! \item[{[status]}] ! Flag indicating the status of the Grid. Please ! see Section~\ref{const:gridstatus} for the list of options. !\item[{[name]}] ! {\tt ESMF\_Grid} name. !\item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. !\end{description} ! !EOP integer :: localrc ! local error status type(ESMF_GridDecompType) :: decompType ! check if arbitrary type(ESMF_InterfaceInt) :: distgridToGridMapArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: coordDimCountArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: coordDimMapArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: gridEdgeLWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: gridEdgeUWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: gridAlignArg ! Language Interface Helper Var ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) ! Get Grid decomposition type call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (decompType == ESMF_Grid_NONARBITRARY) then if (present(arbDim)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- arbDim does not exist for a non-arbitrarily distributed grid", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! get name if (present(name)) then call c_ESMC_GetName(grid, name, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif if (present(coordTypeKind) .or. & present(dimCount) .or. & present(tileCount) .or. & present(staggerlocCount) .or. & present(localDECount) .or. & present(distgrid) .or. & present(distgridToGridMap) .or. & present(coordDimCount) .or. & present(coordDimMap) .or. & present(arbDim) .or. & present(rank) .or. & present(arbDimCount) .or. & present(gridEdgeLWidth) .or. & present(gridEdgeUWidth) .or. & present(gridAlign) .or. & present(indexFlag)) then !! coordTypeKind ! It doesn't look like it needs to be translated, but test to make sure !! distgridToGridMap distgridToGridMapArg = ESMF_InterfaceIntCreate(distgridToGridMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Description of array factorization coordDimCountArg = ESMF_InterfaceIntCreate(coordDimCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return coordDimMapArg = ESMF_InterfaceIntCreate(farray2D=coordDimMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Grid Boundary Info gridEdgeLWidthArg = ESMF_InterfaceIntCreate(gridEdgeLWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return gridEdgeUWidthArg = ESMF_InterfaceIntCreate(gridEdgeUWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return gridAlignArg = ESMF_InterfaceIntCreate(gridAlign, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call C++ Subroutine to do the get call c_ESMC_gridget(grid%this, & coordTypeKind, dimCount, tileCount, distgrid, staggerlocCount, & distgridToGridMapArg, coordDimCountArg, arbDim, & rank, arbDimCount, coordDimMapArg, & gridEdgeLWidthArg, gridEdgeUWidthArg, gridAlignArg, & indexflag, localDECount, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate helper variables call ESMF_InterfaceIntDestroy(distgridToGridMapArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(coordDimCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(coordDimMapArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(gridEdgeLWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(gridEdgeUWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(gridAlignArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set Deep Classes as created if (present(distgrid)) then call ESMF_DistGridSetInitCreated(distgrid, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif endif ! Call C++ Subroutine to get the status if (present(status)) then call c_ESMC_gridgetstatus(grid%this, status) endif ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetDefault !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetIndex" !BOPI ! !IROUTINE: ESMF_GridGet - Get information about the min and max index of the grid dimension ! !INTERFACE: ! Private name; call using ESMF_GridGet() subroutine ESMF_GridGetIndex(grid, tileNo, minIndex, maxIndex, rc) ! ! !Arguments: type(ESMF_Grid), intent(in) :: grid integer, intent(in), optional :: tileNo integer,target, intent(out), optional :: minIndex(:) integer,target, intent(out) :: maxIndex(:) integer, intent(out), optional :: rc ! ! !DESCRIPTON: ! This method gets the minimal index and maximal index of a given tile of the grid !The arguments are: !\begin{description} !\item[{grid}] ! Grid to get the information from. !\item[{[tileNo]}] ! The tile number from which to get the information. The default is 0. !\item[{[minIndex]}] ! The minimal grid index for the given tile. !\item[{[maxIndex]}] ! The maximal grid index for the given tile. !\item[{[rc]}] ! The return value. !\end{description} ! !EOPI integer :: localrc ! local error status type(ESMF_InterfaceInt) :: minIndexArg ! helper variable type(ESMF_InterfaceInt) :: maxIndexArg ! helper variable type(ESMF_GridDecompType) :: decompType integer :: localTileNo ! local TileNo ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) if (present(tileNo)) then ! Get Grid decomposition type call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if ((decompType == ESMF_GRID_ARBITRARY) .and. & (tileNo /= 1)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- tileNo has to be 1 for arbitrarily distributed grid", & ESMF_CONTEXT, rcToReturn=rc) return elseif (tileNo /= 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- multiple tiles is not implemented", & ESMF_CONTEXT, rcToReturn=rc) return endif localTileNo = tileNo else localTileNo = 1 endif ! process optional arguments minIndexArg=ESMF_InterfaceIntCreate(minIndex, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexArg=ESMF_InterfaceIntCreate(maxIndex, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call c_ESMC_gridgetindex(grid, localTileNo, minIndexArg, maxIndexArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(minIndexArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(maxIndexArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetIndex !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetPLocalDe" !BOP ! !IROUTINE: ESMF_GridGet - Get information about a particular DE in a Grid ! !INTERFACE: ! Private name; call using ESMF_GridGet() subroutine ESMF_GridGetPLocalDe(grid, localDe, keywordEnforcer, & isLBound,isUBound, arbIndexCount, arbIndexList, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: localDe type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below logical, intent(out), optional :: isLBound(:) logical, intent(out), optional :: isUBound(:) integer, intent(out), optional :: arbIndexCount integer, target, intent(out), optional :: arbIndexList(:,:) integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This call gets information about a particular local DE in a Grid. ! !The arguments are: !\begin{description} !\item[{grid}] ! Grid to get the information from. !\item[{[localDe]}] ! The local DE from which to get the information. {\tt [0,..,localDeCount-1]} !\item[{[isLBound]}] ! Upon return, for each dimension this indicates if the DE is a lower bound of the Grid. ! {\tt isLBound} must be allocated to be of size equal to the Grid dimCount. !\item[{[isUBound]}] ! Upon return, for each dimension this indicates if the DE is an upper bound of the Grid. ! {\tt isUBound} must be allocated to be of size equal to the Grid dimCount. ! \item[{[arbIndexCount]}] ! The number of local cells for an arbitrarily distributed grid ! \item[{[arbIndexList]}] ! The 2D array storing the local cell indices for an arbitrarily distributed grid. The size of the array ! is arbIndexCount * arbDimCount !\item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. !\end{description} ! !EOP integer :: localrc ! local error status integer :: isLBoundTmp(ESMF_MAXDIM) integer :: isUBoundTmp(ESMF_MAXDIM) integer :: dimCount,i type(ESMF_GridDecompType) :: decompType ! check if arbitrary type(ESMF_InterfaceInt) :: arbIndexListArg ! Language Interface Helper Var ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) ! Get Grid decomposition type call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (decompType == ESMF_Grid_NONARBITRARY) then if (present(arbIndexCount) .or. present(arbIndexList)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- arbIndexCount, or arbIndexList do not exist for a non-arbitrarily distributed grid", & ESMF_CONTEXT, rcToReturn=rc) return endif else if (decompType == ESMF_Grid_ARBITRARY) then if (present(isUBound) .or. present(isLBound)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- isLBound and/or isUBound not supported for arbitrary Grids", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Get Grid Dimension call ESMF_GridGet(grid, dimCount=dimCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Error check input if (present(isLBound)) then if (size(isLBound) < dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_RANK, & msg="- isLBound must have at least the same size as the grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(isUBound)) then if (size(isUBound) < dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_RANK, & msg="- isUBound must have at least the same size as the grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif !! Arbitrarily distributed grid local indices arbIndexListArg = ESMF_InterfaceIntCreate(farray2D=arbIndexList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetPLocalDe(grid, localDE, & dimCount, isLBoundTmp, isUBoundTmp, arbIndexCount, arbIndexListArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Process return values if (present(isLBound)) then isLBound=.false. do i=1,dimCount if (isLBoundTmp(i) == 1) isLBound(i)=.true. enddo endif if (present(isUBound)) then isUBound=.false. do i=1,dimCount if (isUBoundTmp(i) == 1) isUBound(i)=.true. enddo endif call ESMF_InterfaceIntDestroy(arbIndexListArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetPLocalDe !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetPLocalDePSloc" !BOP ! !IROUTINE: ESMF_GridGet - Get information about a particular DE in a stagger location in a Grid ! !INTERFACE: ! Private name; call using ESMF_GridGet() subroutine ESMF_GridGetPLocalDePSloc(grid, staggerloc, localDE, & keywordEnforcer, exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: localDe type (ESMF_StaggerLoc), intent(in) :: staggerloc type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This method gets information about the range of index space which a ! particular stagger location occupies. This call differs from the coordinate ! bound calls (e.g. {\tt ESMF\_GridGetCoord}) in that a given coordinate ! array may only occupy a subset of the Grid's dimensions, and ! so these calls may not give all the bounds of the stagger location. ! The bounds from this call are the full bounds, and so ! for example, give the appropriate bounds for allocating a Fortran array to hold ! data residing on the stagger location. ! Note that unlike the output from the Array, these values also include the ! undistributed dimensions and are ! ordered to reflect the order of the indices in the Grid. This call will ! still give correct values even if the stagger location does not contain ! coordinate arrays (e.g. if {\tt ESMF\_GridAddCoord} hasn't yet ! been called on the stagger location). ! !The arguments are: !\begin{description} !\item[{grid}] ! Grid to get the information from. !\item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. !\item[{[localDe]}] ! The local DE from which to get the information. {\tt [0,..,localDeCount-1]} !\item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the Grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the Grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[exclusiveCount]}] ! Upon return this holds the number of items,{\tt exclusiveUBound-exclusiveLBound+1}, ! in the exclusive region per dimension. ! {\tt exclusiveCount} must ! be allocated to be of size equal to the Grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[computationalLBound]}] ! \begin{sloppypar} ! Upon return this holds the lower bounds of the computational region. ! {\tt computationalLBound} must be allocated to be of size equal to the Grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \end{sloppypar} !\item[{[computationalUBound]}] ! \begin{sloppypar} ! Upon return this holds the upper bounds of the computational region. ! {\tt computationalUBound} must be allocated to be of size equal to the Grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \end{sloppypar} !\item[{[computationalCount]}] ! \begin{sloppypar} ! Upon return this holds the number of items in the computational region per dimension. ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} must ! be allocated to be of size equal to the Grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \end{sloppypar} !\item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. !\end{description} ! !EOP integer :: localrc ! local error status type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) tmp_staggerloc=staggerloc%staggerloc ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetPLocalDePSloc(grid, localDE, tmp_staggerLoc, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg, & localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetPLocalDePSloc !------------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetPSloc" !BOP ! !IROUTINE: ESMF_GridGet - Get information about a particular stagger location in a Grid ! !INTERFACE: ! Private name; call using ESMF_GridGet() subroutine ESMF_GridGetPSloc(grid, staggerloc, & keywordEnforcer, distgrid, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_StaggerLoc), intent(in) :: staggerloc type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_DistGrid), intent(out), optional :: distgrid integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This method gets information about a particular stagger location. ! This information is useful for creating an ESMF Array to hold ! the data at the stagger location. ! !The arguments are: !\begin{description} !\item[{grid}] ! Grid to get the information from. !\item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. !\item[{[distgrid]}] ! The structure describing the distribution of this staggerloc in this grid. !\item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. !\end{description} ! !EOP integer :: localrc ! local error status type(ESMF_InterfaceInt) :: minIndexArg ! helper variable type(ESMF_InterfaceInt) :: maxIndexArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) tmp_staggerloc=staggerloc%staggerloc ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetPSloc(grid, tmp_staggerLoc, & distgrid, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set Deep Classes as created if (present(distgrid)) then call ESMF_DistGridSetInitCreated(distgrid, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetPSloc !------------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetPSlocPTile" !BOP ! !IROUTINE: ESMF_GridGet - Get information about a particular stagger location and tile ! !INTERFACE: ! Private name; call using ESMF_GridGet() subroutine ESMF_GridGetPSlocPTile(grid, tile, staggerloc, & keywordEnforcer, minIndex, maxIndex, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: tile type (ESMF_StaggerLoc), intent(in) :: staggerloc type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, target, intent(out), optional :: minIndex(:) integer, target, intent(out), optional :: maxIndex(:) integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This method gets information about a particular stagger location. ! This information is useful for creating an ESMF Array to hold ! the data at the stagger location. ! !The arguments are: !\begin{description} !\item[{grid}] ! Grid to get the information from. !\item[{tile}] ! The tile number to get the data from. Tile numbers range from 1 to TileCount. !\item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. !\item[{[minIndex]}] ! Upon return this holds the global lower index of this stagger location. ! {\tt minIndex} must be allocated to be of size equal to the grid DimCount. ! Note that this value is only for the first Grid tile, as multigrid support ! is added, this interface will likely be changed or moved to adapt. !\item[{[maxIndex]}] ! Upon return this holds the global upper index of this stagger location. ! {\tt maxIndex} must be allocated to be of size equal to the grid DimCount. ! Note that this value is only for the first Grid tile, as multigrid support ! is added, this interface will likely be changed or moved to adapt. !\item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. !\end{description} ! !EOP integer :: localrc ! local error status type(ESMF_InterfaceInt) :: minIndexArg ! helper variable type(ESMF_InterfaceInt) :: maxIndexArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) tmp_staggerloc=staggerloc%staggerloc ! process optional arguments minIndexArg=ESMF_InterfaceIntCreate(minIndex, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexArg=ESMF_InterfaceIntCreate(maxIndex, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetPSlocPTile(grid, tile, tmp_staggerLoc, & minIndexArg, maxIndexArg,localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(minIndexArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(maxIndexArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetPSlocPTile !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetDecompType" !BOPI ! !IROUTINE: ESMF_GridGetDecompType - Get decomposition type: arbitrary or not ! !INTERFACE: subroutine ESMF_GridGetDecompType(grid, decompType, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type(ESMF_GridDecompType), intent(out) :: decompType integer, intent(out), optional :: rc ! integer :: localrc call c_ESMC_gridGetDecompType(grid, decompType, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetDecompType !------------------------------------------------------------------------------ !BOP ! !IROUTINE: ESMF_GridGetCoord - Get a Fortran pointer to Grid coord data and coord bounds ! ! !INTERFACE: ! subroutine ESMF_GridGetCoord(grid, coordDim, keywordEnforcer, & ! staggerloc, localDE, , & ! exclusiveLBound, exclusiveUBound, exclusiveCount, & ! computationalLBound, computationalUBound, computationalCount, & ! totalLBound, totalUBound, totalCount, & ! datacopyflag, rc) ! ! !ARGUMENTS: ! type(ESMF_Grid), intent(in) :: grid ! integer, intent(in) :: coordDim !type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below ! type (ESMF_StaggerLoc) intent(in), optional :: staggerloc ! integer, intent(in), optional :: localDE ! , see below for supported values ! integer, intent(out), optional :: exclusiveLBound(:) ! integer, intent(out), optional :: exclusiveUBound(:) ! integer, intent(out), optional :: exclusiveCount(:) ! integer, intent(out), optional :: computationalLBound(:) ! integer, intent(out), optional :: computationalUBound(:) ! integer, intent(out), optional :: computationalCount(:) ! integer, intent(out), optional :: totalLBound(:) ! integer, intent(out), optional :: totalUBound(:) ! integer, intent(out), optional :: totalCount(:) ! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag ! integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! coordinate data on the local DE for the given coordinate dimension and stagger ! locations. ! This is useful, for example, for setting the coordinate values in a Grid, or ! for reading the coordinate values. Currently this method supports up to three ! coordinate dimensions, of either R4 or R8 datatype. See below for specific ! supported values. If the coordinates that you are trying to retrieve are of ! higher dimension, use the {\tt ESMF\_GetCoord()} interface that returns coordinate ! values in an {\tt ESMF\_Array} instead. That interface supports the retrieval of ! coordinates up to 7D. ! ! Supported values for the are: ! \begin{description} ! \item real(ESMF\_KIND\_R4), pointer :: farrayPtr(:) ! \item real(ESMF\_KIND\_R4), pointer :: farrayPtr(:,:) ! \item real(ESMF\_KIND\_R4), pointer :: farrayPtr(:,:,:) ! \item real(ESMF\_KIND\_R8), pointer :: farrayPtr(:) ! \item real(ESMF\_KIND\_R8), pointer :: farrayPtr(:,:) ! \item real(ESMF\_KIND\_R8), pointer :: farrayPtr(:,:,:) ! \end{description} ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{coordDim}] ! The coordinate dimension to get the data from (e.g. 1=x). ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! \item[{[localDE]}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the coordinate data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the coord dimCount. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items, {\tt exclusiveUBound-exclusiveLBound+1}, ! in the exclusive region per dimension. ! {\tt exclusiveCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! \begin{sloppypar} ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \end{sloppypar} ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid coordinate arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetCoord1DR4" !BOPI ! !IROUTINE: ESMF_GridGetCoord - Get pointer to 1DR4 coordinates ! !INTERFACE: ! Private name; call using ESMF_GridGetCoord() subroutine ESMF_GridGetCoord1DR4(grid, coordDim, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, & exclusiveCount, computationalLBound, computationalUBound, & computationalCount, totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: coordDim type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: localDE real(ESMF_KIND_R4), pointer :: farrayPtr(:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! coordinate data for the given coordinate and stagger locations on the given local DE. ! This is useful, for example, for setting the coordinate values in a Grid, or ! for reading the coordinate values. Eventually this method will be overloaded ! for the full range of ESMF supported types and dimensions. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{coordDim}] ! The coordinate dimension to get the data from (e.g. 1=x). ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! \item[{[localDE]}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the coordinate data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! \begin{sloppypar} ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid coordinate arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localarray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc type(ESMF_GridDecompType) :: decompType ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Check consistency call ESMF_GridGet(grid, coordTypeKind=typekind, dimCount=dimCount, coordDimCount=coordDimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr typekind to match Grid typekind if (typekind /= ESMF_TYPEKIND_R4) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr typekind does not match Grid typekind", & ESMF_CONTEXT, rcToReturn=rc) return endif ! make sure coord is legitimate if ((coordDim .lt. 1) .or. (coordDim > dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- coordinate dimension outside of range specified for this Grid", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Require farrayPtr dimCount to match coordinate dimCount if (coordDimCount(coordDim) /= 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested coordinate dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then if ((decompType == ESMF_GRID_ARBITRARY) .and. & (staggerloc /= ESMF_STAGGERLOC_CENTER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return else tmp_staggerloc=staggerloc%staggerloc endif else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif ! Get the Array call ESMF_GridGetCoordIntoArray(grid, coordDim, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Get the pointer from the array call ESMF_ArrayGet(array, localDE=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetCoordBounds(grid, localDE, coordDim, tmp_staggerloc, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetCoord1DR4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetCoord2DR4" !BOPI ! !IROUTINE: ESMF_GridGetCoord - Get pointer to 2DR4 coordinates ! !INTERFACE: ! Private name; call using ESMF_GridGetCoord() subroutine ESMF_GridGetCoord2DR4(grid, coordDim, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: coordDim type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in),optional :: staggerloc integer, intent(in),optional :: localDE real(ESMF_KIND_R4), pointer :: farrayPtr(:,:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! coordinate data for the given coordinate and stagger locations on the given local DE. ! This is useful, for example, for setting the coordinate values in a Grid, or ! for reading the coordinate values. Eventually this method will be overloaded ! for the full range of ESMF supported types and dimensions. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{coordDim}] ! The coordinate dimension to get the data from (e.g. 1=x). ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{[localDE]}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the coordinate data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid coordinate arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localarray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc type(ESMF_GridDecompType) :: decompType ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Check consistency call ESMF_GridGet(grid, coordTypeKind=typekind, dimCount=dimCount, coordDimCount=coordDimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr typekind to match Grid typekind if (typekind /= ESMF_TYPEKIND_R4) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr typekind does not match Grid typekind", & ESMF_CONTEXT, rcToReturn=rc) return endif ! make sure coord is legitimate if ((coordDim .lt. 1) .or. (coordDim > dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- coordinate dimension outside of range specified for this Grid", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Require farrayPtr dimCount to match coordinate dimCount if (coordDimCount(coordDim) /= 2) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested coordinate dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then if ((decompType == ESMF_GRID_ARBITRARY) .and. & (staggerloc /= ESMF_STAGGERLOC_CENTER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return else tmp_staggerloc=staggerloc%staggerloc endif else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif ! Get the Array call ESMF_GridGetCoordIntoArray(grid, coordDim, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDe=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetCoordBounds(grid, localDE, coordDim, tmp_staggerloc, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetCoord2DR4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetCoord3DR4" !BOPI ! !IROUTINE: ESMF_GridGetCoord - Get pointer to 3DR4 coordinates ! !INTERFACE: ! Private name; call using ESMF_GridGetCoord() subroutine ESMF_GridGetCoord3DR4(grid, coordDim, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: coordDim type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in),optional :: localDE real(ESMF_KIND_R4), pointer :: farrayPtr(:,:,:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! coordinate data for the given coordinate and stagger locations on the given local DE. ! This is useful, for example, for setting the coordinate values in a Grid, or ! for reading the coordinate values. Eventually this method will be overloaded ! for the full range of ESMF supported types and dimensions. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{coordDim}] ! The coordinate dimension to get the data from (e.g. 1=x). ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{[localDE]}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the coordinate data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid coordinate arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localArray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc type(ESMF_GridDecompType) :: decompType ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Check consistency call ESMF_GridGet(grid, coordTypeKind=typekind, dimCount=dimCount, coordDimCount=coordDimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr typekind to match Grid typekind if (typekind /= ESMF_TYPEKIND_R4) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr typekind does not match Grid typekind", & ESMF_CONTEXT, rcToReturn=rc) return endif ! make sure coord is legitimate if ((coordDim .lt. 1) .or. (coordDim > dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- coordinate dimension outside of range specified for this Grid", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Require farrayPtr dimCount to match coordinate dimCount if (coordDimCount(coordDim) /= 3) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested coordinate dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then if ((decompType == ESMF_GRID_ARBITRARY) .and. & (staggerloc /= ESMF_STAGGERLOC_CENTER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return else tmp_staggerloc=staggerloc%staggerloc endif else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif ! Get the Array call ESMF_GridGetCoordIntoArray(grid, coordDim, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDE=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments ! for non-arbitrarily grid only ! should check these optional arguments are not present for arbitrary grid???? if (decompType /= ESMF_GRID_ARBITRARY) then exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetCoordBounds(grid, localDE, coordDim, tmp_staggerloc, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetCoord3DR4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetCoord1DR8" !BOPI ! !IROUTINE: ESMF_GridGetCoord - Get pointer to 1DR8 coordinates ! !INTERFACE: ! Private name; call using ESMF_GridGetCoord() subroutine ESMF_GridGetCoord1DR8(grid, coordDim, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: coordDim type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in),optional :: staggerloc integer, intent(in),optional :: localDE real(ESMF_KIND_R8), pointer :: farrayPtr(:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! coordinate data for the given coordinate and stagger locations on the given local DE. ! This is useful, for example, for setting the coordinate values in a Grid, or ! for reading the coordinate values. Eventually this method will be overloaded ! for the full range of ESMF supported types and dimensions. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{coordDim}] ! The coordinate dimension to get the data from (e.g. 1=x). ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{[localDE]}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the coordinate data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid coordinate arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localArray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc type(ESMF_GridDecompType) :: decompType ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Check consistency call ESMF_GridGet(grid, coordTypeKind=typekind, dimCount=dimCount, coordDimCount=coordDimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr typekind to match Grid typekind if (typekind /= ESMF_TYPEKIND_R8) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr typekind does not match Grid typekind", & ESMF_CONTEXT, rcToReturn=rc) return endif ! make sure coord is legitimate if ((coordDim .lt. 1) .or. (coordDim > dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- coordinate dimension outside of range specified for this Grid", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Require farrayPtr dimCount to match coordinate dimCount if (coordDimCount(coordDim) /= 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested coordinate dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then if ((decompType == ESMF_GRID_ARBITRARY) .and. & (staggerloc /= ESMF_STAGGERLOC_CENTER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return else tmp_staggerloc=staggerloc%staggerloc endif else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif ! Get the Array call ESMF_GridGetCoordIntoArray(grid, coordDim, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDE=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetCoordBounds(grid, localDE, coordDim, tmp_staggerloc, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetCoord1DR8 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetCoord2DR8" !BOPI ! !IROUTINE: ESMF_GridGetCoord - Get pointer to 2DR8 coordinates ! !INTERFACE: ! Private name; call using ESMF_GridGetCoord() subroutine ESMF_GridGetCoord2DR8(grid, coordDim, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: coordDim type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in),optional :: staggerloc integer, intent(in),optional :: localDE real(ESMF_KIND_R8), pointer :: farrayPtr(:,:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! coordinate data for the given coordinate and stagger locations on the given local DE. ! This is useful, for example, for setting the coordinate values in a Grid, or ! for reading the coordinate values. Eventually this method will be overloaded ! for the full range of ESMF supported types and dimensions. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{coordDim}] ! The coordinate dimension to get the data from (e.g. 1=x). ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{[localDE]}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the coordinate data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid coordinate arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localarray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc type(ESMF_GridDecompType) :: decompType ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Check consistency call ESMF_GridGet(grid, coordTypeKind=typekind, dimCount=dimCount, coordDimCount=coordDimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr typekind to match Grid typekind if (typekind /= ESMF_TYPEKIND_R8) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr typekind does not match Grid typekind", & ESMF_CONTEXT, rcToReturn=rc) return endif ! make sure coord is legitimate if ((coordDim .lt. 1) .or. (coordDim > dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- coordinate dimension outside of range specified for this Grid", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Require farrayPtr dimCount to match coordinate dimCount if (coordDimCount(coordDim) /= 2) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested coordinate dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then if ((decompType == ESMF_GRID_ARBITRARY) .and. & (staggerloc /= ESMF_STAGGERLOC_CENTER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return else tmp_staggerloc=staggerloc%staggerloc endif else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif ! Get the Array call ESMF_GridGetCoordIntoArray(grid, coordDim, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDE=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetCoordBounds(grid, localDE, coordDim, tmp_staggerloc, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetCoord2DR8 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetCoord3DR8" !BOPI ! !IROUTINE: ESMF_GridGetCoord - Get pointer to 3DR8 coordinates ! !INTERFACE: ! Private name; call using ESMF_GridGetCoord() subroutine ESMF_GridGetCoord3DR8(grid, coordDim, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: coordDim type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in),optional :: staggerloc integer, intent(in),optional :: localDE real(ESMF_KIND_R8), pointer :: farrayPtr(:,:,:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! coordinate data for the given coordinate and stagger locations on the given local DE. ! This is useful, for example, for setting the coordinate values in a Grid, or ! for reading the coordinate values. Eventually this method will be overloaded ! for the full range of ESMF supported types and dimensions. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{coordDim}] ! The coordinate dimension to get the data from (e.g. 1=x). ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{[localDE]}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the coordinate data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid coordinate arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localarray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc type(ESMF_GridDecompType) :: decompType ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Check consistency call ESMF_GridGet(grid, coordTypeKind=typekind, dimCount=dimCount, coordDimCount=coordDimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr typekind to match Grid typekind if (typekind /= ESMF_TYPEKIND_R8) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr typekind does not match Grid typekind", & ESMF_CONTEXT, rcToReturn=rc) return endif ! make sure coord is legitimate if ((coordDim .lt. 1) .or. (coordDim > dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- coordinate dimension outside of range specified for this Grid", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Require farrayPtr dimCount to match coordinate dimCount if (coordDimCount(coordDim) /= 3) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested coordinate dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then if ((decompType == ESMF_GRID_ARBITRARY) .and. & (staggerloc /= ESMF_STAGGERLOC_CENTER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return else tmp_staggerloc=staggerloc%staggerloc endif else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif ! Get the Array call ESMF_GridGetCoordIntoArray(grid, coordDim, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDE=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetCoordBounds(grid, localDE, coordDim, tmp_staggerloc, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetCoord3DR8 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetCoordIntoArray" !BOP ! !IROUTINE: ESMF_GridGetCoord - Get coordinates and put in an Array ! !INTERFACE: ! Private name; call using ESMF_GridGetCoord() subroutine ESMF_GridGetCoordIntoArray(grid, coordDim, staggerloc, & array, keywordEnforcer, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: coordDim type (ESMF_StaggerLoc), intent(in), optional :: staggerloc type(ESMF_Array), intent(out) :: array type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This method allows the user to get access to the ESMF Array holding ! coordinate data at a particular stagger location. This is useful, for example, ! to set the coordinate values. To have an Array to access, the coordinate Arrays ! must have already been allocated, for example by {\tt ESMF\_GridAddCoord} or ! {\tt ESMF\_GridSetCoord}. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! The grid to get the coord array from. ! \item[{coordDim}] ! The coordinate dimension to get the data from (e.g. 1=x). ! \item[{staggerloc}] ! The stagger location from which to get the arrays. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! \item[{array}] ! An array into which to put the coordinate infomation. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP integer :: tmp_staggerloc integer :: localrc ! local error status type(ESMF_GridDecompType) :: decompType type(ESMF_DataCopy_Flag) :: datacopyflag ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! handle staggerloc if (present(staggerloc)) then if ((decompType == ESMF_GRID_ARBITRARY) .and. & (staggerloc /= ESMF_STAGGERLOC_CENTER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return else tmp_staggerloc=staggerloc%staggerloc endif else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif ! Init datacopyflag datacopyflag=ESMF_DATACOPY_REFERENCE ! Call C++ Subroutine to do the create call c_ESMC_gridgetcoordintoarray(grid%this,tmp_staggerloc, coordDim, & array, datacopyflag, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set Array as created call ESMF_ArraySetInitCreated(array,localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetCoordIntoArray !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetCoordR4" !BOP ! !IROUTINE: ESMF_GridGetCoord - Get coordinates from a specific index location ! !INTERFACE: ! Private name; call using ESMF_GridGetCoord() subroutine ESMF_GridGetCoordR4(grid, staggerloc, localDe, & index, coord, keywordEnforcer, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: localDE integer, intent(in) :: index(:) real(ESMF_KIND_R4), intent(out) :: coord(:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! Given a specific index location in a Grid, this method returns the full set ! of coordinates from that index location. This method will eventually be overloaded ! to support the full complement of types supported by the Grid. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{[localDE]}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{index}] ! This array holds the index location to be queried in the Grid. This array must ! at least be of the size Grid rank. ! \item[{coord}] ! This array will be filled with the coordinate data. This array must ! at least be of the size Grid rank. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables integer :: localrc integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Have default option for staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! NOTE THERE IS NO INPUT VALUE CHECKING HERE BECAUSE IT'S DONE IN ! THE C++ VERSION. ! Call into the C++ interface call c_esmc_gridgetcoordr4(grid, localDE, tmp_staggerloc, & index, coord, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetCoordR4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetCoordR8" !BOP ! !IROUTINE: ESMF_GridGetCoord - Get coordinates from a specific index location ! !INTERFACE: ! Private name; call using ESMF_GridGetCoord() subroutine ESMF_GridGetCoordR8(grid, staggerloc, localDE, & index, coord, keywordEnforcer, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: localDE integer, intent(in) :: index(:) real(ESMF_KIND_R8), intent(out) :: coord(:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! Given a specific index location in a Grid, this method returns the full set ! of coordinates from that index location. This method will eventually be overloaded ! to support the full complement of types supported by the Grid. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{[localDE]}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{index}] ! This array holds the index location to be queried in the Grid. This array must ! at least be of the size Grid rank. ! \item[{coord}] ! This array will be filled with the coordinate data. This array must ! at least be of the size Grid rank. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables integer :: localrc integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Have default option for staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! NOTE THERE IS NO INPUT VALUE CHECKING HERE BECAUSE IT'S DONE IN ! THE C++ VERSION. ! Call into the C++ interface call c_esmc_gridgetcoordr8(grid, localDE, tmp_staggerloc, & index, coord, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetCoordR8 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetCoordBounds" !BOP ! !IROUTINE: ESMF_GridGetCoordBounds - Get Grid coordinate bounds ! !INTERFACE: subroutine ESMF_GridGetCoordBounds(grid, coordDim, keywordEnforcer, & staggerloc, localDE, exclusiveLBound, exclusiveUBound, & exclusiveCount, computationalLBound, computationalUBound , & computationalCount, totalLBound, totalUBound, totalCount, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: coordDim type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: localDE integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This method gets information about the range of index space which a particular ! piece of coordinate data occupies. In other words, this method returns the ! bounds of the coordinate arrays. Note that unlike the output from the ! Array, these values also include the undistributed dimensions and are ! ordered to reflect the order of the indices in the coordinate. So, for example, ! {\tt totalLBound} and {\tt totalUBound} should match the bounds of the Fortran array ! retrieved by {\tt ESMF\_GridGetCoord}. ! !The arguments are: !\begin{description} !\item[{grid}] ! Grid to get the information from. !\item[{coordDim}] ! The coordinate dimension to get the information for (e.g. 1=x). !\item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. !\item[{[localDE]}] ! The local DE from which to get the information. {\tt [0,..,localDeCount-1]} !\item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[exclusiveCount]}] ! Upon return this holds the number of items, {\tt exclusiveUBound-exclusiveLBound+1}, ! in the exclusive region per dimension. ! {\tt exclusiveCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt computationalUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[totalCount]}] ! \begin{sloppypar} ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the coord dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \end{sloppypar} !\item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. !\end{description} ! !EOP integer :: localrc ! local error status type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetCoordBounds(grid, localDE, coordDim, tmp_staggerloc, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetCoordBounds !------------------------------------------------------------------------------ !BOP ! !IROUTINE: ESMF_GridGetItem - Get a Fortran pointer to Grid item data and item bounds ! !INTERFACE: ! subroutine ESMF_GridGetItem(grid, itemflag, keywordEnforcer, & ! staggerloc, localDE, , ! exclusiveLBound, exclusiveUBound, exclusiveCount, & ! computationalLBound, computationalUBound, computationalCount, & ! totalLBound, totalUBound, totalCount, & ! datacopyflag, rc) ! ! !ARGUMENTS: ! type(ESMF_Grid), intent(in) :: grid ! type (ESMF_GridItem_Flag),intent(in) :: itemflag !type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below ! type (ESMF_StaggerLoc), intent(in), optional :: staggerloc ! integer, intent(in), optional :: localDE ! , see below for supported values ! integer, intent(out), optional :: exclusiveLBound(:) ! integer, intent(out), optional :: exclusiveUBound(:) ! integer, intent(out), optional :: exclusiveCount(:) ! integer, intent(out), optional :: computationalLBound(:) ! integer, intent(out), optional :: computationalUBound(:) ! integer, intent(out), optional :: computationalCount(:) ! integer, intent(out), optional :: totalLBound(:) ! integer, intent(out), optional :: totalUBound(:) ! integer, intent(out), optional :: totalCount(:) ! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag ! integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! item data on the local DE for the given stagger locations. ! This is useful, for example, for setting the item values in a Grid, or ! for reading the item values. Currently this method supports up to three ! grid dimensions, but is limited to the I4 datatype. See below for specific ! supported values. If the item values that you are trying to retrieve are of ! higher dimension, use the {\tt ESMF\_GetItem()} interface that returns coordinate ! values in an {\tt ESMF\_Array} instead. That interface supports the retrieval of ! coordinates up to 7D. ! ! Supported values for the are: ! \begin{description} ! \item integer(ESMF\_KIND\_I4), pointer :: farrayPtr(:) ! \item integer(ESMF\_KIND\_I4), pointer :: farrayPtr(:,:) ! \item integer(ESMF\_KIND\_I4), pointer :: farrayPtr(:,:,:) ! \item real(ESMF\_KIND\_R4), pointer :: farrayPtr(:) ! \item real(ESMF\_KIND\_R4), pointer :: farrayPtr(:,:) ! \item real(ESMF\_KIND\_R4), pointer :: farrayPtr(:,:,:) ! \item real(ESMF\_KIND\_R8), pointer :: farrayPtr(:) ! \item real(ESMF\_KIND\_R8), pointer :: farrayPtr(:,:) ! \item real(ESMF\_KIND\_R8), pointer :: farrayPtr(:,:,:) ! \end{description} ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{itemflag}] ! The item to get the information for. Please see Section~\ref{const:griditem} for a ! list of valid items. ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! \item[{localDE}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the item data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the grid dimCount. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the grid dimCount. ! \item[{[exclusiveCount]}] ! \begin{sloppypar} ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \end{sloppypar} ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! \begin{sloppypar} ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the grid dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \end{sloppypar} ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid item arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetItem1DI4" !BOPI ! !IROUTINE: ESMF_GridGetItem - Get pointer to 1DI4 coordinates ! !INTERFACE: ! Private name; call using ESMF_GridGetItem() subroutine ESMF_GridGetItem1DI4(grid, itemflag, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: localDE integer(ESMF_KIND_I4), pointer :: farrayPtr(:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! item data for the stagger locations on the given local DE. ! This is useful, for example, for setting the item values in a Grid, or ! for reading the item values. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{itemflag}] ! The item to get the information for. Please see Section~\ref{const:griditem} for a ! list of valid items. ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! \item[{localDE}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the item data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid item arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localArray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Check consistency call ESMF_GridGet(grid, dimCount=dimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr dimCount to match grid dimCount if (dimCount /= 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested item dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! Get the Array call ESMF_GridGetItemIntoArray(grid, itemflag, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDE=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetItemBounds(grid, localDE, tmp_staggerloc, itemflag, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetItem1DI4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetItem2DI4" !BOPI ! !IROUTINE: ESMF_GridGetItem - Get pointer to 2DI4 item ! !INTERFACE: ! Private name; call using ESMF_GridGetItem() subroutine ESMF_GridGetItem2DI4(grid, itemflag, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: localDE integer(ESMF_KIND_I4), pointer :: farrayPtr(:,:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! item data for the stagger locations on the given local DE. ! This is useful, for example, for setting the item values in a Grid, or ! for reading the item values. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{itemflag}] ! The item to get the information for. Please see Section~\ref{const:griditem} for a ! list of valid items. ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{localDE}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the item data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid item arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localArray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Check consistency call ESMF_GridGet(grid, dimCount=dimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr dimCount to match grid dimCount if (dimCount /= 2) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested item dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! Get the Array call ESMF_GridGetItemIntoArray(grid, itemflag, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDE=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetItemBounds(grid, localDE, tmp_staggerloc, itemflag, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetItem2DI4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetItem3DI4" !BOPI ! !IROUTINE: ESMF_GridGetItem - Get pointer to 3DI4 item ! !INTERFACE: ! Private name; call using ESMF_GridGetItem() subroutine ESMF_GridGetItem3DI4(grid, itemflag, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: localDE integer(ESMF_KIND_I4), pointer :: farrayPtr(:,:,:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! maks data and stagger locations on the given local DE. ! This is useful, for example, for setting the item values in a Grid, or ! for reading the item values. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{itemflag}] ! The item to get the information for. Please see Section~\ref{const:griditem} for a ! list of valid items. ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{localDE}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the item data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid item arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localArray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Check consistency call ESMF_GridGet(grid, dimCount=dimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr dimCount to match coordinate dimCount if (dimCount /= 3) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested item dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! Get the Array call ESMF_GridGetItemIntoArray(grid, itemflag, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDe=localDe, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetItemBounds(grid, localDE, tmp_staggerloc, itemflag, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetItem3DI4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetItem1DR4" !BOPI ! !IROUTINE: ESMF_GridGetItem - Get pointer to 1DR4 coordinates ! !INTERFACE: ! Private name; call using ESMF_GridGetItem() subroutine ESMF_GridGetItem1DR4(grid, itemflag, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: localDE real(ESMF_KIND_R4), pointer :: farrayPtr(:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! item data for the stagger locations on the given local DE. ! This is useful, for example, for setting the item values in a Grid, or ! for reading the item values. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{itemflag}] ! The item to get the information for. Please see Section~\ref{const:griditem} for a ! list of valid items. ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! \item[{localDE}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the item data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid item arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray):: localarray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Check consistency call ESMF_GridGet(grid, dimCount=dimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr dimCount to match grid dimCount if (dimCount /= 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested item dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! Get the Array call ESMF_GridGetItemIntoArray(grid, itemflag, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDe=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetItemBounds(grid, localDE, tmp_staggerloc, itemflag, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetItem1DR4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetItem2DR4" !BOPI ! !IROUTINE: ESMF_GridGetItem - Get pointer to 2DR4 item ! !INTERFACE: ! Private name; call using ESMF_GridGetItem() subroutine ESMF_GridGetItem2DR4(grid, itemflag, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: localDE real(ESMF_KIND_R4), pointer :: farrayPtr(:,:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! item data for the stagger locations on the given local DE. ! This is useful, for example, for setting the item values in a Grid, or ! for reading the item values. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{itemflag}] ! The item to get the information for. Please see Section~\ref{const:griditem} for a ! list of valid items. ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{localDE}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the item data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid item arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: localDeCount, dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localarray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Check consistency call ESMF_GridGet(grid, dimCount=dimCount, & localDECount=localDECount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr dimCount to match grid dimCount if (dimCount /= 2) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested item dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! Get the Array call ESMF_GridGetItemIntoArray(grid, itemflag, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDE=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetItemBounds(grid, localDE, tmp_staggerloc, itemflag, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetItem2DR4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetItem3DR4" !BOPI ! !IROUTINE: ESMF_GridGetItem - Get pointer to 3DR4 item ! !INTERFACE: ! Private name; call using ESMF_GridGetItem() subroutine ESMF_GridGetItem3DR4(grid, itemflag, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in),optional :: localDE real(ESMF_KIND_R4), pointer :: farrayPtr(:,:,:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! maks data and stagger locations on the given local DE. ! This is useful, for example, for setting the item values in a Grid, or ! for reading the item values. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{itemflag}] ! The item to get the information for. Please see Section~\ref{const:griditem} for a ! list of valid items. ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{localDE}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the item data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid item arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localArray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Check consistency call ESMF_GridGet(grid, dimCount=dimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr dimCount to match coordinate dimCount if (dimCount /= 3) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested item dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! Get the Array call ESMF_GridGetItemIntoArray(grid, itemflag, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetItemBounds(grid, localDE, tmp_staggerloc, itemflag, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetItem3DR4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetItem1DR8" !BOPI ! !IROUTINE: ESMF_GridGetItem - Get pointer to 1DR8 coordinates ! !INTERFACE: ! Private name; call using ESMF_GridGetItem() subroutine ESMF_GridGetItem1DR8(grid, itemflag, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in),optional :: localDE real(ESMF_KIND_R8), pointer :: farrayPtr(:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! item data for the stagger locations on the given local DE. ! This is useful, for example, for setting the item values in a Grid, or ! for reading the item values. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{itemflag}] ! The item to get the information for. Please see Section~\ref{const:griditem} for a ! list of valid items. ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! \item[{localDE}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{farrayPtr}] ! The pointer to the item data. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid item arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localArray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Check consistency call ESMF_GridGet(grid, dimCount=dimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr dimCount to match grid dimCount if (dimCount /= 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested item dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! Get the Array call ESMF_GridGetItemIntoArray(grid, itemflag, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetItemBounds(grid, localDE, tmp_staggerloc, itemflag, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetItem1DR8 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetItem2DR8" !BOPI ! !IROUTINE: ESMF_GridGetItem - Get pointer to 2DR8 item ! !INTERFACE: ! Private name; call using ESMF_GridGetItem() subroutine ESMF_GridGetItem2DR8(grid, itemflag, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in),optional :: localDE real(ESMF_KIND_R8), pointer :: farrayPtr(:,:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! item data for the stagger locations on the given local DE. ! This is useful, for example, for setting the item values in a Grid, or ! for reading the item values. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{itemflag}] ! The item to get the information for. Please see Section~\ref{const:griditem} for a ! list of valid items. ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{localDE}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the item data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid item arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localarray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Check consistency call ESMF_GridGet(grid, dimCount=dimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr dimCount to match grid dimCount if (dimCount /= 2) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested item dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! Get the Array call ESMF_GridGetItemIntoArray(grid, itemflag, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDE=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetItemBounds(grid, localDE, tmp_staggerloc, itemflag, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetItem2DR8 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetItem3DR8" !BOPI ! !IROUTINE: ESMF_GridGetItem - Get pointer to 3DR8 item ! !INTERFACE: ! Private name; call using ESMF_GridGetItem() subroutine ESMF_GridGetItem3DR8(grid, itemflag, keywordEnforcer, & staggerloc, localDE, farrayPtr, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, & datacopyflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in),optional :: localDE real(ESMF_KIND_R8), pointer :: farrayPtr(:,:,:) integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This method gets a Fortran pointer to the piece of memory which holds the ! maks data and stagger locations on the given local DE. ! This is useful, for example, for setting the item values in a Grid, or ! for reading the item values. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Grid to get the information from. ! \item[{itemflag}] ! The item to get the information for. Please see Section~\ref{const:griditem} for a ! list of valid items. ! \item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! \item[{localDE}] ! The local DE to get the information for. {\tt [0,..,localDeCount-1]} ! \item[{farrayPtr}] ! The pointer to the item data. ! \item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[exclusiveCount]}] ! Upon return this holds the number of items in the exclusive region per dimension ! (i.e. {\tt exclusiveUBound-exclusiveLBound+1}). {\tt exclusiveCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[totalCount]}] ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \item[{[datacopyflag]}] ! If not specified, default to {\tt ESMF\_DATACOPY\_REFERENCE}, in this case ! farrayPtr is a reference to the data in the Grid item arrays. ! Please see Section~\ref{const:datacopyflag} for further description and a ! list of valid values. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI ! Local variables type(ESMF_Array) :: array integer :: localrc ! local error status integer :: dimCount type(ESMF_TypeKind_Flag) :: typekind type(ESMF_LocalArray) :: localarray type(ESMF_DataCopy_Flag) :: datacopyflagInt integer :: coordDimCount(ESMF_MAXDIM) type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Check consistency call ESMF_GridGet(grid, dimCount=dimCount, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Require farrayPtr dimCount to match coordinate dimCount if (dimCount /= 3) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- farrayPtr dimCount does not match requested item dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set Defaults if (present(datacopyflag)) then datacopyflagInt=datacopyflag else datacopyflagInt=ESMF_DATACOPY_REFERENCE endif !! localDE is error checked inside ESMF_ArrayGet() and GetCoordBounds(), so don't do it here !! ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! Get the Array call ESMF_GridGetItemIntoArray(grid, itemflag, staggerloc, array, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(array, localDe=localDE, localarray=localarray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_LocalArrayGet(localarray, farrayPtr, & datacopyflag=datacopyflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetItemBounds(grid, localDE, tmp_staggerloc, itemflag, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetItem3DR8 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetItemIntoArray" !BOP ! !IROUTINE: ESMF_GridGetItem - Get item and put into an Array ! !INTERFACE: ! Private name; call using ESMF_GridGetItem() subroutine ESMF_GridGetItemIntoArray(grid, itemflag, staggerloc, & array, keywordEnforcer, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type (ESMF_StaggerLoc), intent(in), optional :: staggerloc type(ESMF_Array), intent(out) :: array type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This method allows the user to get access to the ESMF Array holding ! item data at a particular stagger location. This is useful, for example, ! to set the item values. To have an Array to access, the item Array ! must have already been allocated, for example by {\tt ESMF\_GridAddItem} or ! {\tt ESMF\_GridSetItem}. ! ! The arguments are: ! \begin{description} ! \item[{itemflag}] ! The item from which to get the arrays. Please see Section~\ref{const:griditem} for a ! list of valid items. ! \item[{staggerloc}] ! The stagger location from which to get the arrays. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! \item[{array}] ! An array into which to put the item infomation. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP integer :: tmp_staggerloc integer :: localrc ! local error status type(ESMF_DataCopy_Flag) :: datacopyflag ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif ! Init datacopyflag datacopyflag=ESMF_DATACOPY_REFERENCE ! Call C++ Subroutine call c_ESMC_gridgetitemintoarray(grid%this,tmp_staggerloc, itemflag, & array, datacopyflag, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set Array as created call ESMF_ArraySetInitCreated(array,localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetItemIntoArray !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetItemBounds" !BOP ! !IROUTINE: ESMF_GridGetItemBounds - Get Grid item bounds ! !INTERFACE: subroutine ESMF_GridGetItemBounds(grid, itemflag, keywordEnforcer, & staggerloc, localDE, & exclusiveLBound, exclusiveUBound, exclusiveCount, & computationalLBound, computationalUBound, computationalCount, & totalLBound, totalUBound, totalCount, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type (ESMF_StaggerLoc), intent(in), optional :: staggerloc integer, intent(in), optional :: localDE integer, target, intent(out), optional :: exclusiveLBound(:) integer, target, intent(out), optional :: exclusiveUBound(:) integer, target, intent(out), optional :: exclusiveCount(:) integer, target, intent(out), optional :: computationalLBound(:) integer, target, intent(out), optional :: computationalUBound(:) integer, target, intent(out), optional :: computationalCount(:) integer, target, intent(out), optional :: totalLBound(:) integer, target, intent(out), optional :: totalUBound(:) integer, target, intent(out), optional :: totalCount(:) integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This method gets information about the range of index space which a particular ! piece of item data occupies. In other words, this method returns the ! bounds of the item arrays. Note that unlike the output from the ! Array, these values also include the undistributed dimensions and are ! ordered to reflect the order of the indices in the item. So, for example, ! {\tt totalLBound} and {\tt totalUBound} should match the bounds of the Fortran array ! retrieved by {\tt ESMF\_GridGetItem}. ! !The arguments are: !\begin{description} !\item[{grid}] ! Grid to get the information from. !\item[{itemflag}] ! The item to get the information for. Please see Section~\ref{const:griditem} for a ! list of valid items. !\item[{staggerloc}] ! The stagger location to get the information for. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. !\item[{localDE}] ! The local DE from which to get the information. {\tt [0,..,localDeCount-1]} !\item[{[exclusiveLBound]}] ! Upon return this holds the lower bounds of the exclusive region. ! {\tt exclusiveLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[exclusiveUBound]}] ! Upon return this holds the upper bounds of the exclusive region. ! {\tt exclusiveUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[exclusiveCount]}] ! Upon return this holds the number of items, {\tt exclusiveUBound-exclusiveLBound+1}, ! in the exclusive region per dimension. ! {\tt exclusiveCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[computationalLBound]}] ! Upon return this holds the lower bounds of the stagger region. ! {\tt computationalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[computationalUBound]}] ! Upon return this holds the upper bounds of the stagger region. ! {\tt computationalUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[computationalCount]}] ! Upon return this holds the number of items in the computational region per dimension ! (i.e. {\tt computationalUBound-computationalLBound+1}). {\tt computationalCount} ! must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[totalLBound]}] ! Upon return this holds the lower bounds of the total region. ! {\tt totalLBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[totalUBound]}] ! Upon return this holds the upper bounds of the total region. ! {\tt totalUBound} must be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. !\item[{[totalCount]}] ! \begin{sloppypar} ! Upon return this holds the number of items in the total region per dimension ! (i.e. {\tt totalUBound-totalLBound+1}). {\tt totalCount} must ! be allocated to be of size equal to the item dimCount. ! Please see Section~\ref{sec:grid:usage:bounds} for a description ! of the regions and their associated bounds and counts. ! \end{sloppypar} !\item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. !\end{description} ! !EOP integer :: localrc ! local error status type(ESMF_InterfaceInt) :: exclusiveLBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveUBoundArg ! helper variable type(ESMF_InterfaceInt) :: exclusiveCountArg ! helper variable type(ESMF_InterfaceInt) :: computationalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: computationalCountArg ! helper variable type(ESMF_InterfaceInt) :: totalLBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalUBoundArg ! helper variable type(ESMF_InterfaceInt) :: totalCountArg ! helper variable integer :: tmp_staggerloc ! Initialize return code localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! handle staggerloc if (present(staggerloc)) then tmp_staggerloc=staggerloc%staggerloc else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc ! default endif ! process optional arguments exclusiveLBoundArg=ESMF_InterfaceIntCreate(exclusiveLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveUBoundArg=ESMF_InterfaceIntCreate(exclusiveUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return exclusiveCountArg=ESMF_InterfaceIntCreate(exclusiveCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalLBoundArg=ESMF_InterfaceIntCreate(computationalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalUBoundArg=ESMF_InterfaceIntCreate(computationalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return computationalCountArg=ESMF_InterfaceIntCreate(computationalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalLBoundArg=ESMF_InterfaceIntCreate(totalLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalUBoundArg = ESMF_InterfaceIntCreate(totalUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return totalCountArg = ESMF_InterfaceIntCreate(totalCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call into the C++ interface, which will sort out optional arguments call c_ESMC_GridGetItemBounds(grid, localDE, tmp_staggerloc, itemflag, & exclusiveLBoundArg, exclusiveUBoundArg, exclusiveCountArg, & computationalLBoundArg, computationalUBoundArg, computationalCountArg,& totalLBoundArg, totalUBoundArg, totalCountArg, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate interface ints call ESMF_InterfaceIntDestroy(exclusiveLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(exclusiveCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(computationalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalUBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(totalCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridGetItemBounds !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridSerialize" !BOPI ! !IROUTINE: ESMF_GridSerialize - Serialize grid info into a byte stream ! ! !INTERFACE: subroutine ESMF_GridSerialize(grid, buffer, length, offset, & attreconflag, inquireflag, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(inout) :: grid character, pointer, dimension(:) :: buffer integer, intent(inout) :: length integer, intent(inout) :: offset type(ESMF_AttReconcileFlag), intent(in), optional :: attreconflag type(ESMF_InquireFlag), intent(in), optional :: inquireflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! Takes an {\tt ESMF\_Grid} object and adds all the information needed ! to recreate the object based on this information. ! Expected to be used by {\tt ESMF\_StateReconcile()}. ! ! The arguments are: ! \begin{description} ! \item [grid] ! {\tt ESMF\_Grid} object to be serialized. ! \item [buffer] ! Data buffer which will hold the serialized information. ! \item [length] ! Current length of buffer, in bytes. If the serialization ! process needs more space it will allocate it and update ! this length. ! \item [offset] ! Current write offset in the current buffer. This will be ! updated by this routine and return pointing to the next ! available byte in the buffer. ! \item[{[attreconflag]}] ! Flag to tell if Attribute serialization is to be done ! \item[{[inquireflag]}] ! Flag to tell if serialization is to be done (ESMF_NOINQUIRE) ! or if this is simply a size inquiry (ESMF_INQUIREONLY) ! \item [{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc type(ESMF_AttReconcileFlag) :: lattreconflag type(ESMF_InquireFlag) :: linquireflag ! Initialize localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! check variables ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit,grid,rc) ! deal with optional attreconflag and inquireflag if (present(attreconflag)) then lattreconflag = attreconflag else lattreconflag = ESMF_ATTRECONCILE_OFF endif if (present (inquireflag)) then linquireflag = inquireflag else linquireflag = ESMF_NOINQUIRE end if call c_ESMC_GridSerialize(grid, buffer, length, offset, & lattreconflag, linquireflag, localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! return success if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridSerialize !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridDeserialize" !BOPI ! !IROUTINE: ESMF_GridDeserialize - Deserialize a byte stream into a Grid ! ! !INTERFACE: function ESMF_GridDeserialize(buffer, offset, & attreconflag, rc) ! ! !RETURN VALUE: type(ESMF_Grid) :: ESMF_GridDeserialize ! ! !ARGUMENTS: character, pointer, dimension(:) :: buffer integer, intent(inout) :: offset type(ESMF_AttReconcileFlag), optional :: attreconflag integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! Takes a byte-stream buffer and reads the information needed to ! recreate a Grid object. Recursively calls the deserialize routines ! needed to recreate the subobjects. ! Expected to be used by {\tt ESMF\_StateReconcile()}. ! ! The arguments are: ! \begin{description} ! \item [buffer] ! Data buffer which holds the serialized information. ! \item [offset] ! Current read offset in the current buffer. This will be ! updated by this routine and return pointing to the next ! unread byte in the buffer. ! \item[{[attreconflag]}] ! Flag to tell if Attribute serialization is to be done ! \item [{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc type(ESMF_Grid) :: grid type(ESMF_AttReconcileFlag) :: lattreconflag ! Initialize localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! deal with optional attreconflag if (present(attreconflag)) then lattreconflag = attreconflag else lattreconflag = ESMF_ATTRECONCILE_OFF endif ! Call into C++ to Deserialize the Grid call c_ESMC_GridDeserialize(grid%this, buffer, offset, & lattreconflag, localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set return value ESMF_GridDeserialize = grid ! Set init status ESMF_INIT_SET_CREATED(ESMF_GridDeserialize) if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridDeserialize ! -------------------------- ESMF-public method ------------------------------- #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridMatch()" !BOP ! !IROUTINE: ESMF_GridMatch - Check if two Grid objects match ! !INTERFACE: function ESMF_GridMatch(grid1, grid2, keywordEnforcer, rc) ! ! !RETURN VALUE: type(ESMF_GridMatch_Flag) :: ESMF_GridMatch ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid1 type(ESMF_Grid), intent(in) :: grid2 type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! ! ! !DESCRIPTION: ! Check if {\tt grid1} and {\tt grid2} match. Returns a range of values of type ! ESMF\_GridMatch indicating how closely the Grids match. For a description of ! the possible return values, please see~\ref{const:gridmatch}. ! Please also note that this call returns the match for the piece of the Grids on ! the local PET only. It's entirely possible for this call to return a different match ! on different PETs for the same Grids. The user is responsible for computing the ! global match across the set of PETs. ! ! The arguments are: ! \begin{description} ! \item[grid1] ! {\tt ESMF\_Grid} object. ! \item[grid2] ! {\tt ESMF\_Grid} object. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP !------------------------------------------------------------------------------ integer :: localrc ! local return code integer :: matchResult ! initialize return code; assume routine not implemented localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! init to one setting in case of error ESMF_GridMatch = ESMF_GRIDMATCH_INVALID ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid1, rc) ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid2, rc) ! Check for alias if (grid1%this==grid2%this) then ESMF_GridMatch = ESMF_GRIDMATCH_ALIAS if (present(rc)) rc = ESMF_SUCCESS return endif ! Call into the C++ interface, which will sort out optional arguments. call c_ESMC_GridMatch(grid1, grid2, matchResult, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! return successfully if (matchResult == 1) then ESMF_GridMatch = ESMF_GRIDMATCH_EXACT else ESMF_GridMatch = ESMF_GRIDMATCH_NONE endif if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridMatch !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridSetFromDistGrid" !BOPI ! !IROUTINE: ESMF_GridSet - Set the values in a Grid which has been created with EmptyCreate ! !INTERFACE: ! Private name; call using ESMF_GridSet() subroutine ESMF_GridSetFromDistGrid(grid, keywordEnforcer, & distgrid,distgridToGridMap, distDim, & coordSys, coordTypeKind, coordDimCount, coordDimMap, & minIndex, maxIndex, & localArbIndexCount, localArbIndex, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, gridMemLBound, & indexflag, destroyDistgrid, destroyDELayout, name, rc) ! ! !RETURN VALUE: ! ! !ARGUMENTS: type(ESMF_Grid), intent(inout) :: grid type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_DistGrid), intent(in), optional :: distgrid integer, intent(in), optional :: distgridToGridMap(:) integer, intent(in), optional :: distDim(:) type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: coordDimCount(:) integer, intent(in), optional :: coordDimMap(:,:) integer, intent(in), optional :: minIndex(:) integer, intent(in), optional :: maxIndex(:) integer, intent(in), optional :: localArbIndexCount integer, intent(in), optional :: localArbIndex(:,:) integer, intent(in), optional :: gridEdgeLWidth(:) integer, intent(in), optional :: gridEdgeUWidth(:) integer, intent(in), optional :: gridAlign(:) integer, intent(in), optional :: gridMemLBound(:) type(ESMF_Index_Flag), intent(in), optional :: indexflag logical, intent(in), optional :: destroyDistgrid logical, intent(in), optional :: destroyDELayout character (len=*), intent(in), optional :: name integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! Set values in a grid in preparation for committing and creating a grid. This method ! is called between {\tt ESMF\_GridEmptyCreate} and {\tt ESMF\_GridCommit}. Note that ! once a grid is committed and created it's an error to try to set values in it. Note also ! that new values overwrite old values if previously set. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! Partially created Grid to set information into. ! \item[distgrid] ! {\tt ESMF\_DistGrid} object that describes how the array is decomposed and ! distributed over DEs. ! \item[{[distgridToGridMap]}] ! List that has as dimCount elements. ! The elements map each dimension of distgrid to a dimension in the grid. ! (i.e. the values should range from 1 to dimCount). If not specified, the default ! is to map all of distgrid's dimensions against the dimensions of the ! grid in sequence. ! \item[{[coordSys]}] ! The coordinate system of the grid coordinate data. ! For a full list of options, please see Section~\ref{const:coordsys}. ! If not specified then defaults to ESMF\_COORDSYS\_SPH\_DEG. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[minIndex]}] ! Tuple to start the index ranges at. If not present, defaults ! to /1,1,1,.../. ! \item[{[maxIndex]}] ! The upper extend of the grid index ranges. ! \item[{[localArbIndex]}] ! This 2D array specifies the indices of the local grid cells. The ! dimensions should be localArbIndexCount * number of grid dimensions ! where localArbIndexCount is the input argument specified below ! \item[{localArbIndexCount}] ! number of grid cells in the local DE ! \item[{[gridEdgeLWidth]}] ! The padding around the lower edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. ! \item[{[gridEdgeUWidth]}] ! The padding around the upper edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. ! \item[{[gridAlign]}] ! Specification of how the stagger locations should align with the cell ! index space (can be overridden by the individual staggerAligns). If ! the {\tt gridEdgeWidths} are not specified than this parameter ! implies the EdgeWidths. ! \item[{[gridMemLBound]}] ! Specifies the lower index range of the memory of every DE in this Grid. ! Only used when indexflag is {\tt ESMF\_INDEX\_USER}. May be overridden ! by staggerMemLBound. ! \item[{[indexflag]}] ! Indicates the indexing scheme to be used in the new Grid. Please see ! Section~\ref{const:indexflag} for the list of options. If not present, ! defaults to ESMF\_INDEX\_DELOCAL. ! \item[{[destroyDistgrid]}] ! If true, when the Grid is destroyed the DistGrid will be destroyed also. ! Defaults to false. ! \item[{[destroyDELayout]}] ! If true, when the Grid is destroyed the DELayout will be destroyed also. ! Defaults to false. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc ! local error status integer :: nameLen type(ESMF_InterfaceInt) :: gridEdgeLWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: gridEdgeUWidthArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: gridAlignArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: gridMemLBoundArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: distgridToGridMapArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: distDimArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: coordDimCountArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: coordDimMapArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: minIndexArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: maxIndexArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: localArbIndexArg ! Language Interface Helper Var integer :: intDestroyDistgrid,intDestroyDELayout ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_DistGridGetInit, distgrid, rc) ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) ! Translate F90 arguments to C++ friendly form !! name nameLen=0 if (present(name)) then nameLen=len_trim(name) endif !! coordTypeKind ! It doesn't look like it needs to be translated, but test to make sure !! gridEdgeLWidth and gridEdgeUWidth gridEdgeLWidthArg = ESMF_InterfaceIntCreate(gridEdgeLWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return gridEdgeUWidthArg = ESMF_InterfaceIntCreate(gridEdgeUWidth, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return gridAlignArg = ESMF_InterfaceIntCreate(gridAlign, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return gridMemLBoundArg = ESMF_InterfaceIntCreate(gridMemLBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! distgridToGridMap distgridToGridMapArg = ESMF_InterfaceIntCreate(distgridToGridMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! distDim distDimArg = ESMF_InterfaceIntCreate(distDim, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Description of array factorization coordDimCountArg = ESMF_InterfaceIntCreate(coordDimCount, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return coordDimMapArg = ESMF_InterfaceIntCreate(farray2D=coordDimMap, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Index bound and localArbIndex array minIndexArg = ESMF_InterfaceIntCreate(minIndex, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexArg = ESMF_InterfaceIntCreate(maxIndex, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return localArbIndexArg = ESMF_InterfaceIntCreate(farray2D=localArbIndex, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! default to don't destroy, actual value can be set by subroutine in other creates intDestroyDistgrid=0 intDestroyDELayout=0 ! Call C++ Subroutine to do the create call c_ESMC_gridsetfromdistgrid(grid%this, nameLen, name, & coordTypeKind, distgrid, & distgridToGridMapArg, distDimArg, & coordSys, coordDimCountArg, coordDimMapArg, & minIndexArg, maxIndexArg, localArbIndexArg, localArbIndexCount, & gridEdgeLWidthArg, gridEdgeUWidthArg, gridAlignArg, & gridMemLBoundArg, indexflag, intDestroyDistGrid, intDestroyDELayout, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate helper variables call ESMF_InterfaceIntDestroy(gridEdgeUWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(gridEdgeLWidthArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(gridAlignArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(gridMemLBoundArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(distgridToGridMapArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(distDimArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(coordDimCountArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(coordDimMapArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(minIndexArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(maxIndexArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(localArbIndexArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridSetFromDistGrid !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridSetCoordFromArray" !BOP ! !IROUTINE: ESMF_GridSetCoord - Set coordinates using Arrays ! !INTERFACE: subroutine ESMF_GridSetCoordFromArray(grid, coordDim, staggerloc, & array, keywordEnforcer, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(in) :: coordDim type (ESMF_StaggerLoc), intent(in), optional :: staggerloc type(ESMF_Array), intent(in) :: array type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This method sets the passed in Array as the holder of the coordinate data ! for stagger location {\tt staggerloc} and coordinate {\tt coord}. If the location ! already contains an Array, then this one overwrites it. ! ! The arguments are: !\begin{description} !\item[{grid}] ! The grid to set the coord in. !\item[{coordDim}] ! The coordinate dimension to put the data in (e.g. 1=x). !\item[{staggerloc}] ! The stagger location into which to copy the arrays. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. !\item[{array}] ! An array to set the grid coordinate information from. !\item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. !\end{description} ! !EOP integer :: tmp_staggerloc integer :: localrc ! local error status type(ESMF_GridDecompType) :: decompType type(ESMF_DataCopy_Flag) :: datacopyflag ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_ArrayGetInit, array, rc) ! ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! handle staggerloc if (present(staggerloc)) then if ((decompType == ESMF_GRID_ARBITRARY) .and. & (staggerloc /= ESMF_STAGGERLOC_CENTER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return else tmp_staggerloc=staggerloc%staggerloc endif else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif ! Use reference datacopyflag=ESMF_DATACOPY_REFERENCE ! Call C++ Subroutine to do the create call c_ESMC_gridsetcoordfromarray(grid%this,tmp_staggerloc, coordDim, & array, datacopyflag, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridSetCoordFromArray !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridSetCmmitShapeTileIrreg" !BOPI ! !IROUTINE: ESMF_GridSetCommitShapeTile - Set and complete a Grid with an irregular distribution ! !INTERFACE: ! Private name; call using ESMF_GridSetCommitShapeTile() subroutine ESMF_GridSetCmmitShapeTileIrreg(grid, name,coordTypeKind, & minIndex, countsPerDEDim1, countsPerDeDim2, & keywordEnforcer, countsPerDEDim3, connflagDim1, connflagDim2, connflagDim3, & poleStaggerLoc1, poleStaggerLoc2, poleStaggerLoc3, & bipolePos1, bipolePos2, bipolePos3, & coordDep1, coordDep2, coordDep3, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridMemLBound, indexflag, petMap, rc) ! ! !ARGUMENTS: type (ESMF_Grid) :: grid character (len=*), intent(in), optional :: name type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: minIndex(:) integer, intent(in) :: countsPerDEDim1(:) integer, intent(in) :: countsPerDEDim2(:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(in), optional :: countsPerDEDim3(:) type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim1(:) !N. IMP. type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim2(:) !N. IMP. type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim3(:) !N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc1(2)!N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc2(2)!N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc3(2)!N. IMP. integer, intent(in), optional :: bipolePos1(2)!N. IMP. integer, intent(in), optional :: bipolePos2(2)!N. IMP. integer, intent(in), optional :: bipolePos3(2)!N. IMP. integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(in), optional :: gridEdgeLWidth(:) integer, intent(in), optional :: gridEdgeUWidth(:) integer, intent(in), optional :: gridAlign(:) integer, intent(in), optional :: gridMemLBound(:) type(ESMF_Index_Flag), intent(in), optional :: indexflag integer, intent(in), optional :: petMap(:,:,:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This method sets information into an empty Grid and then commits it to ! create a single tile, irregularly distributed grid ! (see Figure \ref{fig:GridDecomps}). ! To specify the irregular distribution, the user passes in an array ! for each grid dimension, where the length of the array is the number ! of DEs in the dimension. Up to three dimensions can be specified, ! using the countsPerDEDim1, countsPerDEDim2, countsPerDEDim3 arguments. ! The index of each array element corresponds to a DE number. The ! array value at the index is the number of grid cells on the DE in ! that dimension. The dimCount of the grid is equal to the number of ! countsPerDEDim arrays that are specified. ! ! Section \ref{example:2DIrregUniGrid} shows an example ! of using this method to create a 2D Grid with uniformly spaced ! coordinates. This creation method can also be used as the basis for ! grids with rectilinear coordinates or curvilinear coordinates. ! ! For consistency's sake the {\tt ESMF\_GridSetCommitShapeTile()} call ! should be executed in the same set or a subset of the PETs in which the ! {\tt ESMF\_GridEmptyCreate()} call was made. If the call ! is made in a subset, the Grid objects outside that subset will ! still be "empty" and not usable. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! The empty {\tt ESMF\_Grid} to set information into and then commit. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[minIndex]}] ! Tuple to start the index ranges at. If not present, defaults ! to /1,1,1,.../. ! \item[{countsPerDEDim1}] ! This arrays specifies the number of cells per DE for index dimension 1 ! for the exclusive region (the center stagger location). ! If the array has only one entry, then the dimension is undistributed. ! \item[{countsPerDEDim2}] ! This array specifies the number of cells per DE for index dimension 2 ! for the exclusive region (center stagger location). ! If the array has only one entry, then the dimension is undistributed. ! \item[{[countsPerDEDim3]}] ! This array specifies the number of cells per DE for index dimension 3 ! for the exclusive region (center stagger location). ! If not specified then grid is 2D. Also, If the array has only one entry, ! then the dimension is undistributed. ! \item[{[connflagDim1]}] ! Fortran array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[connflagDim2]}] ! Fortran array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[connflagDim3]}] ! Fortran array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3 ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc1]}] ! Two element array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc2]}] ! Two element array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc3]}] ! Two element array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If a pole, this describes which staggerlocation is at the pole at each end. ! If not present, the default is the edge. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos1]}] ! Two element array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos2]}] ! Two element array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos3]}] ! Two element array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[coordDep1]}] ! This array specifies the dependence of the first ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the first ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep2]}] ! This array specifies the dependence of the second ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the second ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep3]}] ! This array specifies the dependence of the third ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the third ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[gridEdgeLWidth]}] ! The padding around the lower edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. ! \item[{[gridEdgeUWidth]}] ! The padding around the upper edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. ! \item[{[gridAlign]}] ! Specification of how the stagger locations should align with the cell ! index space (can be overridden by the individual staggerAligns). If ! the {\tt gridEdgeWidths} are not specified than this parameter ! implies the EdgeWidths. ! \item[{[gridMemLBound]}] ! Specifies the lower index range of the memory of every DE in this Grid. ! Only used when indexflag is {\tt ESMF\_INDEX\_USER}. May be overridden ! by staggerMemLBound. ! \item[{[indexflag]}] ! Indicates the indexing scheme to be used in the new Grid. Please see ! Section~\ref{const:indexflag} for the list of options. If not present, ! defaults to ESMF\_INDEX\_DELOCAL. ! \item[{[petMap]}] ! \begin{sloppypar} ! Sets the mapping of pets to the created DEs. This 3D ! should be of size size(countsPerDEDim1) x size(countsPerDEDim2) x ! size(countsPerDEDim3). If countsPerDEDim3 isn't present, then ! the last dimension is of size 1. ! \end{sloppypar} ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI type(ESMF_DistGrid) :: distgrid type(ESMF_DELayout) :: delayout integer, pointer :: petList(:) integer, pointer :: coordDimCount(:) integer, pointer :: coordDimMap(:,:) integer :: localrc integer :: dimCount,i,maxSizeDEDim integer, pointer :: distgridToGridMap(:), deDimCount(:) integer, pointer :: minIndexLocal(:) integer, pointer :: maxIndexLocal(:) integer, pointer :: gridEdgeLWidthLocal(:) integer, pointer :: gridEdgeUWidthLocal(:) integer, pointer :: gridAlignLocal(:) integer, pointer :: countsPerDEDim1Local(:) integer, pointer :: countsPerDEDim2Local(:) integer, pointer :: countsPerDEDim3Local(:) integer, pointer :: deBlockList(:,:,:),minPerDEDim(:,:),maxPerDEDim(:,:) integer :: deCount integer :: d,i1,i2,i3,k type(ESMF_GridConn_Flag) :: connflagDim1Local(2) type(ESMF_GridConn_Flag) :: connflagDim2Local(2) type(ESMF_GridConn_Flag) :: connflagDim3Local(2) integer :: connCount, petListCount integer :: top ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Compute the Grid DimCount and Derivatives --------------------------------------------------- ! dimCount if (present(countsPerDEDim3)) then dimCount=3 else dimCount=2 endif ! Argument Consistency Checking -------------------------------------------------------------- if (size(countsPerDEDim1) .lt. 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- size 0 countsPerDEDim1 not allowed", & ESMF_CONTEXT, rcToReturn=rc) return endif if (size(countsPerDEDim2) .lt. 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- size 0 countsPerDEDim2 not allowed", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(countsPerDEDim3)) then if (size(countsPerDEDim3) .lt. 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- size 0 countsPerDEDim3 not allowed", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if ((dimCount .lt. 3) .and. present(connflagDim3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- connflagDim3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(poleStaggerLoc3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- poleStaggerLoc3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(bipolePos3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- bipolePos3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(coordDep3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(coordDep1)) then if ((size(coordDep1) < 1) .or. (size(coordDep1)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep1 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep2)) then if ((size(coordDep2) < 1) .or. (size(coordDep2)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep2 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep3)) then if ((size(coordDep3) < 1) .or. (size(coordDep3)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep3 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(minIndex)) then if (size(minIndex) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- minIndex size must equal grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(petMap)) then if (dimCount > 2) then if ((size(petMap,1) /= size(countsPerDEDim1)) .or. & (size(petMap,2) /= size(countsPerDEDim2)) .or. & (size(petMap,3) /= size(countsPerDEDim3))) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif else if ((size(petMap,1) /= size(countsPerDEDim1)) .or. & (size(petMap,2) /= size(countsPerDEDim2)) .or. & (size(petMap,3) /= 1)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif ! Check DimCount of gridWidths and Aligns if (present(gridEdgeLWidth)) then if (size(gridEdgeLWidth) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeLWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (size(gridEdgeUWidth) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeUWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridAlign)) then if (size(gridAlign) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridAlign must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim1)) then if (size(connflagDim1) == 1) then if (connflagDim1(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim1) == 2) then if (connflagDim1(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim1(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim2)) then if (size(connflagDim2) == 1) then if (connflagDim2(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim2) == 2) then if (connflagDim2(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim2(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim3)) then if (size(connflagDim3) == 1) then if (connflagDim3(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim3) == 2) then if (connflagDim3(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim3(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! check for gridMemLBound issues if (present(gridMemLBound)) then if (.not. present(indexflag)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using gridMemLBound must specify indexflag=ESMF_INDEX_USER ", & ESMF_CONTEXT, rcToReturn=rc) return else if (.not. (indexflag == ESMF_INDEX_USER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using gridMemLBound must specify indexflag=ESMF_INDEX_USER ", & ESMF_CONTEXT, rcToReturn=rc) return endif else if (present(indexflag)) then if (indexflag == ESMF_INDEX_USER) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using indexflag=ESMF_INDEX_USER must provide gridMemLBound ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif ! Check for non-valid connection types here !TODO: Consider making some of these a separate local subroutine (particularly if you're going to ! have 3 of these ShapeCreate subroutines with only minor changes ! Copy vales for countsPerDEDim -------------------------------------------- allocate(countsPerDEDim1Local(size(countsPerDEDim1)), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return countsPerDEDim1Local=countsPerDEDim1 allocate(countsPerDEDim2Local(size(countsPerDEDim2)), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return countsPerDEDim2Local=countsPerDEDim2 if (dimCount > 2) then allocate(countsPerDEDim3Local(size(countsPerDEDim3)), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return countsPerDEDim3Local=countsPerDEDim3 endif ! Set Defaults ------------------------------------------------------------- ! Set default for minIndex allocate(minIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(minIndex)) then minIndexLocal(:)=minIndex(:) else do i=1,dimCount minIndexLocal(i)=1 enddo endif ! Set Default for connections (although they don't work yet in distgrid/array, so they aren't really used anywhere yet.) if (present(connflagDim1)) then if (size(connflagDim1) == 1) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim1) >= 2) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(2) endif else connflagDim1Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim1Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim2)) then if (size(connflagDim2) == 1) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim2) >= 2) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(2) endif else connflagDim2Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim2Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim3)) then if (size(connflagDim3) == 1) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim3) >= 2) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(2) endif else connflagDim3Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim3Local(2)=ESMF_GRIDCONN_NONE endif ! check for not implemented functionality if (connflagDim1Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim1Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim2Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim2Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim3Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim3Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Make alterations to size due to GridEdgeWidths ---------------------------- allocate(gridEdgeLWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeLWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridEdgeUWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeUWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridAlignLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridAlignLocal", & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridLUADefault(dimCount, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridEdgeLWidthLocal, gridEdgeUWidthLocal, gridAlignLocal, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return #if 0 ! Modify lower bound do i=1,dimCount minIndexLocal(i)=minIndexLocal(i)-gridEdgeLWidthLocal(i) enddo ! Modify lower size countsPerDEDim1Local(1)=countsPerDEDim1Local(1)+gridEdgeLWidthLocal(1) countsPerDEDim2Local(1)=countsPerDEDim2Local(1)+gridEdgeLWidthLocal(2) if (dimCount > 2) then countsPerDEDim3Local(1)=countsPerDEDim3Local(1)+gridEdgeLWidthLocal(3) endif ! Modify upper size top=size(countsPerDEDim1Local) countsPerDEDim1Local(top)=countsPerDEDim1Local(top)+gridEdgeUWidthLocal(1) top=size(countsPerDEDim2Local) countsPerDEDim2Local(top)=countsPerDEDim2Local(top)+gridEdgeUWidthLocal(2) if (dimCount > 2) then top=size(countsPerDEDim3Local) countsPerDEDim3Local(top)=countsPerDEDim3Local(top)+gridEdgeUWidthLocal(3) endif #endif ! Calc minIndex,maxIndex,distgridToGridMap for DistGrid ----------------------------------- ! Set default for maxIndex allocate(maxIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexLocal(1)=sum(countsPerDEDim1Local)+minIndexLocal(1)-1 maxIndexLocal(2)=sum(countsPerDEDim2Local)+minIndexLocal(2)-1 if (dimCount > 2) then maxIndexLocal(3)=sum(countsPerDEDim3Local)+minIndexLocal(3)-1 endif allocate(distgridToGridMap(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distgridToGridMap", & ESMF_CONTEXT, rcToReturn=rc)) return do i=1,dimCount distgridToGridMap(i)=i enddo ! Setup deBlockList for DistGrid ------------------------------------------------ ! count de blocks deCount=1 deCount=deCount*size(countsPerDEDim1Local) deCount=deCount*size(countsPerDEDim2Local) if (dimCount > 2) then deCount=deCount*size(countsPerDEDim3Local) endif ! Calc the max size of a DEDim maxSizeDEDim=1 if (size(countsPerDEDim1Local) > maxSizeDEDim) then maxSizeDEDim=size(countsPerDEDim1Local) endif if (size(countsPerDEDim2Local) > maxSizeDEDim) then maxSizeDEDim=size(countsPerDEDim2Local) endif if (dimCount > 2) then if (size(countsPerDEDim3Local) > maxSizeDEDim) then maxSizeDEDim=size(countsPerDEDim3Local) endif endif ! generate deblocklist allocate(maxPerDEDim(dimCount,maxSizeDEDim), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxPerDEDim", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(minPerDEDim(dimCount,maxSizeDEDim), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minPerDEDim", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(deDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxPerDEDim", & ESMF_CONTEXT, rcToReturn=rc)) return ! Calc the maximum end of each DE in a Dim, and the size of each DEDim d=1 deDimCount(d)=size(countsPerDEDim1Local) minPerDeDim(d,1)=minIndexLocal(d) maxPerDeDim(d,1)=minIndexLocal(d)+countsPerDEDim1Local(1)-1 do i=2,deDimCount(d) minPerDEDim(d,i)=maxPerDEDim(d,i-1)+1 maxPerDEDim(d,i)=minPerDEDim(d,i)+countsPerDEDim1Local(i)-1 enddo d=2 deDimCount(d)=size(countsPerDEDim2Local) minPerDeDim(d,1)=minIndexLocal(d) maxPerDeDim(d,1)=minIndexLocal(d)+countsPerDEDim2Local(1)-1 do i=2,deDimCount(d) minPerDEDim(d,i)=maxPerDEDim(d,i-1)+1 maxPerDEDim(d,i)=minPerDEDim(d,i)+countsPerDEDim2Local(i)-1 enddo if (dimCount > 2) then d=3 deDimCount(d)=size(countsPerDEDim3Local) minPerDeDim(d,1)=minIndexLocal(d) maxPerDeDim(d,1)=minIndexLocal(d)+countsPerDEDim3Local(1)-1 do i=2,deDimCount(d) minPerDEDim(d,i)=maxPerDEDim(d,i-1)+1 maxPerDEDim(d,i)=minPerDEDim(d,i)+countsPerDEDim3Local(i)-1 enddo endif ! allocate deblocklist allocate(deBlockList(dimCount,2,deCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating deBlockList", & ESMF_CONTEXT, rcToReturn=rc)) return ! Fill in DeBlockList if (dimCount == 2) then k=1 do i2=1,deDimCount(2) do i1=1,deDimCount(1) deBlockList(1,1,k)=minPerDEDim(1,i1) deBlockList(1,2,k)=maxPerDEDim(1,i1) deBlockList(2,1,k)=minPerDEDim(2,i2) deBlockList(2,2,k)=maxPerDEDim(2,i2) k=k+1 enddo enddo else if (dimCount == 3) then k=1 do i3=1,deDimCount(3) do i2=1,deDimCount(2) do i1=1,deDimCount(1) deBlockList(1,1,k)=minPerDEDim(1,i1) deBlockList(1,2,k)=maxPerDEDim(1,i1) deBlockList(2,1,k)=minPerDEDim(2,i2) deBlockList(2,2,k)=maxPerDEDim(2,i2) deBlockList(3,1,k)=minPerDEDim(3,i3) deBlockList(3,2,k)=maxPerDEDim(3,i3) k=k+1 enddo enddo enddo endif ! do i=1,deCount ! write(*,*) i,"min=",deBlockList(:,1,i)," max=",deBlockList(:,2,i) ! enddo ! Setup Connections between tile sides ---------------------------------------- ! CONNECTIONS DON'T WORK YET SO NOT IMPLEMENTED ! Process PetMap -------------------------------------------------------------- if (present(petMap)) then !! Allocate petList allocate(petList(deCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating petList", & ESMF_CONTEXT, rcToReturn=rc)) return !! copy petMap to petList if (dimCount > 2) then k=1 do i3=1,size(countsPerDEDim3Local) do i2=1,size(countsPerDEDim2Local) do i1=1,size(countsPerDEDim1Local) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo else k=1 do i3=1,1 do i2=1,size(countsPerDEDim2Local) do i1=1,size(countsPerDEDim1Local) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo endif !! create delayout from the petList delayout=ESMF_DELayoutCreate(petList=petList,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Get rid of list deallocate(petList) else !! create a default delayout delayout=ESMF_DELayoutCreate(deCount=deCount,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Create DistGrid -------------------------------------------------------------- distgrid=ESMF_DistGridCreate(minIndex=minIndexLocal, maxIndex=maxIndexLocal, & deBlockList=deBlockList, delayout=delayout, indexflag=indexflag, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Convert coordDeps to coordDimCount and coordDimMap ------------------------------- allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(coordDep1)) then coordDimCount(1)=size(coordDep1) coordDimMap(1,:)=0 do i=1,size(coordDep1) coordDimMap(1,i)=coordDep1(i) enddo else coordDimCount(1)=dimCount do i=1,dimCount coordDimMap(1,i)=i enddo endif if (present(coordDep2)) then coordDimCount(2)=size(coordDep2) coordDimMap(2,:)=0 do i=1,size(coordDep2) coordDimMap(2,i)=coordDep2(i) enddo else coordDimCount(2)=dimCount do i=1,dimCount coordDimMap(2,i)=i enddo endif if (dimCount > 2) then if (present(coordDep3)) then coordDimCount(3)=size(coordDep3) coordDimMap(3,:)=0 do i=1,size(coordDep3) coordDimMap(3,i)=coordDep3(i) enddo else coordDimCount(3)=dimCount do i=1,dimCount coordDimMap(3,i)=i enddo endif endif ! Create Grid from specification ----------------------------------------------- call ESMF_GridSetFromDistGrid(grid, coordTypeKind=coordTypeKind, & distgrid=distgrid, distgridToGridMap=distgridToGridMap, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & gridEdgeLWidth=gridEdgeLWidthLocal, & gridEdgeUWidth=gridEdgeUWidthLocal, & gridAlign=gridAlignLocal, & gridMemLBound=gridMemLBound, & indexflag=indexflag, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid call ESMF_GridSetDestroyDistgrid(grid,destroy=.true., rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout(grid,destroy=.true., rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Commit Grid ----------------------------------------------------------------- call ESMF_GridCommit(grid, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(maxIndexLocal) deallocate(minIndexLocal) deallocate(coordDimCount) deallocate(coordDimMap) deallocate(distgridToGridMap) deallocate(maxPerDEDim) deallocate(minPerDEDim) deallocate(deDimCount) deallocate(deBlockList) deallocate(gridEdgeLWidthLocal) deallocate(gridEdgeUWidthLocal) deallocate(gridAlignLocal) deallocate(countsPerDEDim1Local) deallocate(countsPerDEDim2Local) if (dimCount > 2) then deallocate(countsPerDEDim3Local) endif ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridSetCmmitShapeTileIrreg !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridSetCmmitShapeTileReg" !BOPI ! !IROUTINE: ESMF_GridSetCommitShapeTile - Set and complete a Grid with a regular distribution ! !INTERFACE: ! Private name; call using ESMF_GridSetCommitShapeTile() subroutine ESMF_GridSetCmmitShapeTileReg(grid, name, coordTypeKind, & regDecomp, decompFlag, minIndex, maxIndex, & keywordEnforcer, connflagDim1, connflagDim2, connflagDim3, & poleStaggerLoc1, poleStaggerLoc2, poleStaggerLoc3, & bipolePos1, bipolePos2, bipolePos3, & coordDep1, coordDep2, coordDep3, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridMemLBound, indexflag, petMap, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(inout) :: grid character (len=*), intent(in), optional :: name type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: regDecomp(:) type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) integer, intent(in), optional :: minIndex(:) integer, intent(in) :: maxIndex(:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim1(:) !N. IMP. type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim2(:) !N. IMP. type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim3(:) !N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc1(2)!N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc2(2)!N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc3(2)!N. IMP. integer, intent(in), optional :: bipolePos1(2) !N. IMP. integer, intent(in), optional :: bipolePos2(2) !N. IMP. integer, intent(in), optional :: bipolePos3(2) !N. IMP. integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(in), optional :: gridEdgeLWidth(:) integer, intent(in), optional :: gridEdgeUWidth(:) integer, intent(in), optional :: gridAlign(:) integer, intent(in), optional :: gridMemLBound(:) type(ESMF_Index_Flag), intent(in), optional :: indexflag integer, intent(in), optional :: petMap(:,:,:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This method sets information into an empty Grid and then commits it to ! create a single tile, regularly distributed grid ! (see Figure \ref{fig:GridDecomps}). ! To specify the distribution, the user passes in an array ! ({\tt regDecomp}) specifying the number of DEs to divide each ! dimension into. If the number of DEs is 1 than the dimension is undistributed. ! The array {\tt decompFlag} indicates how the division into DEs is to ! occur. The default is to divide the range as evenly as possible. ! ! For consistency's sake the {\tt ESMF\_GridSetCommitShapeTile()} call ! should be executed in the same set or a subset of the PETs in which the ! {\tt ESMF\_GridEmptyCreate()} call was made. If the call ! is made in a subset, the Grid objects outside that subset will ! still be "empty" and not usable. ! ! The arguments are: ! \begin{description} ! \item[{grid}] ! {\tt ESMF\_Grid} to set information into and then commit. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[regDecomp]}] ! List that has the same number of elements as {\tt maxIndex}. ! Each entry is the number of decounts for that dimension. ! If not specified, the default decomposition will be petCountx1x1..x1. ! \item[{[decompflag]}] ! List of decomposition flags indicating how each dimension of the ! tile is to be divided between the DEs. The default setting ! is {\tt ESMF\_DECOMP\_BALANCED} in all dimensions. Please see ! Section~\ref{const:decompflag} for a full description of the ! possible options. ! \item[{[minIndex]}] ! The bottom extent of the grid array. If not given then the value defaults ! to /1,1,1,.../. ! \item[{maxIndex}] ! The upper extent of the grid array. ! \item[{[connflagDim1]}] ! Fortran array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[connflagDim2]}] ! Fortran array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[connflagDim3]}] ! Fortran array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc1]}] ! Two element array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc2]}] ! Two element array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc3]}] ! Two element array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos1]}] ! Two element array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos2]}] ! Two element array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos3]}] ! Two element array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[coordDep1]}] ! This array specifies the dependence of the first ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the first ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep2]}] ! This array specifies the dependence of the second ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the second ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[coordDep3]}] ! This array specifies the dependence of the third ! coordinate component on the three index dimensions ! described by {\tt coordsPerDEDim1,2,3}. The size of the ! array specifies the number of dimensions of the third ! coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. If not present the default is 1,2,...,grid rank. ! \item[{[gridEdgeLWidth]}] ! The padding around the lower edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. ! \item[{[gridEdgeUWidth]}] ! The padding around the upper edges of the grid. This padding is between ! the index space corresponding to the cells and the boundary of the ! the exclusive region. This extra space is to contain the extra ! padding for non-center stagger locations, and should be big enough ! to hold any stagger in the grid. ! \item[{[gridAlign]}] ! Specification of how the stagger locations should align with the cell ! index space (can be overridden by the individual staggerAligns). If ! the {\tt gridEdgeWidths} are not specified than this parameter ! implies the EdgeWidths. ! \item[{[gridMemLBound]}] ! Specifies the lower index range of the memory of every DE in this Grid. ! Only used when indexflag is {\tt ESMF\_INDEX\_USER}. May be overridden ! by staggerMemLBound. ! \item[{[indexflag]}] ! Indicates the indexing scheme to be used in the new Grid. Please see ! Section~\ref{const:indexflag} for the list of options. If not present, ! defaults to ESMF\_INDEX\_DELOCAL. ! \item[{[petMap]}] ! Sets the mapping of pets to the created DEs. This 3D ! should be of size regDecomp(1) x regDecomp(2) x regDecomp(3) ! If the Grid is 2D, then the last dimension is of size 1. ! If the Grid contains undistributed dimensions then these ! should also be of size 1. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI type(ESMF_DistGrid) :: distgrid type(ESMF_DELayout) :: delayout type(ESMF_VM) :: vm integer, pointer :: petList(:) integer, pointer :: undistLBound(:) integer, pointer :: undistUBound(:) integer, pointer :: coordDimCount(:) integer, pointer :: coordDimMap(:,:) integer :: localrc integer :: dimCount,i,maxSizeDEDim integer, pointer :: regDecompDG(:) type(ESMF_Decomp_Flag), pointer :: decompflagDG(:) integer, pointer :: regDecompLocal(:) type(ESMF_Decomp_Flag), pointer :: decompflagLocal(:) integer, pointer :: distgridToGridMap(:), deDimCount(:) integer, pointer :: minIndexLocal(:), maxIndexLocal(:) integer, pointer :: gridEdgeLWidthLocal(:) integer, pointer :: gridEdgeUWidthLocal(:) integer, pointer :: gridAlignLocal(:) integer :: deCount integer :: d,i1,i2,i3,k type(ESMF_GridConn_Flag) :: connflagDim1Local(2) type(ESMF_GridConn_Flag) :: connflagDim2Local(2) type(ESMF_GridConn_Flag) :: connflagDim3Local(2) integer :: connCount, petListCount ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Compute the Grid DimCount and Derivatives --------------------------------------------------- ! dimCount dimCount=size(maxIndex) if ((dimCount < 2) .or. (dimCount > 3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- maxIndex size and thus Grid dimCount must be either 2 or 3 when using create shape ", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Argument Consistency Checking -------------------------------------------------------------- if (present(regDecomp)) then if (size(regDecomp) .lt. dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- regDecomp size doesn't match Grid dimCount ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(decompFlag)) then if (size(decompFlag) .lt. dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- decompFlag size doesn't match Grid dimCount ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if ((dimCount .lt. 3) .and. present(connflagDim3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- connflagDim3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(poleStaggerLoc3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- poleStaggerLoc3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(bipolePos3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- bipolePos3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(coordDep3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(coordDep1)) then if ((size(coordDep1) < 1) .or. (size(coordDep1)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep1 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep2)) then if ((size(coordDep2) < 1) .or. (size(coordDep2)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep2 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep3)) then if ((size(coordDep3) < 1) .or. (size(coordDep3)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep3 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(minIndex)) then if (size(minIndex) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- minIndex size must equal grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Check DimCount of gridWidths and Aligns if (present(gridEdgeLWidth)) then if (size(gridEdgeLWidth) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeLWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (size(gridEdgeUWidth) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeUWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridAlign)) then if (size(gridAlign) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridAlign must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim1)) then if (size(connflagDim1) == 1) then if (connflagDim1(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim1) == 2) then if (connflagDim1(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim1(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(1) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim2)) then if (size(connflagDim2) == 1) then if (connflagDim2(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim2) == 2) then if (connflagDim2(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim2(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(2) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! make sure connected dimensions don't have an edge width if (present(connflagDim3)) then if (size(connflagDim3) == 1) then if (connflagDim3(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif else if (size(connflagDim3) == 2) then if (connflagDim3(1) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeLWidth)) then if (gridEdgeLWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have LWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif if (connflagDim3(2) /= ESMF_GRIDCONN_NONE) then if (present(gridEdgeUWidth)) then if (gridEdgeUWidth(3) > 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Connected dimensions must have UWidth 0", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif endif endif ! check for gridMemLBound issues if (present(gridMemLBound)) then if (.not. present(indexflag)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using gridMemLBound must specify indexflag=ESMF_INDEX_USER ", & ESMF_CONTEXT, rcToReturn=rc) return else if (.not.(indexflag == ESMF_INDEX_USER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using gridMemLBound must specify indexflag=ESMF_INDEX_USER ", & ESMF_CONTEXT, rcToReturn=rc) return endif else if (present(indexflag)) then if (indexflag == ESMF_INDEX_USER) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- when using indexflag=ESMF_INDEX_USER must provide gridMemLBound ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif ! Check for non-valid connection types here !TODO: Consider making some of these a separate local subroutine (particularly if you're going to ! have 3 of these ShapeCreate subroutines with only minor changes ! Set Defaults ------------------------------------------------------------------ ! Set default for minIndex allocate(minIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(minIndex)) then minIndexLocal(:)=minIndex(:) else do i=1,dimCount minIndexLocal(i)=1 enddo endif ! Set default for maxIndex allocate(maxIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexLocal(:)=maxIndex(:) ! Set default for regDecomp allocate(regDecompLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating regDecompLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(regDecomp)) then regDecompLocal(:)=regDecomp(:) else ! The default is 1D divided among all the Pets call ESMF_VMGetGlobal(vm,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_VMGet(vm,petCount=regDecompLocal(1),rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return do i=2,dimCount regDecompLocal(i)=1 enddo endif ! Set Default for connections (although they don't work yet in distgrid/array, so they aren't really used anywhere yet.) if (present(connflagDim1)) then if (size(connflagDim1) == 1) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim1) >= 2) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(2) endif else connflagDim1Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim1Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim2)) then if (size(connflagDim2) == 1) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim2) >= 2) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(2) endif else connflagDim2Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim2Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim3)) then if (size(connflagDim3) == 1) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim3) >= 2) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(2) endif else connflagDim3Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim3Local(2)=ESMF_GRIDCONN_NONE endif ! check for not implemented functionality if (connflagDim1Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim1Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim2Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim2Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim3Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim3Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(petMap)) then if (dimCount > 2) then if ((size(petMap,1) /= regDecompLocal(1)) .or. & (size(petMap,2) /= regDecompLocal(2)) .or. & (size(petMap,3) /= regDecompLocal(3))) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif else if ((size(petMap,1) /= regDecompLocal(1)) .or. & (size(petMap,2) /= regDecompLocal(2)) .or. & (size(petMap,3) /= 1)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif ! Modify Bounds by GridEdgeUWidth and GridEdgeLWidth ------------------------- ! setup maxIndexLocal to hold modified bounds allocate(gridEdgeLWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeLWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridEdgeUWidthLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridEdgeUWidthLocal", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(gridAlignLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating gridAlignLocal", & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridLUADefault(dimCount, & gridEdgeLWidth, gridEdgeUWidth, gridAlign, & gridEdgeLWidthLocal, gridEdgeUWidthLocal, gridAlignLocal, & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return #if 0 ! Modify lower bound do i=1,dimCount minIndexLocal(i)=minIndexLocal(i)-gridEdgeLWidthLocal(i) enddo ! Modify upper bound do i=1,dimCount maxIndexLocal(i)=maxIndexLocal(i)+gridEdgeUWidthLocal(i) enddo #endif ! Set default for decomp flag based on gridEdgeWidths ----------------------------------- ! NOTE: This is a temporary fix until we have something better implemented in distGrid ! Set default for decompFlag allocate(decompFlagLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating decompFlagLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(decompFlag)) then decompFlagLocal(:)=decompFlag(:) else decompFlagLocal(:)=ESMF_DECOMP_BALANCED endif allocate(distgridToGridMap(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distgridToGridMap", & ESMF_CONTEXT, rcToReturn=rc)) return do i=1,dimCount distgridToGridMap(i)=i enddo ! Setup Connections between tile sides ---------------------------------------- ! CONNECTIONS DON'T WORK YET SO NOT IMPLEMENTED ! Process PetMap -------------------------------------------------------------- !! Calculate deCount deCount=1 do i=1,dimCount deCount=deCount*regDecompLocal(i) enddo ! create DELayout based on presence of petMap if (present(petMap)) then !! Allocate petList allocate(petList(deCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating petList", & ESMF_CONTEXT, rcToReturn=rc)) return !! copy petMap to petList if (dimCount > 2) then k=1 do i3=1,regDecompLocal(3) do i2=1,regDecompLocal(2) do i1=1,regDecompLocal(1) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo else k=1 do i3=1,1 do i2=1,regDecompLocal(2) do i1=1,regDecompLocal(1) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo endif !! create delayout from the petList delayout=ESMF_DELayoutCreate(petList=petList,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Get rid of list deallocate(petList) else !! create a default delayout delayout=ESMF_DELayoutCreate(deCount=deCount,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Create DistGrid -------------------------------------------------------------- distgrid=ESMF_DistGridCreate(minIndex=minIndexLocal, maxIndex=maxIndexLocal, & regDecomp=regDecompLocal, decompFlag=decompFlagLocal, delayout=delayout,& indexflag=indexflag, & #if 0 regDecompFirstExtra=gridEdgeLWidthLocal, & regDecompLastExtra=gridEdgeUWidthLocal, & #endif rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Convert coordDeps to coordDimCount and coordDimMap ------------------------------- allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(coordDep1)) then coordDimCount(1)=size(coordDep1) coordDimMap(1,:)=0 do i=1,size(coordDep1) coordDimMap(1,i)=coordDep1(i) enddo else coordDimCount(1)=dimCount do i=1,dimCount coordDimMap(1,i)=i enddo endif if (present(coordDep2)) then coordDimCount(2)=size(coordDep2) coordDimMap(2,:)=0 do i=1,size(coordDep2) coordDimMap(2,i)=coordDep2(i) enddo else coordDimCount(2)=dimCount do i=1,dimCount coordDimMap(2,i)=i enddo endif if (dimCount > 2) then if (present(coordDep3)) then coordDimCount(3)=size(coordDep3) coordDimMap(3,:)=0 do i=1,size(coordDep3) coordDimMap(3,i)=coordDep3(i) enddo else coordDimCount(3)=dimCount do i=1,dimCount coordDimMap(3,i)=i enddo endif endif ! Create Grid from specification ----------------------------------------------- call ESMF_GridSetFromDistGrid(grid, coordTypeKind=coordTypeKind, & distgrid=distgrid, distgridToGridMap=distgridToGridMap, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & gridEdgeLWidth=gridEdgeLWidthLocal, & gridEdgeUWidth=gridEdgeUWidthLocal, & gridAlign=gridAlignLocal, & gridMemLBound=gridMemLBound, & indexflag=indexflag, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Commit Grid ----------------------------------------------------------------- call ESMF_GridCommit(grid, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(regDecompLocal) deallocate(decompFlagLocal) deallocate(coordDimCount) deallocate(coordDimMap) deallocate(minIndexLocal) deallocate(maxIndexLocal) deallocate(distgridToGridMap) deallocate(gridEdgeLWidthLocal) deallocate(gridEdgeUWidthLocal) deallocate(gridAlignLocal) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridSetCmmitShapeTileReg !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridSetCmmitShapeTileArb" !BOPI ! !IROUTINE: ESMF_GridSetCommitShapeTile - Create a Grid with an arbitrary distribution ! !INTERFACE: ! Private name; call using ESMF_GridSetCommitShapeTile() subroutine ESMF_GridSetCmmitShapeTileArb(grid, name,coordTypeKind, & minIndex, maxIndex, arbIndexCount, arbIndexList, & keywordEnforcer, connflagDim1, connflagDim2, connflagDim3, & poleStaggerLoc1, poleStaggerLoc2, poleStaggerLoc3, & bipolePos1, bipolePos2, bipolePos3, & coordDep1, coordDep2, coordDep3, & distDim, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(inout) :: grid character (len=*), intent(in), optional :: name type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind integer, intent(in), optional :: minIndex(:) integer, intent(in) :: maxIndex(:) integer, intent(in) :: arbIndexCount integer, intent(in) :: arbIndexList(:,:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim1(:) !N. IMP. type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim2(:) !N. IMP. type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim3(:) !N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc1(2)!N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc2(2)!N. IMP. type(ESMF_StaggerLoc),intent(in),optional::poleStaggerLoc3(2)!N. IMP. integer, intent(in), optional :: bipolePos1(2) !N. IMP. integer, intent(in), optional :: bipolePos2(2) !N. IMP. integer, intent(in), optional :: bipolePos3(2) !N. IMP. integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(in), optional :: distDim(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This method set an empty grid as a single tile, arbitrarily distributed grid ! (see Figure \ref{fig:GridDecomps}). ! To specify the arbitrary distribution, the user passes in an 2D array ! of local indices, where the first dimension is the number of local grid cells ! specified by arbIndexCount and the second dimension is the number of distributed ! dimensions. ! ! {\tt distDim} specifies which grid dimensions are arbitrarily distributed. The ! size of {\tt distDim} has to agree with the size of the second dimension of ! {\tt arbIndexList}. ! ! For consistency's sake the {\tt ESMF\_GridSetCommitShapeTile()} call ! should be executed in the same set or a subset of the PETs in which the ! {\tt ESMF\_GridEmptyCreate()} call was made. If the call ! is made in a subset, the Grid objects outside that subset will ! still be "empty" and not usable. ! ! The arguments are: ! \begin{description} ! \item[{[grid]}] ! The empty {\tt ESMF\_Grid} to set information into and then commit. ! \item[{[name]}] ! {\tt ESMF\_Grid} name. ! \item[{[coordTypeKind]}] ! The type/kind of the grid coordinate data. ! If not specified then the type/kind will be 8 byte reals. ! \item[{[minIndex]}] ! Tuple to start the index ranges at. If not present, defaults ! to /1,1,1,.../. ! \item[{[maxIndex]}] ! The upper extend of the grid index ranges. ! \item[{[arbIndexList]}] ! This 2D array specifies the indices of the local grid cells. The ! dimensions should be arbIndexCount * number of Distributed grid dimensions ! where arbIndexCount is the input argument specified below ! \item[{arbIndexCount}] ! The number of grid cells in the local DE ! \item[{[connflagDim1]}] ! Fortran array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[connflagDim2]}] ! Fortran array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[connflagDim3]}] ! Fortran array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If array is only one element long, then that element is used ! for both the minimum and maximum end. ! Please see Section~\ref{const:gridconn} for a list of valid ! options. If not present, defaults to ESMF\_GRIDCONN\_NONE. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc1]}] ! Two element array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc2]}] ! Two element array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[poleStaggerLoc3]}] ! Two element array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If a pole, this describes which staggerlocation is at the pole at each end. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ESMF\_STAGGERLOC\_CENTER. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos1]}] ! Two element array describing the index dimension 1 connections. ! The first element represents the minimum end of dimension 1. ! The second element represents the maximum end of dimension 1. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos2]}] ! Two element array describing the index dimension 2 connections. ! The first element represents the minimum end of dimension 2. ! The second element represents the maximum end of dimension 2. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[bipolePos3]}] ! Two element array describing the index dimension 3 connections. ! The first element represents the minimum end of dimension 3. ! The second element represents the maximum end of dimension 3. ! If a bipole, this gives the index position of one of the poles. ! The other is half way around. If not present, the default is 1. ! [CURRENTLY NOT IMPLEMENTED] ! \item[{[coordDep1]}] ! The size of the array specifies the number of dimensions of the ! first coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_DIM\_ARB/ where ! /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_DIM\_ARB/ if the first dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=1) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB. ! \item[{[coordDep2]}] ! The size of the array specifies the number of dimensions of the ! second coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_DIM\_ARB/ where ! /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_DIM\_ARB/ if this dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=2) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB. ! \item[{[coordDep3]}] ! The size of the array specifies the number of dimensions of the ! third coordinate component array. The values specify which ! of the index dimensions the corresponding coordinate ! arrays map to. The format should be /ESMF\_DIM\_ARB/ where ! /ESMF\_DIM\_ARB/ is mapped to the collapsed 1D dimension from all ! the arbitrarily distributed dimensions. n is the dimension that ! is not distributed (if exists). ! If not present the default is /ESMF\_DIM\_ARB/ if this dimension ! is arbitararily distributed, or /n/ if not distributed (i.e. n=3) ! Please see Section~\ref{const:arbdim} for a definition of ESMF\_DIM\_ARB. ! \item[{[distDim]}] ! This array specifies which dimensions are arbitrarily distributed. ! The size of the array specifies the total distributed dimensions. ! if not specified, defaults is all dimensions will be arbitrarily ! distributed. The size has to agree with the size of the second ! dimension of {\tt arbIndexList}. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI type(ESMF_DistGrid) :: distgrid type(ESMF_DELayout) :: delayout integer, pointer :: petList(:) integer, pointer :: undistLBound(:) integer, pointer :: undistUBound(:) integer, pointer :: coordDimCount(:) integer, pointer :: coordDimMap(:,:) integer :: localrc integer :: dimCount,distDimCount,undistDimCount integer, pointer :: deDimCount(:) integer, pointer :: minIndexLocal(:) integer, pointer :: maxIndexLocal(:) integer :: i,j,d,f,i1,i2,i3,k,ind,ud type(ESMF_GridConn_Flag) :: connflagDim1Local(2) type(ESMF_GridConn_Flag) :: connflagDim2Local(2) type(ESMF_GridConn_Flag) :: connflagDim3Local(2) integer :: connCount, petListCount integer :: top integer, pointer :: distSize(:) integer, pointer :: distDimLocal(:) logical, pointer :: isDist(:) integer, pointer :: local1DIndices(:) logical :: found ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Compute the Grid DimCount and Derivatives --------------------------------------------------- ! dimCount dimCount=size(maxIndex) if ((dimCount < 2) .or. (dimCount > 3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- maxIndex size and thus Grid dimCount must be either 2 or 3 when using create shape ", & ESMF_CONTEXT, rcToReturn=rc) return endif ! number of distributed dimension, distDimCount, is determined by the second dim of ! arbIndexList distDimCount = size(arbIndexList,2) if (distDimCount > dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- the second dim of arbIndexList must be equal or less than grid dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif allocate(distDimLocal(distDimCount), stat=localrc) allocate(isDist(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distDimLocal or isDist", & ESMF_CONTEXT, rcToReturn=rc)) return isDist(:)=.false. ! check distribution info if (present(distDim)) then if (size(distDim) /= distDimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- distDim must match with the second dimension of arbIndexList", & ESMF_CONTEXT, rcToReturn=rc) return endif distDimLocal(:)=distDim(:) do i=1,distDimCount isDist(distDimLocal(i))=.true. enddo else do i=1,distDimCount distDimLocal(i)=i enddo isDist(1:distDimCount)=.true. endif ! Argument Consistency Checking -------------------------------------------------------------- if ((dimCount .lt. 3) .and. present(connflagDim3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- connflagDim3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(poleStaggerLoc3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- poleStaggerLoc3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((dimCount .lt. 3) .and. present(bipolePos3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- bipolePos3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(minIndex)) then if (size(minIndex) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- minIndex size must equal grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Check for non-valid connection types here ! Set Defaults ------------------------------------------------------------- ! Set default for minIndex allocate(minIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(minIndex)) then minIndexLocal(:)=minIndex(:) else do i=1,dimCount minIndexLocal(i)=1 enddo endif ! Set default for maxIndex allocate(maxIndexLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxIndexLocal", & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexLocal(:)=maxIndex(:) allocate(distSize(distDimCount),stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distSize", & ESMF_CONTEXT, rcToReturn=rc)) return do i=1,distDimCount ind = distDimLocal(i) distSize(i)=maxIndexLocal(ind)-minIndexLocal(ind)+1 enddo ! dimCounts of the undistributed part of the grid undistDimCount=dimCount-distDimCount ! can't have all undistributed dimensions if (distDimCount == 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Need to have at least one distributed dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Check arbIndexList dimension matched with arbIndexCount and diskDimCount if (size(arbIndexList, 1) /= arbIndexCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- arbIndexList 1st dimension has to match with arbIndexCount", & ESMF_CONTEXT, rcToReturn=rc) return endif allocate(local1DIndices(arbIndexCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating local1DIndices", & ESMF_CONTEXT, rcToReturn=rc)) return ! convert arbIndexList into 1D index array for DistGrid if (arbIndexCount > 0) then do i = 1, arbIndexCount local1DIndices(i) = arbIndexList(i,1)-1 if (distDimCount >= 2) then do j = 2, distDimCount local1DIndices(i) = local1DIndices(i)*distSize(j) + arbIndexList(i,j)-1 enddo endif local1DIndices(i) = local1DIndices(i)+1 enddo endif ! Set Default for connections (although they don't work yet in distgrid/array, so they aren't really used anywhere yet.) if (present(connflagDim1)) then if (size(connflagDim1) == 1) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim1) >= 2) then connflagDim1Local(1)=connflagDim1(1) connflagDim1Local(2)=connflagDim1(2) endif else connflagDim1Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim1Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim2)) then if (size(connflagDim2) == 1) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim2) >= 2) then connflagDim2Local(1)=connflagDim2(1) connflagDim2Local(2)=connflagDim2(2) endif else connflagDim2Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim2Local(2)=ESMF_GRIDCONN_NONE endif if (present(connflagDim3)) then if (size(connflagDim3) == 1) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(1) ! if only 1 connection is specified then repeat for both ends else if (size(connflagDim3) >= 2) then connflagDim3Local(1)=connflagDim3(1) connflagDim3Local(2)=connflagDim3(2) endif else connflagDim3Local(1)=ESMF_GRIDCONN_NONE ! if not present then default to no connection connflagDim3Local(2)=ESMF_GRIDCONN_NONE endif ! check for not implemented functionality if (connflagDim1Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim1Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim2Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim2Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif if (connflagDim3Local(1) /= ESMF_GRIDCONN_NONE .or. & connflagDim3Local(2) /= ESMF_GRIDCONN_NONE) then call ESMF_LogSetError(rcToCheck=ESMF_RC_NOT_IMPL, & msg="- Only ESMF_GRIDCONN_NONE Grid connection implemented so far", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Setup Connections between tile sides ---------------------------------------- ! CONNECTIONS DON'T WORK YET SO NOT IMPLEMENTED ! Convert coordDeps to coordDimCount and coordDimMap ------------------------------- allocate(coordDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimCount", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(coordDimMap(dimCount,dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating coordDimMap", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(coordDep1)) then ! error checking, if this dimension is arbitrary, one of the ! coordinate dimension has to be be ESMF_DIM_ARB if (isDist(1)) then found = .false. do i=1,size(coordDep1) if (coordDep1(i) == ESMF_DIM_ARB) found = .true. enddo if (.not. found) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep1 does not contain ESMF_DIM_ARB", & ESMF_CONTEXT, rcToReturn=rc) return endif endif coordDimCount(1)=size(coordDep1) coordDimMap(1,:)=0 do i=1,size(coordDep1) coordDimMap(1,i)=coordDep1(i) enddo else coordDimCount(1)=1 ! ESMF_DIM_ARB if 1 is distributed, otherwise 1 if (isDist(1)) then coordDimMap(1,1)=ESMF_DIM_ARB else coordDimMap(1,1)=1 endif endif if (present(coordDep2)) then ! error checking, one of the dimensions has to be ESMF_DIM_ARB ! if dimension 2 is arbitrary if (isDist(2)) then found = .false. do i=1,size(coordDep2) if (coordDep2(i) == ESMF_DIM_ARB) found = .true. enddo if (.not. found) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep2 does not contain ESMF_DIM_ARB", & ESMF_CONTEXT, rcToReturn=rc) return endif endif coordDimCount(2)=size(coordDep2) coordDimMap(2,:)=0 do i=1,size(coordDep2) coordDimMap(2,i)=coordDep2(i) enddo else coordDimCount(2)=1 ! ESMF_DIM_ARB if 1 is distributed, otherwise 1 if (isDist(2)) then coordDimMap(2,1)=ESMF_DIM_ARB else coordDimMap(2,1)=2 endif endif if (dimCount > 2) then if (present(coordDep3)) then ! error checking, one of the dimensions has to be ESMF_DIM_ARB ! if dimension 3 is arbitrary if (isDist(3)) then found = .false. do i=1,size(coordDep3) if (coordDep3(i) == ESMF_DIM_ARB) found = .true. enddo if (.not. found) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep3 does not contain ESMF_DIM_ARB", & ESMF_CONTEXT, rcToReturn=rc) return endif endif coordDimCount(3)=size(coordDep3) coordDimMap(3,:)=0 do i=1,size(coordDep3) coordDimMap(3,i)=coordDep3(i) enddo else coordDimCount(3)=1 ! ESMF_DIM_ARB if 1 is distributed, otherwise 1 if (isDist(3)) then coordDimMap(3,1)=ESMF_DIM_ARB else coordDimMap(3,1)=3 endif endif endif ! Calc undistLBound, undistUBound for Grid ----------------------------------------------- if (undistDimCount > 0) then allocate(undistLBound(undistDimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating undistLBound", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(undistUBound(undistDimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating undistUBound", & ESMF_CONTEXT, rcToReturn=rc)) return ! Fill in undistLBound, undistUBound ud=1 do i=1,dimCount if (.not. isDist(i)) then undistLBound(ud)=minIndexLocal(i) undistUBound(ud)=maxIndexLocal(i) ud=ud+1 endif enddo endif ! Create DistGrid -------------------------------------------------------------- if (undistDimCount > 0) then distgrid=ESMF_DistGridCreate(local1DIndices, 1, undistLBound, undistUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return else distgrid=ESMF_DistGridCreate(local1DIndices, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Create Grid from specification ----------------------------------------------- call ESMF_GridSetFromDistGrid(grid, coordTypeKind=coordTypeKind, & distgrid=distgrid, distDim=distDimLocal, & coordDimCount=coordDimCount, coordDimMap=coordDimMap, & minIndex=minIndexLocal, maxIndex=maxIndexLocal, & localArbIndexCount=arbIndexCount, localArbIndex=arbIndexList, & name=name, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Set internal items to be destroyed with grid call ESMF_GridSetDestroyDistgrid(grid,destroy=.true., rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GridSetDestroyDELayout(grid,destroy=.false., rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(minIndexLocal) deallocate(maxIndexLocal) deallocate(local1DIndices) deallocate(isDist) deallocate(distDimLocal) deallocate(coordDimCount) deallocate(coordDimMap) if (undistDimCount > 0) then deallocate(undistLBound) deallocate(undistUBound) endif deallocate(distSize) ! Commit Grid ----------------------------------------------------------------- call ESMF_GridCommit(grid, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridSetCmmitShapeTileArb !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridSetItemFromArray" !BOP ! !IROUTINE: ESMF_GridSetItem - Set an item using an Array ! !INTERFACE: subroutine ESMF_GridSetItemFromArray(grid, itemflag, staggerloc, & array, keywordEnforcer, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type (ESMF_GridItem_Flag), intent(in) :: itemflag type (ESMF_StaggerLoc), intent(in), optional :: staggerloc type(ESMF_Array), intent(in) :: array type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! This method sets the passed in Array as the holder of the item data ! for stagger location {\tt staggerloc} and coordinate {\tt coord}. If the location ! already contains an Array, then this one overwrites it. ! ! Eventually there should be an Add, Get,... like for the Coords to make things ! easy for the user (except restricted to just I4??) ! ! The arguments are: !\begin{description} !\item[{grid}] ! The grid in which to set the array. !\item[{itemflag}] ! The item into which to copy the arrays. Please see Section~\ref{const:griditem} for a ! list of valid items. !\item[{staggerloc}] ! The stagger location into which to copy the arrays. ! Please see Section~\ref{const:staggerloc} for a list ! of predefined stagger locations. If not present, defaults to ! ESMF\_STAGGERLOC\_CENTER. !\item[{array}] ! An array to set the grid item information from. !\item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. !\end{description} ! !EOP integer :: tmp_staggerloc integer :: localrc ! local error status type(ESMF_GridDecompType) :: decompType type(ESMF_DataCopy_Flag) :: datacopyflag ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP_SHORT(ESMF_ArrayGetInit, array, rc) ESMF_INIT_CHECK_DEEP_SHORT(ESMF_GridGetInit, grid, rc) call ESMF_GridGetDecompType(grid, decompType, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! handle staggerloc if (present(staggerloc)) then if ((decompType == ESMF_GRID_ARBITRARY) .and. & (staggerloc /= ESMF_STAGGERLOC_CENTER)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- staggerloc has to be ESMF_STAGGERLOC_CENTER for arbitrary grid", & ESMF_CONTEXT, rcToReturn=rc) return else tmp_staggerloc=staggerloc%staggerloc endif else tmp_staggerloc=ESMF_STAGGERLOC_CENTER%staggerloc endif ! Use reference datacopyflag=ESMF_DATACOPY_REFERENCE ! Call C++ Subroutine call c_ESMC_gridsetitemfromarray(grid%this,tmp_staggerloc, itemflag, & array, datacopyflag, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridSetItemFromArray ! -------------------------- ESMF-public method ------------------------------- #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridValidate()" !BOP ! !IROUTINE: ESMF_GridValidate - Validate Grid internals ! !INTERFACE: subroutine ESMF_GridValidate(grid, keywordEnforcer, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! Validates that the {\tt Grid} is internally consistent. ! Note that one of the checks that the Grid validate does ! is the Grid status. Currently, the validate will return ! an error if the grid is not at least ! {\tt ESMF\_GRIDSTATUS\_COMPLETE}. This means that ! if a Grid was created with the {\tt ESMF\_GridEmptyCreate} ! method, it must also have been finished with ! {\tt ESMF\_GridEmptyComplete()} ! to be valid. If a Grid was created with another create ! call it should automatically have the correct status level ! to pass the status part of the validate. ! The Grid validate at this time doesn't check for the presence ! or consistency of the Grid coordinates. ! The method returns an error code if problems are found. ! ! The arguments are: ! \begin{description} ! \item[grid] ! Specified {\tt ESMF\_Grid} object. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP !------------------------------------------------------------------------------ integer :: localrc ! local return code ! initialize return code; assume routine not implemented localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Call into the C++ interface, which will sort out optional arguments. call c_ESMC_GridValidate(grid, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridValidate !------------------------------------------------------------------------------ ! -------------------------- ESMF-internal method ----------------------------- #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridGetInit" !BOPI ! !IROUTINE: ESMF_GridGetInit - Internal access routine for init code ! ! !INTERFACE: function ESMF_GridGetInit(grid) ! ! !RETURN VALUE: ESMF_INIT_TYPE :: ESMF_GridGetInit ! ! !ARGUMENTS: type(ESMF_Grid), intent(in), optional :: grid ! ! !DESCRIPTION: ! Access deep object init code. ! ! The arguments are: ! \begin{description} ! \item [grid] ! Grid object. ! \end{description} ! !EOPI if (present(grid)) then ESMF_GridGetInit = ESMF_INIT_GET(grid) else ESMF_GridGetInit = ESMF_INIT_CREATED endif end function ESMF_GridGetInit !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridConnEqual" !BOPI ! !IROUTINE: ESMF_GridConnEqual - Equality of GridConns ! ! !INTERFACE: function ESMF_GridConnEqual(GridConn1, GridConn2) ! !RETURN VALUE: logical :: ESMF_GridConnEqual ! !ARGUMENTS: type (ESMF_GridConn_Flag), intent(in) :: & GridConn1, &! Two igrid statuses to compare for GridConn2 ! equality ! !DESCRIPTION: ! This routine compares two ESMF GridConn statuses to see if ! they are equivalent. ! ! The arguments are: ! \begin{description} ! \item[GridConn1, GridConn2] ! Two igrid statuses to compare for equality ! \end{description} ! !EOPI ESMF_GridConnEqual = (GridConn1%gridconn == & GridConn2%gridconn) end function ESMF_GridConnEqual !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridConnNotEqual" !BOPI ! !IROUTINE: ESMF_GridConnNotEqual - Non-equality of GridConns ! ! !INTERFACE: function ESMF_GridConnNotEqual(GridConn1, GridConn2) ! !RETURN VALUE: logical :: ESMF_GridConnNotEqual ! !ARGUMENTS: type (ESMF_GridConn_Flag), intent(in) :: & GridConn1, &! Two GridConn Statuses to compare for GridConn2 ! inequality ! !DESCRIPTION: ! This routine compares two ESMF GridConn statuses to see if ! they are unequal. ! ! The arguments are: ! \begin{description} ! \item[GridConn1, GridConn2] ! Two statuses of GridConns to compare for inequality ! \end{description} ! !EOPI ESMF_GridConnNotEqual = (GridConn1%gridconn /= & GridConn2%gridconn) end function ESMF_GridConnNotEqual !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridDecompEqual" !BOPI ! !IROUTINE: ESMF_GridDecompEqual - Equality of GridDecomps ! ! !INTERFACE: function ESMF_GridDecompEqual(GridDecomp1, GridDecomp2) ! !RETURN VALUE: logical :: ESMF_GridDecompEqual ! !ARGUMENTS: type (ESMF_GridDecompType), intent(in) :: & GridDecomp1, &! Two igrid statuses to compare for GridDecomp2 ! equality ! !DESCRIPTION: ! This routine compares two ESMF_GridDecompType statuses to see if ! they are equivalent. ! ! The arguments are: ! \begin{description} ! \item[GridDecomp1, GridDecomp2] ! Two igrid statuses to compare for equality ! \end{description} ! !EOPI ESMF_GridDecompEqual = (GridDecomp1%griddecomptype == & GridDecomp2%griddecomptype) end function ESMF_GridDecompEqual !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridDecompNotEqual" !BOPI ! !IROUTINE: ESMF_GridDecompNotEqual - Non-equality of GridDecomps ! ! !INTERFACE: function ESMF_GridDecompNotEqual(GridDecomp1, GridDecomp2) ! !RETURN VALUE: logical :: ESMF_GridDecompNotEqual ! !ARGUMENTS: type (ESMF_GridDecompType), intent(in) :: & GridDecomp1, &! Two GridDecomp Statuses to compare for GridDecomp2 ! inequality ! !DESCRIPTION: ! This routine compares two ESMF_GridDecompType statuses to see if ! they are unequal. ! ! The arguments are: ! \begin{description} ! \item[GridDecomp1, GridDecomp2] ! Two statuses of GridDecomps to compare for inequality ! \end{description} ! !EOPI ESMF_GridDecompNotEqual = (GridDecomp1%griddecomptype /= & GridDecomp2%griddecomptype) end function ESMF_GridDecompNotEqual !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridLUADefault" !BOPI ! !IROUTINE: ESMF_GridLUADefault ! !INTERFACE: subroutine ESMF_GridLUADefault(dimCount, & lWidthIn, uWidthIn, alignIn, & lWidthOut, uWidthOut, alignOut, & rc) ! ! !ARGUMENTS: integer, intent(in) :: dimCount integer, target, intent(in), optional :: lWidthIn(:) integer, target, intent(in), optional :: uWidthIn(:) integer, target, intent(in), optional :: alignIn(:) integer, target, intent(out) :: lWidthOut(:) integer, target, intent(out) :: uWidthOut(:) integer, target, intent(out) :: alignOut(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This routine sets the default values of the lwidth, uwidth, and align ! based on the user's passed in values for these. ! ! The arguments are: ! \begin{description} ! \item[{[lWidthIn]}] ! The lower width from the user. ! \item[{[uWidthIn]}] ! The upper width from the user. ! \item[{[alignIn]}] ! The lower width from the user. ! \item[{[lWidthOut]}] ! The lower width based on user input. ! \item[{[uWidthIn]}] ! The upper width based on user input. ! \item[{[alignIn]}] ! The lower width based on user input. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc ! local error status type(ESMF_InterfaceInt) :: lWidthInArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: uWidthInArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: alignInArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: lWidthOutArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: uWidthOutArg ! Language Interface Helper Var type(ESMF_InterfaceInt) :: alignOutArg ! Language Interface Helper Var ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check DimCount of gridWidths and Aligns if (present(lWidthIn)) then if (size(lWidthIn) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeLWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(uWidthIn)) then if (size(uWidthIn) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeUWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(alignIn)) then if (size(alignIn) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridAlign must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! turn to interfaceint lWidthInArg = ESMF_InterfaceIntCreate(lWidthIn, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return uWidthInArg = ESMF_InterfaceIntCreate(uWidthIn, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return alignInArg = ESMF_InterfaceIntCreate(alignIn, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return lWidthOutArg = ESMF_InterfaceIntCreate(lWidthOut, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return uWidthOutArg = ESMF_InterfaceIntCreate(uWidthOut, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return alignOutArg = ESMF_InterfaceIntCreate(alignOut, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Call C++ Subroutine for the default call c_ESMC_gridluadefault(dimCount, & lWidthInArg, uWidthInArg, alignInArg, & lWidthOutArg, uWidthOutArg, alignOutArg, & localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Deallocate helper variables call ESMF_InterfaceIntDestroy(lWidthInArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(uWidthInArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(alignInArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(lWidthOutArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(uWidthOutArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_InterfaceIntDestroy(alignOutArg, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridLUADefault !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridLUA1PeriDim" !BOPI ! !IROUTINE: ESMF_GridLUA1PeriDim ! !INTERFACE: subroutine ESMF_GridLUA1PeriDim(dimCount, periodicDim, & lWidthIn, uWidthIn, alignIn, & lWidthOut, uWidthOut, alignOut, & rc) ! ! !ARGUMENTS: integer, intent(in) :: dimCount integer, intent(in) :: periodicDim integer, target, intent(in), optional :: lWidthIn(:) integer, target, intent(in), optional :: uWidthIn(:) integer, target, intent(in), optional :: alignIn(:) integer, target, intent(out) :: lWidthOut(:) integer, target, intent(out) :: uWidthOut(:) integer, target, intent(out) :: alignOut(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This routine sets the default values of the lwidth, uwidth, and align ! based on the user's passed in values for these. ! ! The arguments are: ! \begin{description} ! \item[{[lWidthIn]}] ! The lower width from the user. ! \item[{[uWidthIn]}] ! The upper width from the user. ! \item[{[alignIn]}] ! The lower width from the user. ! \item[{[lWidthOut]}] ! The lower width based on user input. ! \item[{[uWidthIn]}] ! The upper width based on user input. ! \item[{[alignIn]}] ! The lower width based on user input. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc ! local error status localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check DimCount of gridWidths and Aligns if (present(lWidthIn)) then if (size(lWidthIn) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeLWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif if (lWidthIn(periodicDim) /= 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeLWidth must be of size 0 on the periodic dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(uWidthIn)) then if (size(uWidthIn) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeUWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif if (uWidthIn(periodicDim) /= 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeUWidth must be of size 0 on the periodic dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif endif call ESMF_GridLUADefault(dimCount, & lWidthIn, uWidthIn, alignIn, & lWidthOut, uWidthOut, alignOut, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Make default 0 for periodic dimension lWidthOut(periodicDim)=0 uWidthOut(periodicDim)=0 ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridLUA1PeriDim !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridLUA2PeriDim" !BOPI ! !IROUTINE: ESMF_GridLUA2PeriDim ! !INTERFACE: subroutine ESMF_GridLUA2PeriDim(dimCount, & periodicDim1, periodicDim2, & lWidthIn, uWidthIn, alignIn, & lWidthOut, uWidthOut, alignOut, & rc) ! ! !ARGUMENTS: integer, intent(in) :: dimCount integer, intent(in) :: periodicDim1 integer, intent(in) :: periodicDim2 integer, target, intent(in), optional :: lWidthIn(:) integer, target, intent(in), optional :: uWidthIn(:) integer, target, intent(in), optional :: alignIn(:) integer, target, intent(out) :: lWidthOut(:) integer, target, intent(out) :: uWidthOut(:) integer, target, intent(out) :: alignOut(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! This routine sets the default values of the lwidth, uwidth, and align ! based on the user's passed in values for these. ! ! The arguments are: ! \begin{description} ! \item[{[lWidthIn]}] ! The lower width from the user. ! \item[{[uWidthIn]}] ! The upper width from the user. ! \item[{[alignIn]}] ! The lower width from the user. ! \item[{[lWidthOut]}] ! The lower width based on user input. ! \item[{[uWidthIn]}] ! The upper width based on user input. ! \item[{[alignIn]}] ! The lower width based on user input. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc ! local error status localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check DimCount of gridWidths and Aligns if (present(lWidthIn)) then if (size(lWidthIn) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeLWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif if (lWidthIn(periodicDim1) /= 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeLWidth must be of size 0 on a periodic dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif if (lWidthIn(periodicDim2) /= 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeLWidth must be of size 0 on a periodic dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(uWidthIn)) then if (size(uWidthIn) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeUWidth must be of size equal to Grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif if (uWidthIn(periodicDim1) /= 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeUWidth must be of size 0 on a periodic dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif if (uWidthIn(periodicDim2) /= 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- gridEdgeUWidth must be of size 0 on a periodic dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif endif call ESMF_GridLUADefault(dimCount, & lWidthIn, uWidthIn, alignIn, & lWidthOut, uWidthOut, alignOut, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Make default 0 for periodic dimension lWidthOut(periodicDim1)=0 lWidthOut(periodicDim2)=0 uWidthOut(periodicDim1)=0 uWidthOut(periodicDim2)=0 ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridLUA2PeriDim !------------------------------------------------------------------------------ ! --------------------------------------------- ------------------------------- #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridSetDestroyDistgrid()" !BOPI ! !IROUTINE: ESMF_GridSetDestroyDistgrid ! !INTERFACE: subroutine ESMF_GridSetDestroyDistgrid(grid,destroy, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid logical, intent(in) :: destroy integer, intent(out), optional :: rc ! ! ! !DESCRIPTION: ! !EOPI !------------------------------------------------------------------------------ integer :: localrc ! local return code integer :: destroyInt ! initialize return code; assume routine not implemented localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! set int from logical if (destroy) then destroyInt=1 else destroyInt=0 endif ! Call into the C++ interface, which will sort out optional arguments. call c_esmc_gridsetdestroydistgrid(grid, destroyInt); ! return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridSetDestroyDistgrid !------------------------------------------------------------------------------ ! --------------------------------------------- ------------------------------- #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridSetDestroyDELayout()" !BOPI ! !IROUTINE: ESMF_GridSetDestroyDELayout ! !INTERFACE: subroutine ESMF_GridSetDestroyDELayout(grid,destroy, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid logical, intent(in) :: destroy integer, intent(out), optional :: rc ! ! ! !DESCRIPTION: ! !EOPI !------------------------------------------------------------------------------ integer :: localrc ! local return code integer :: destroyInt ! initialize return code; assume routine not implemented localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! set int from logical if (destroy) then destroyInt=1 else destroyInt=0 endif ! Call into the C++ interface, which will sort out optional arguments. call c_esmc_gridsetdestroydelayout(grid, destroyInt); ! return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridSetDestroyDELayout !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridStatusEqual" !BOPI ! !IROUTINE: ESMF_GridStatusEqual - Equality of GridStatus statuses ! ! !INTERFACE: function ESMF_GridStatusEqual(GridStatus1, GridStatus2) ! !RETURN VALUE: logical :: ESMF_GridStatusEqual ! !ARGUMENTS: type (ESMF_GridStatus_Flag), intent(in) :: & GridStatus1, &! Two igrid statuses to compare for GridStatus2 ! equality ! !DESCRIPTION: ! This routine compares two ESMF GridStatus statuses to see if ! they are equivalent. ! ! The arguments are: ! \begin{description} ! \item[GridStatus1, GridStatus2] ! Two igrid statuses to compare for equality ! \end{description} ! !EOPI ESMF_GridStatusEqual = (GridStatus1%gridstatus == & GridStatus2%gridstatus) end function ESMF_GridStatusEqual !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridStatusNotEqual" !BOPI ! !IROUTINE: ESMF_GridStatusNotEqual - Non-equality of GridStatus statuses ! ! !INTERFACE: function ESMF_GridStatusNotEqual(GridStatus1, GridStatus2) ! !RETURN VALUE: logical :: ESMF_GridStatusNotEqual ! !ARGUMENTS: type (ESMF_GridStatus_Flag), intent(in) :: & GridStatus1, &! Two GridStatus Statuses to compare for GridStatus2 ! inequality ! !DESCRIPTION: ! This routine compares two ESMF GridStatus statuses to see if ! they are unequal. ! ! The arguments are: ! \begin{description} ! \item[GridStatus1, GridStatus2] ! Two statuses of GridStatuss to compare for inequality ! \end{description} ! !EOPI ESMF_GridStatusNotEqual = (GridStatus1%gridstatus /= & GridStatus2%gridstatus) end function ESMF_GridStatusNotEqual !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridStatusGreater" !BOPI ! !IROUTINE: ESMF_GridStatusGreater - Equality of GridStatus statuses ! ! !INTERFACE: function ESMF_GridStatusGreater(GridStatus1, GridStatus2) ! !RETURN VALUE: logical :: ESMF_GridStatusGreater ! !ARGUMENTS: type (ESMF_GridStatus_Flag), intent(in) :: & GridStatus1, &! Two igrid statuses to compare for GridStatus2 ! equality ! !DESCRIPTION: ! This routine compares two ESMF GridStatus statuses to see if ! they are equivalent. ! ! The arguments are: ! \begin{description} ! \item[GridStatus1, GridStatus2] ! Two igrid statuses to compare for equality ! \end{description} ! !EOPI ESMF_GridStatusGreater = (GridStatus1%gridstatus > & GridStatus2%gridstatus) end function ESMF_GridStatusGreater !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridStatusLess" !BOPI ! !IROUTINE: ESMF_GridStatusLess - Non-equality of GridStatus statuses ! ! !INTERFACE: function ESMF_GridStatusLess(GridStatus1, GridStatus2) ! !RETURN VALUE: logical :: ESMF_GridStatusLess ! !ARGUMENTS: type (ESMF_GridStatus_Flag), intent(in) :: & GridStatus1, &! Two GridStatus Statuses to compare for GridStatus2 ! inequality ! !DESCRIPTION: ! This routine compares two ESMF GridStatus statuses to see if ! they are unequal. ! ! The arguments are: ! \begin{description} ! \item[GridStatus1, GridStatus2] ! Two statuses of GridStatuss to compare for inequality ! \end{description} ! !EOPI ESMF_GridStatusLess = (GridStatus1%gridstatus .lt. & GridStatus2%gridstatus) end function ESMF_GridStatusLess !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridStatusGreaterEqual" !BOPI ! !IROUTINE: ESMF_GridStatusGreaterEqual - Greater than or equal of GridStatus statuses ! ! !INTERFACE: function ESMF_GridStatusGreaterEqual(GridStatus1, GridStatus2) ! !RETURN VALUE: logical :: ESMF_GridStatusGreaterEqual ! !ARGUMENTS: type (ESMF_GridStatus_Flag), intent(in) :: & GridStatus1, &! Two igrid statuses to compare for GridStatus2 ! equality ! !DESCRIPTION: ! This routine compares two ESMF GridStatus statuses to see if ! they are equivalent. ! ! The arguments are: ! \begin{description} ! \item[GridStatus1, GridStatus2] ! Two igrid statuses to compare ! \end{description} ! !EOPI ESMF_GridStatusGreaterEqual = (GridStatus1%gridstatus >= & GridStatus2%gridstatus) end function ESMF_GridStatusGreaterEqual !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridStatusLessEqual" !BOPI ! !IROUTINE: ESMF_GridStatusLessEqual - Less than or equal of GridStatus statuses ! ! !INTERFACE: function ESMF_GridStatusLessEqual(GridStatus1, GridStatus2) ! !RETURN VALUE: logical :: ESMF_GridStatusLessEqual ! !ARGUMENTS: type (ESMF_GridStatus_Flag), intent(in) :: & GridStatus1, &! Two GridStatus Statuses to compare for GridStatus2 ! inequality ! !DESCRIPTION: ! This routine compares two ESMF GridStatus statuses to see if ! they are unequal. ! ! The arguments are: ! \begin{description} ! \item[GridStatus1, GridStatus2] ! Two statuses of GridStatuss to compare ! \end{description} ! !EOPI ESMF_GridStatusLessEqual = (GridStatus1%gridstatus .le. & GridStatus2%gridstatus) end function ESMF_GridStatusLessEqual !! GRIDMATCH !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridMatchEqual" !BOPI ! !IROUTINE: ESMF_GridMatchEqual - Equality of GridMatch statuses ! ! !INTERFACE: function ESMF_GridMatchEqual(GridMatch1, GridMatch2) ! !RETURN VALUE: logical :: ESMF_GridMatchEqual ! !ARGUMENTS: type (ESMF_GridMatch_Flag), intent(in) :: & GridMatch1, &! Two igrid statuses to compare for GridMatch2 ! equality ! !DESCRIPTION: ! This routine compares two ESMF GridMatch statuses to see if ! they are equivalent. ! ! The arguments are: ! \begin{description} ! \item[GridMatch1, GridMatch2] ! Two igrid statuses to compare for equality ! \end{description} ! !EOPI ESMF_GridMatchEqual = (GridMatch1%gridmatch == & GridMatch2%gridmatch) end function ESMF_GridMatchEqual !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridMatchNotEqual" !BOPI ! !IROUTINE: ESMF_GridMatchNotEqual - Non-equality of GridMatch statuses ! ! !INTERFACE: function ESMF_GridMatchNotEqual(GridMatch1, GridMatch2) ! !RETURN VALUE: logical :: ESMF_GridMatchNotEqual ! !ARGUMENTS: type (ESMF_GridMatch_Flag), intent(in) :: & GridMatch1, &! Two GridMatch Statuses to compare for GridMatch2 ! inequality ! !DESCRIPTION: ! This routine compares two ESMF GridMatch statuses to see if ! they are unequal. ! ! The arguments are: ! \begin{description} ! \item[GridMatch1, GridMatch2] ! Two statuses of GridMatchs to compare for inequality ! \end{description} ! !EOPI ESMF_GridMatchNotEqual = (GridMatch1%gridmatch /= & GridMatch2%gridmatch) end function ESMF_GridMatchNotEqual !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridMatchGreater" !BOPI ! !IROUTINE: ESMF_GridMatchGreater - Equality of GridMatch statuses ! ! !INTERFACE: function ESMF_GridMatchGreater(GridMatch1, GridMatch2) ! !RETURN VALUE: logical :: ESMF_GridMatchGreater ! !ARGUMENTS: type (ESMF_GridMatch_Flag), intent(in) :: & GridMatch1, &! Two igrid statuses to compare for GridMatch2 ! equality ! !DESCRIPTION: ! This routine compares two ESMF GridMatch statuses to see if ! they are equivalent. ! ! The arguments are: ! \begin{description} ! \item[GridMatch1, GridMatch2] ! Two igrid statuses to compare for equality ! \end{description} ! !EOPI ESMF_GridMatchGreater = (GridMatch1%gridmatch > & GridMatch2%gridmatch) end function ESMF_GridMatchGreater !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridMatchLess" !BOPI ! !IROUTINE: ESMF_GridMatchLess - Non-equality of GridMatch statuses ! ! !INTERFACE: function ESMF_GridMatchLess(GridMatch1, GridMatch2) ! !RETURN VALUE: logical :: ESMF_GridMatchLess ! !ARGUMENTS: type (ESMF_GridMatch_Flag), intent(in) :: & GridMatch1, &! Two GridMatch Statuses to compare for GridMatch2 ! inequality ! !DESCRIPTION: ! This routine compares two ESMF GridMatch statuses to see if ! they are unequal. ! ! The arguments are: ! \begin{description} ! \item[GridMatch1, GridMatch2] ! Two statuses of GridMatchs to compare for inequality ! \end{description} ! !EOPI ESMF_GridMatchLess = (GridMatch1%gridmatch .lt. & GridMatch2%gridmatch) end function ESMF_GridMatchLess !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridMatchGreaterEqual" !BOPI ! !IROUTINE: ESMF_GridMatchGreaterEqual - Greater than or equal of GridMatch statuses ! ! !INTERFACE: function ESMF_GridMatchGreaterEqual(GridMatch1, GridMatch2) ! !RETURN VALUE: logical :: ESMF_GridMatchGreaterEqual ! !ARGUMENTS: type (ESMF_GridMatch_Flag), intent(in) :: & GridMatch1, &! Two igrid statuses to compare for GridMatch2 ! equality ! !DESCRIPTION: ! This routine compares two ESMF GridMatch statuses to see if ! they are equivalent. ! ! The arguments are: ! \begin{description} ! \item[GridMatch1, GridMatch2] ! Two igrid statuses to compare ! \end{description} ! !EOPI ESMF_GridMatchGreaterEqual = (GridMatch1%gridmatch >= & GridMatch2%gridmatch) end function ESMF_GridMatchGreaterEqual !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridMatchLessEqual" !BOPI ! !IROUTINE: ESMF_GridMatchLessEqual - Less than or equal of GridMatch statuses ! ! !INTERFACE: function ESMF_GridMatchLessEqual(GridMatch1, GridMatch2) ! !RETURN VALUE: logical :: ESMF_GridMatchLessEqual ! !ARGUMENTS: type (ESMF_GridMatch_Flag), intent(in) :: & GridMatch1, &! Two GridMatch Statuses to compare for GridMatch2 ! inequality ! !DESCRIPTION: ! This routine compares two ESMF GridMatch statuses to see if ! they are unequal. ! ! The arguments are: ! \begin{description} ! \item[GridMatch1, GridMatch2] ! Two statuses of GridMatchs to compare ! \end{description} ! !EOPI ESMF_GridMatchLessEqual = (GridMatch1%gridmatch .le. & GridMatch2%gridmatch) end function ESMF_GridMatchLessEqual #if 0 ! -------------------------- ESMF-public method ------------------------------- #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridTest()" !BOPI ! !IROUTINE: ESMF_GridTest - Test Grid internals ! !INTERFACE: subroutine ESMF_GridTest(grid, rc) ! ! !ARGUMENTS: type(ESMF_Grid), intent(in) :: grid integer, intent(out), optional :: rc ! ! ! !DESCRIPTION: ! TEST SUBROUTINE FOR INTERNAL ESMF USE ONLY ! !EOPI !------------------------------------------------------------------------------ integer :: localrc ! local return code ! initialize return code; assume routine not implemented localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_GridGetInit, grid, rc) ! Call into the C++ interface, which will sort out optional arguments. call c_ESMC_GridTest(grid, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_GridTest !------------------------------------------------------------------------------ #endif !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreateDistgridIrreg" !BOPI ! !IROUTINE: ESMF_GridCreateDistgridIrreg - an internal routine to create a irreg distgrid ! !INTERFACE: function ESMF_GridCreateDistgridIrreg(dimCount, & minIndex, maxIndex, & countsPerDEDim1,countsPerDeDim2, & countsPerDEDim3, & indexflag, petMap, connList, rc) ! ! !RETURN VALUE: type(ESMF_DistGrid) :: ESMF_GridCreateDistgridIrreg ! ! !ARGUMENTS: integer, intent(in) :: dimCount integer, intent(in) :: minIndex(:) integer, intent(in) :: maxIndex(:) integer, intent(in) :: countsPerDEDim1(:) integer, intent(in) :: countsPerDEDim2(:) integer, intent(in), optional :: countsPerDEDim3(:) type(ESMF_Index_Flag), intent(in), optional :: indexflag integer, intent(in), optional :: petMap(:,:,:) type(ESMF_DistgridConnection), intent(in), optional :: connList(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This is an internal method to create a single tile, irregularly distributed distgrid ! (see Figure \ref{fig:GridDecomps}). ! To specify the irregular distribution, the user passes in an array ! for each grid dimension, where the length of the array is the number ! of DEs in the dimension. Up to three dimensions can be specified, ! using the countsPerDEDim1, countsPerDEDim2, countsPerDEDim3 arguments. ! The index of each array element corresponds to a DE number. The ! array value at the index is the number of grid cells on the DE in ! that dimension. The dimCount of the grid is equal to the number of ! countsPerDEDim arrays that are specified. ! ! Section \ref{example:2DIrregUniGrid} shows an example ! of using this method to create a 2D Grid with uniformly spaced ! coordinates. This creation method can also be used as the basis for ! grids with rectilinear coordinates or curvilinear coordinates. ! ! The arguments are: ! \begin{description} ! \item[{minIndex}] ! Tuple to start the index ranges at. If not present, defaults ! to /1,1,1,.../. ! \item[{maxIndex}] ! Tuple to end the index ranges at. ! \item[{countsPerDEDim1}] ! This arrays specifies the number of cells per DE for index dimension 1 ! for the exclusive region (the center stagger location). ! \item[{countsPerDEDim2}] ! This array specifies the number of cells per DE for index dimension 2 ! for the exclusive region (center stagger location). ! \item[{[countsPerDEDim3]}] ! This array specifies the number of cells per DE for index dimension 3 ! for the exclusive region (center stagger location). ! If not specified then grid is 2D. ! \item[{[indexflag]}] ! Indicates the indexing scheme to be used in the new Grid. Please see ! Section~\ref{const:indexflag} for the list of options. If not present, ! defaults to ESMF\_INDEX\_DELOCAL. ! \item[{[petMap]}] ! \begin{sloppypar} ! Sets the mapping of pets to the created DEs. This 3D ! should be of size size(countsPerDEDim1) x size(countsPerDEDim2) x ! size(countsPerDEDim3). If countsPerDEDim3 isn't present, then ! the last dimension is of size 1. ! \end{sloppypar} ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI type(ESMF_DistGrid) :: distgrid type(ESMF_DELayout) :: delayout integer, pointer :: petList(:) integer :: localrc integer :: i,maxSizeDEDim integer, pointer :: deDimCount(:) integer, pointer :: countsPerDEDim1Local(:) integer, pointer :: countsPerDEDim2Local(:) integer, pointer :: countsPerDEDim3Local(:) integer, pointer :: deBlockList(:,:,:),minPerDEDim(:,:),maxPerDEDim(:,:) integer :: deCount integer :: d,i1,i2,i3,k integer :: top ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! error checking if (present(petMap)) then if (dimCount > 2) then if ((size(petMap,1) /= size(countsPerDEDim1)) .or. & (size(petMap,2) /= size(countsPerDEDim2)) .or. & (size(petMap,3) /= size(countsPerDEDim3))) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif else if ((size(petMap,1) /= size(countsPerDEDim1)) .or. & (size(petMap,2) /= size(countsPerDEDim2)) .or. & (size(petMap,3) /= 1)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif ! Copy vales for countsPerDEDim -------------------------------------------- allocate(countsPerDEDim1Local(size(countsPerDEDim1)), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating countsPerDEDim1Local", & ESMF_CONTEXT, rcToReturn=rc)) return countsPerDEDim1Local=countsPerDEDim1 allocate(countsPerDEDim2Local(size(countsPerDEDim2)), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating countsPerDEDim2Local", & ESMF_CONTEXT, rcToReturn=rc)) return countsPerDEDim2Local=countsPerDEDim2 if (dimCount > 2) then allocate(countsPerDEDim3Local(size(countsPerDEDim3)), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating countsPerDEDim3Local", & ESMF_CONTEXT, rcToReturn=rc)) return countsPerDEDim3Local=countsPerDEDim3 endif ! Setup deBlockList for DistGrid ------------------------------------------------ ! count de blocks deCount=1 deCount=deCount*size(countsPerDEDim1Local) deCount=deCount*size(countsPerDEDim2Local) if (dimCount > 2) then deCount=deCount*size(countsPerDEDim3Local) endif ! Calc the max size of a DEDim maxSizeDEDim=1 if (size(countsPerDEDim1Local) > maxSizeDEDim) then maxSizeDEDim=size(countsPerDEDim1Local) endif if (size(countsPerDEDim2Local) > maxSizeDEDim) then maxSizeDEDim=size(countsPerDEDim2Local) endif if (dimCount > 2) then if (size(countsPerDEDim3Local) > maxSizeDEDim) then maxSizeDEDim=size(countsPerDEDim3Local) endif endif ! generate deblocklist allocate(maxPerDEDim(dimCount,maxSizeDEDim), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxPerDEDim", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(minPerDEDim(dimCount,maxSizeDEDim), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minPerDEDim", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(deDimCount(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxPerDEDim", & ESMF_CONTEXT, rcToReturn=rc)) return ! Calc the maximum end of each DE in a Dim, and the size of each DEDim d=1 deDimCount(d)=size(countsPerDEDim1Local) minPerDeDim(d,1)=minIndex(d) maxPerDeDim(d,1)=minIndex(d)+countsPerDEDim1Local(1)-1 do i=2,deDimCount(d) minPerDEDim(d,i)=maxPerDEDim(d,i-1)+1 maxPerDEDim(d,i)=minPerDEDim(d,i)+countsPerDEDim1Local(i)-1 enddo d=2 deDimCount(d)=size(countsPerDEDim2Local) minPerDeDim(d,1)=minIndex(d) maxPerDeDim(d,1)=minIndex(d)+countsPerDEDim2Local(1)-1 do i=2,deDimCount(d) minPerDEDim(d,i)=maxPerDEDim(d,i-1)+1 maxPerDEDim(d,i)=minPerDEDim(d,i)+countsPerDEDim2Local(i)-1 enddo if (dimCount > 2) then d=3 deDimCount(d)=size(countsPerDEDim3Local) minPerDeDim(d,1)=minIndex(d) maxPerDeDim(d,1)=minIndex(d)+countsPerDEDim3Local(1)-1 do i=2,deDimCount(d) minPerDEDim(d,i)=maxPerDEDim(d,i-1)+1 maxPerDEDim(d,i)=minPerDEDim(d,i)+countsPerDEDim3Local(i)-1 enddo endif ! allocate deblocklist allocate(deBlockList(dimCount,2,deCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating deBlockList", & ESMF_CONTEXT, rcToReturn=rc)) return ! Fill in DeBlockList if (dimCount == 2) then k=1 do i2=1,deDimCount(2) do i1=1,deDimCount(1) deBlockList(1,1,k)=minPerDEDim(1,i1) deBlockList(1,2,k)=maxPerDEDim(1,i1) deBlockList(2,1,k)=minPerDEDim(2,i2) deBlockList(2,2,k)=maxPerDEDim(2,i2) k=k+1 enddo enddo else if (dimCount == 3) then k=1 do i3=1,deDimCount(3) do i2=1,deDimCount(2) do i1=1,deDimCount(1) deBlockList(1,1,k)=minPerDEDim(1,i1) deBlockList(1,2,k)=maxPerDEDim(1,i1) deBlockList(2,1,k)=minPerDEDim(2,i2) deBlockList(2,2,k)=maxPerDEDim(2,i2) deBlockList(3,1,k)=minPerDEDim(3,i3) deBlockList(3,2,k)=maxPerDEDim(3,i3) k=k+1 enddo enddo enddo endif ! do i=1,deCount ! write(*,*) i,"min=",deBlockList(:,1,i)," max=",deBlockList(:,2,i) ! enddo ! Process PetMap -------------------------------------------------------------- if (present(petMap)) then !! Allocate petList allocate(petList(deCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating petList", & ESMF_CONTEXT, rcToReturn=rc)) return !! copy petMap to petList if (dimCount > 2) then k=1 do i3=1,size(countsPerDEDim3Local) do i2=1,size(countsPerDEDim2Local) do i1=1,size(countsPerDEDim1Local) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo else k=1 do i3=1,1 do i2=1,size(countsPerDEDim2Local) do i1=1,size(countsPerDEDim1Local) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo endif !! create delayout from the petList delayout=ESMF_DELayoutCreate(petList=petList,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Get rid of list deallocate(petList) else !! create a default delayout delayout=ESMF_DELayoutCreate(deCount=deCount,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Create DistGrid -------------------------------------------------------------- ESMF_GridCreateDistgridIrreg=ESMF_DistGridCreate(minIndex=minIndex, maxIndex=maxIndex, & deBlockList=deBlockList, delayout=delayout, indexflag=indexflag, & connectionList=connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(maxPerDEDim) deallocate(minPerDEDim) deallocate(deDimCount) deallocate(deBlockList) deallocate(countsPerDEDim1Local) deallocate(countsPerDEDim2Local) if (dimCount > 2) then deallocate(countsPerDEDim3Local) endif ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateDistgridIrreg !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "GetIndexSpaceIrreg" !BOPI ! !IROUTINE: GetIndexSpaceIrreg - get the dimcount, min and max index ! !INTERFACE: subroutine GetIndexSpaceIrreg(minIndex, & countsPerDEDim1,countsPerDeDim2, & countsPerDEDim3, dimCount, minIndexOut, maxIndexOut, rc) !! ! !ARGUMENTS: integer, intent(in), optional :: minIndex(:) integer, intent(in) :: countsPerDEDim1(:) integer, intent(in) :: countsPerDEDim2(:) integer, intent(in), optional :: countsPerDEDim3(:) integer, intent(inout) :: dimCount integer, pointer :: minIndexOut(:) integer, pointer :: maxIndexOut(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This is a routine to calculate the minIndex and maxIndex of an irregular distribution. ! The arguments are: ! \begin{description} ! \item[{[minIndex]}] ! Tuple to start the index ranges at. If not present, defaults ! to /1,1,1,.../. ! \item[{countsPerDEDim1}] ! This arrays specifies the number of cells per DE for index dimension 1 ! for the exclusive region (the center stagger location). ! \item[{countsPerDEDim2}] ! This array specifies the number of cells per DE for index dimension 2 ! for the exclusive region (center stagger location). ! \item[{[countsPerDEDim3]}] ! This array specifies the number of cells per DE for index dimension 3 ! for the exclusive region (center stagger location). ! If not specified then grid is 2D. ! \item[{minIndexOut}] ! MinIndex of range, needs to be allocated to dimCount. ! \item[{maxIndexOut}] ! MaxIndex of range, needs to be allocated to dimCount. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc integer :: i ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Compute the Grid DimCount ! dimCount if (present(countsPerDEDim3)) then dimCount=3 else dimCount=2 endif ! Argument Consistency Checking if (size(countsPerDEDim1) .lt. 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- size 0 countsPerDEDim1 not allowed", & ESMF_CONTEXT, rcToReturn=rc) return endif if (size(countsPerDEDim2) .lt. 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- size 0 countsPerDEDim2 not allowed", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(countsPerDEDim3)) then if (size(countsPerDEDim3) .lt. 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- size 0 countsPerDEDim3 not allowed", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(minIndex)) then if (size(minIndex) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- minIndex size must equal grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Allocate minIndex allocate(minIndexOut(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexOut", & ESMF_CONTEXT, rcToReturn=rc)) return ! Set minIndex if (present(minIndex)) then minIndexOut(:)=minIndex(:) else do i=1,dimCount minIndexOut(i)=1 enddo endif ! Allocate maxIndex allocate(maxIndexOut(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxIndexOut", & ESMF_CONTEXT, rcToReturn=rc)) return ! Set maxIndex maxIndexOut(1)=sum(countsPerDEDim1)+minIndexOut(1)-1 maxIndexOut(2)=sum(countsPerDEDim2)+minIndexOut(2)-1 if (dimCount > 2) then maxIndexOut(3)=sum(countsPerDEDim3)+minIndexOut(3)-1 endif ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine GetIndexSpaceIrreg !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreateDistgridReg" !BOPI ! !IROUTINE: ESMF_GridCreateDistgrid - Create a Distgrid with a regular distribution ! !INTERFACE: function ESMF_GridCreateDistgridReg(dimCount, minIndex, maxIndex, regDecomp, decompFlag, & indexflag, petMap, connList, rc) ! ! !RETURN VALUE: type(ESMF_Distgrid) :: ESMF_GridCreateDistgridReg ! ! !ARGUMENTS: integer :: dimCount integer, intent(in) :: minIndex(:) integer, intent(in) :: maxIndex(:) integer, intent(in), optional :: regDecomp(:) type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) type(ESMF_Index_Flag), intent(in), optional :: indexflag integer, intent(in), optional :: petMap(:,:,:) type(ESMF_DistgridConnection), intent(in), optional :: connList(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This internal method creates a single tile, regularly distributed distgrid ! (see Figure \ref{fig:GridDecomps}). ! To specify the distribution, the user passes in an array ! ({\tt regDecomp}) specifying the number of DEs to divide each ! dimension into. The array {\tt decompFlag} indicates how the division into DEs is to ! occur. The default is to divide the range as evenly as possible. ! ! The arguments are: ! \begin{description} ! \item[{[regDecomp]}] ! List that has the same number of elements as {\tt maxIndex}. ! Each entry is the number of decounts for that dimension. ! If not specified, the default decomposition will be petCountx1x1..x1. ! \item[{[decompflag]}] ! List of decomposition flags indicating how each dimension of the ! tile is to be divided between the DEs. The default setting ! is {\tt ESMF\_DECOMP\_BALANCED} in all dimensions. Please see ! Section~\ref{const:decompflag} for a full description of the ! possible options. ! \item[{minIndex}] ! The bottom extent of the grid array. If not given then the value defaults ! to /1,1,1,.../. ! \item[{maxIndex}] ! The upper extent of the grid array. ! \item[{[indexflag]}] ! Indicates the indexing scheme to be used in the new Grid. Please see ! Section~\ref{const:indexflag} for the list of options. If not present, ! defaults to ESMF\_INDEX\_DELOCAL. ! \item[{[petMap]}] ! Sets the mapping of pets to the created DEs. This 3D ! should be of size regDecomp(1) x regDecomp(2) x regDecomp(3) ! If the Grid is 2D, then the last dimension is of size 1. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI type(ESMF_DELayout) :: delayout type(ESMF_VM) :: vm integer, pointer :: petList(:) integer :: localrc integer :: i integer, pointer :: regDecompLocal(:) type(ESMF_Decomp_Flag), pointer :: decompflagLocal(:) integer, pointer :: minIndexLocal(:), maxIndexLocal(:) integer :: deCount integer :: i1,i2,i3,k ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Argument Consistency Checking -------------------------------------------------------------- if (present(regDecomp)) then if (size(regDecomp) .lt. dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- regDecomp size doesn't match Grid dimCount ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(decompFlag)) then if (size(decompFlag) .lt. dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- decompFlag size doesn't match Grid dimCount ", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Set default for regDecomp allocate(regDecompLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating regDecompLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(regDecomp)) then regDecompLocal(:)=regDecomp(:) else ! The default is 1D divided among all the Pets call ESMF_VMGetGlobal(vm,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_VMGet(vm,petCount=regDecompLocal(1),rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return do i=2,dimCount regDecompLocal(i)=1 enddo endif if (present(petMap)) then if (dimCount > 2) then if ((size(petMap,1) /= regDecompLocal(1)) .or. & (size(petMap,2) /= regDecompLocal(2)) .or. & (size(petMap,3) /= regDecompLocal(3))) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif else if ((size(petMap,1) /= regDecompLocal(1)) .or. & (size(petMap,2) /= regDecompLocal(2)) .or. & (size(petMap,3) /= 1)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- petMap wrong size in one or more dimensions", & ESMF_CONTEXT, rcToReturn=rc) return endif endif endif ! Set default for decomp flag based on gridEdgeWidths ----------------------------------- ! NOTE: This is a temporary fix until we have something better implemented in distGrid ! Set default for decompFlag allocate(decompFlagLocal(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating decompFlagLocal", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(decompFlag)) then decompFlagLocal(:)=decompFlag(:) else decompFlagLocal(:)=ESMF_DECOMP_BALANCED endif ! Process PetMap -------------------------------------------------------------- !! Calculate deCount deCount=1 do i=1,dimCount deCount=deCount*regDecompLocal(i) enddo ! create DELayout based on presence of petMap if (present(petMap)) then !! Allocate petList allocate(petList(deCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating petList", & ESMF_CONTEXT, rcToReturn=rc)) return !! copy petMap to petList if (dimCount > 2) then k=1 do i3=1,regDecompLocal(3) do i2=1,regDecompLocal(2) do i1=1,regDecompLocal(1) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo else k=1 do i3=1,1 do i2=1,regDecompLocal(2) do i1=1,regDecompLocal(1) petList(k)=petMap(i1,i2,i3) k=k+1 enddo enddo enddo endif !! create delayout from the petList delayout=ESMF_DELayoutCreate(petList=petList,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !! Get rid of list deallocate(petList) else !! create a default delayout delayout=ESMF_DELayoutCreate(deCount=deCount,rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Create DistGrid -------------------------------------------------------------- ESMF_GridCreateDistgridReg=ESMF_DistGridCreate(minIndex=minIndex, maxIndex=maxIndex, & regDecomp=regDecompLocal, decompFlag=decompFlagLocal, delayout=delayout,& indexflag=indexflag, & connectionList=connList, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Clean up memory deallocate(regDecompLocal) deallocate(decompFlagLocal) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateDistgridReg !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "GetIndexSpaceReg" !BOPI ! !IROUTINE: GetIndexSpaceReg - Get the index space for a regular distribution ! !INTERFACE: subroutine GetIndexSpaceReg(minIndex, maxIndex, & dimCount, minIndexOut, maxIndexOut, rc) ! ! !ARGUMENTS: integer, intent(in), optional :: minIndex(:) integer, intent(in) :: maxIndex(:) integer, intent(inout) :: dimCount integer, pointer :: minIndexOut(:) integer, pointer :: maxIndexOut(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This internal method creates a single tile, regularly distributed distgrid ! (see Figure \ref{fig:GridDecomps}). ! To specify the distribution, the user passes in an array ! ({\tt regDecomp}) specifying the number of DEs to divide each ! dimension into. The array {\tt decompFlag} indicates how the division into DEs is to ! occur. The default is to divide the range as evenly as possible. ! ! The arguments are: ! \begin{description} ! \item[{[minIndex]}] ! The bottom extent of the grid array. If not given then the value defaults ! to /1,1,1,.../. ! \item[{maxIndex}] ! The upper extent of the grid array. ! \item[{minIndexOut}] ! MinIndex of range, needs to be allocated to dimCount. ! \item[{maxIndexOut}] ! MaxIndex of range, needs to be allocated to dimCount. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc integer :: i ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Compute the Grid DimCount and Derivatives --------------------------------------------------- ! dimCount dimCount=size(maxIndex) if ((dimCount < 2) .or. (dimCount > 3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- maxIndex size and thus Grid dimCount must be either 2 or 3 when using create shape ", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(minIndex)) then if (size(minIndex) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- minIndex size must equal grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Set default for minIndex allocate(minIndexOut(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexOut", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(minIndex)) then minIndexOut(:)=minIndex(:) else do i=1,dimCount minIndexOut(i)=1 enddo endif ! Set default for maxIndex allocate(maxIndexOut(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxIndexOut", & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexOut(:)=maxIndex(:) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine GetIndexSpaceReg !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_GridCreateDistgridArb" !BOPI ! !IROUTINE: ESMF_GridCreateDistgridArg - Create a Distgrid with an arbitrary distribution ! !INTERFACE: function ESMF_GridCreateDistgridArb(dimCount, distDimCount, isDist, distDim, minIndex, & maxIndex, arbIndexCount, arbIndexList, connList, rc) ! ! !RETURN VALUE: type(ESMF_Distgrid) :: ESMF_GridCreateDistgridArb ! ! !ARGUMENTS: integer, intent(in) :: dimCount integer, intent(in) :: distDimCount logical, intent(in) :: isDist(:) integer, intent(in) :: distDim(:) integer, intent(in) :: minIndex(:) integer, intent(in) :: maxIndex(:) integer, intent(in) :: arbIndexCount integer, intent(in) :: arbIndexList(:,:) type(ESMF_DistgridConnection), intent(in), optional :: connList(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This internal method creates a single tile, arbitrarily distributed distgrid ! (see Figure \ref{fig:GridDecomps}). ! To specify the arbitrary distribution, the user passes in an 2D array ! of local indices, where the first dimension is the number of local grid cells ! specified by {\tt localArbIndexCount} and the second dimension is the number of distributed ! dimensions. ! ! {\tt distDim} specifies which grid dimensions are arbitrarily distributed. The ! size of {\tt distDim} has to agree with the size of the second dimension of ! {\tt localArbIndex}. ! ! The arguments are: ! \begin{description} ! \item[{[minIndex]}] ! Tuple to start the index ranges at. If not present, defaults ! to /1,1,1,.../. ! \item[{[maxIndex]}] ! The upper extend of the grid index ranges. ! \item[{arbIndexCount}] ! The number of grid cells in the local DE. It is okay to have 0 ! grid cell in a local DE. ! \item[{[arbIndexList]}] ! This 2D array specifies the indices of the PET LOCAL grid cells. The ! dimensions should be arbIndexCount * number of Distributed grid dimensions ! where arbIndexCount is the input argument specified below ! \item[distDim] ! This array specifies which dimensions are arbitrarily distributed. ! The size of the array specifies the total distributed dimensions. ! if not specified, defaults is all dimensions will be arbitrarily ! distributed. The size has to agree with the size of the second ! dimension of {\tt localArbIndex}. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP type(ESMF_DistGrid) :: distgrid integer, pointer :: undistLBound(:) integer, pointer :: undistUBound(:) integer :: localrc integer :: undistDimCount integer :: i,j,ud integer, pointer :: distSize(:) integer, pointer :: local1DIndices(:) integer :: ind logical :: found ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! dimCount of distributed part allocate(distSize(distDimCount),stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distSize", & ESMF_CONTEXT, rcToReturn=rc)) return do i=1,distDimCount ind = distDim(i) distSize(i)=maxIndex(ind)-minIndex(ind)+1 enddo ! dimCounts of the undistributed part of the grid undistDimCount=dimCount-distDimCount ! can't have all undistributed dimensions if (distDimCount == 0) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- Need to have at least one distributed dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif ! convert localArbIndex into 1D index array for DistGrid ! Check localArbIndex dimension matched with localArbIndexCount and diskDimCount if (size(arbIndexList, 1) /= arbIndexCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- localArbIndex 1st dimension has to match with localArbIndexCount", & ESMF_CONTEXT, rcToReturn=rc) return endif allocate(local1DIndices(arbIndexCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating local1DIndices", & ESMF_CONTEXT, rcToReturn=rc)) return if (arbIndexCount > 0) then ! use 0-based index to calculate the 1D index and add 1 back at the end do i = 1, arbIndexCount local1DIndices(i) = arbIndexList(i,1)-1 if (distDimCount >= 2) then do j = 2,distDimCount local1DIndices(i) = local1DIndices(i)*distSize(j) + arbIndexList(i,j)-1 enddo endif local1DIndices(i) = local1DIndices(i)+1 enddo endif ! Calc undistLBound, undistUBound for Grid ----------------------------------------------- if (undistDimCount > 0) then allocate(undistLBound(undistDimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating undistLBound", & ESMF_CONTEXT, rcToReturn=rc)) return allocate(undistUBound(undistDimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating undistUBound", & ESMF_CONTEXT, rcToReturn=rc)) return ! Fill in undistLBound, undistUBound ud=1 do i=1,dimCount if (.not. isDist(i)) then undistLBound(ud)=minIndex(i) undistUBound(ud)=maxIndex(i) ud=ud+1 endif enddo endif ! Create DistGrid -------------------------------------------------------------- if (undistDimCount > 0) then ESMF_GridCreateDistgridArb=ESMF_DistGridCreate(local1DIndices, 1, undistLBound, undistUBound, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return else ESMF_GridCreateDistgridArb=ESMF_DistGridCreate(local1DIndices, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! Clean up memory deallocate(local1DIndices) if (undistDimCount > 0) then deallocate(undistLBound) deallocate(undistUBound) endif deallocate(distSize) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end function ESMF_GridCreateDistgridArb !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "GetIndexSpaceArb" !BOPI ! !IROUTINE: GetIndexSpaceReg - Get the index space for a regular distribution ! !INTERFACE: subroutine GetIndexSpaceArb(minIndex, maxIndex, & arbIndexCount, arbIndexList, distDim, & dimCount, distDimCount, isDistOut, distDimOut, minIndexOut, maxIndexOut, rc) ! ! !ARGUMENTS: integer, intent(in), optional :: minIndex(:) integer, intent(in) :: maxIndex(:) integer, intent(in) :: arbIndexCount integer, intent(in) :: arbIndexList(:,:) integer, intent(in), optional :: distDim(:) integer, intent(inout) :: dimCount integer, intent(inout) :: distDimCount logical, pointer :: isDistOut(:) integer, pointer :: distDimOut(:) integer, pointer :: minIndexOut(:) integer, pointer :: maxIndexOut(:) integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! ! This internal method creates a single tile, regularly distributed distgrid ! (see Figure \ref{fig:GridDecomps}). ! To specify the distribution, the user passes in an array ! ({\tt regDecomp}) specifying the number of DEs to divide each ! dimension into. The array {\tt decompFlag} indicates how the division into DEs is to ! occur. The default is to divide the range as evenly as possible. ! ! The arguments are: ! \begin{description} ! \item[{[minIndex]}] ! The bottom extent of the grid array. If not given then the value defaults ! to /1,1,1,.../. ! \item[{maxIndex}] ! The upper extent of the grid array. ! \item[{minIndexOut}] ! MinIndex of range, needs to be allocated to dimCount. ! \item[{maxIndexOut}] ! MaxIndex of range, needs to be allocated to dimCount. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOPI integer :: localrc integer :: i ! Initialize return code; assume failure until success is certain localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Compute the Grid DimCount and Derivatives --------------------------------------------------- ! dimCount dimCount=size(maxIndex) if ((dimCount < 2) .or. (dimCount > 3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- maxIndex size and thus Grid dimCount must be either 2 or 3 when using create shape ", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Error check index size if (present(minIndex)) then if (size(minIndex) /= dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- minIndex size must equal grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! number of distributed dimension, distDimCount, is determined by the second dim of ! arbIndexList distDimCount = size(arbIndexList,2) if (distDimCount > dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- the second dim of arbIndexList must be equal or less than grid dimension", & ESMF_CONTEXT, rcToReturn=rc) return endif ! compute distributed dimensions and isDist list allocate(distDimOut(distDimCount), stat=localrc) allocate(isDistOut(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating distDimLocal or isDist", & ESMF_CONTEXT, rcToReturn=rc)) return isDistOut(:)=.false. ! check distribution info if (present(distDim)) then if (size(distDim) /= distDimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- distDim must match with the second dimension of arbIndexList", & ESMF_CONTEXT, rcToReturn=rc) return endif distDimOut(:)=distDim(:) do i=1,distDimCount isDistOut(distDimOut(i))=.true. enddo else do i=1,distDimCount distDimOut(i)=i enddo isDistOut(1:distDimCount)=.true. endif ! Set default for minIndex allocate(minIndexOut(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating minIndexOut", & ESMF_CONTEXT, rcToReturn=rc)) return if (present(minIndex)) then minIndexOut(:)=minIndex(:) else do i=1,dimCount minIndexOut(i)=1 enddo endif ! Set default for maxIndex allocate(maxIndexOut(dimCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating maxIndexOut", & ESMF_CONTEXT, rcToReturn=rc)) return maxIndexOut(:)=maxIndex(:) ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine GetIndexSpaceArb ! Internal subroutine to build coordDimMap and coordDimCount from coordDep #undef ESMF_METHOD #define ESMF_METHOD "CoordInfoFromCoordDep" subroutine CoordInfoFromCoordDep(dimCount, coordDep1, coordDep2, coordDep3,& coordDimCount, coordDimMap, rc) integer, intent(in) :: dimCount integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(out), optional :: coordDimCount(:) integer, intent(out), optional :: coordDimMap(:,:) integer,optional :: rc integer :: i ! Initialize return code; assume failure until success is certain if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Error checking if ((dimCount .lt. 3) .and. present(coordDep3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(coordDep1)) then if ((size(coordDep1) < 1) .or. (size(coordDep1)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep1 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep2)) then if ((size(coordDep2) < 1) .or. (size(coordDep2)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep2 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep3)) then if ((size(coordDep3) < 1) .or. (size(coordDep3)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep3 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Set coordDimCount and coordDimMap if (present(coordDep1)) then coordDimCount(1)=size(coordDep1) coordDimMap(1,:)=0 do i=1,size(coordDep1) coordDimMap(1,i)=coordDep1(i) enddo else coordDimCount(1)=dimCount do i=1,dimCount coordDimMap(1,i)=i enddo endif if (present(coordDep2)) then coordDimCount(2)=size(coordDep2) coordDimMap(2,:)=0 do i=1,size(coordDep2) coordDimMap(2,i)=coordDep2(i) enddo else coordDimCount(2)=dimCount do i=1,dimCount coordDimMap(2,i)=i enddo endif if (dimCount > 2) then if (present(coordDep3)) then coordDimCount(3)=size(coordDep3) coordDimMap(3,:)=0 do i=1,size(coordDep3) coordDimMap(3,i)=coordDep3(i) enddo else coordDimCount(3)=dimCount do i=1,dimCount coordDimMap(3,i)=i enddo endif endif ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine CoordInfoFromCoordDep ! Internal subroutine to build coordDimMap and coordDimCount from coordDep #undef ESMF_METHOD #define ESMF_METHOD "CoordInfoFromCoordDep" subroutine CoordInfoFromCoordDepArb(dimCount, isDist, coordDep1, coordDep2, coordDep3,& coordDimCount, coordDimMap, rc) integer, intent(in) :: dimCount logical, intent(in) :: isDist(:) integer, intent(in), optional :: coordDep1(:) integer, intent(in), optional :: coordDep2(:) integer, intent(in), optional :: coordDep3(:) integer, intent(out), optional :: coordDimCount(:) integer, intent(out), optional :: coordDimMap(:,:) integer,optional :: rc integer :: i logical :: found ! Initialize return code; assume failure until success is certain if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Error checking if ((dimCount .lt. 3) .and. present(coordDep3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep3 not allowed when grid is less than dimCount 3", & ESMF_CONTEXT, rcToReturn=rc) return endif if (present(coordDep1)) then if ((size(coordDep1) < 1) .or. (size(coordDep1)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep1 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep2)) then if ((size(coordDep2) < 1) .or. (size(coordDep2)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep2 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep3)) then if ((size(coordDep3) < 1) .or. (size(coordDep3)>dimCount)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, & msg="- coordDep3 size incompatible with grid dimCount", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(coordDep1)) then ! error checking, if this dimension is arbitrary, one of the ! coordinate dimension has to be be ESMF_DIM_ARB if (isDist(1)) then found = .false. do i=1,size(coordDep1) if (coordDep1(i) == ESMF_DIM_ARB) found = .true. enddo if (.not. found) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep1 does not contain ESMF_DIM_ARB", & ESMF_CONTEXT, rcToReturn=rc) return endif endif coordDimCount(1)=size(coordDep1) coordDimMap(1,:)=0 do i=1,size(coordDep1) coordDimMap(1,i)=coordDep1(i) enddo else coordDimCount(1)=1 ! ESMF_DIM_ARB if 1 is distributed, otherwise 1 if (isDist(1)) then coordDimMap(1,1)=ESMF_DIM_ARB else coordDimMap(1,1)=1 endif endif if (present(coordDep2)) then ! error checking, one of the dimensions has to be ESMF_DIM_ARB ! if dimension 2 is arbitrary if (isDist(2)) then found = .false. do i=1,size(coordDep2) if (coordDep2(i) == ESMF_DIM_ARB) found = .true. enddo if (.not. found) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep2 does not contain ESMF_DIM_ARB", & ESMF_CONTEXT, rcToReturn=rc) return endif endif coordDimCount(2)=size(coordDep2) coordDimMap(2,:)=0 do i=1,size(coordDep2) coordDimMap(2,i)=coordDep2(i) enddo else coordDimCount(2)=1 ! ESMF_DIM_ARB if 1 is distributed, otherwise 1 if (isDist(2)) then coordDimMap(2,1)=ESMF_DIM_ARB else coordDimMap(2,1)=2 endif endif if (dimCount > 2) then if (present(coordDep3)) then ! error checking, one of the dimensions has to be ESMF_DIM_ARB ! if dimension 3 is arbitrary if (isDist(3)) then found = .false. do i=1,size(coordDep3) if (coordDep3(i) == ESMF_DIM_ARB) found = .true. enddo if (.not. found) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_WRONG, & msg="- coordDep3 does not contain ESMF_DIM_ARB", & ESMF_CONTEXT, rcToReturn=rc) return endif endif coordDimCount(3)=size(coordDep3) coordDimMap(3,:)=0 do i=1,size(coordDep3) coordDimMap(3,i)=coordDep3(i) enddo else coordDimCount(3)=1 ! ESMF_DIM_ARB if 1 is distributed, otherwise 1 if (isDist(3)) then coordDimMap(3,1)=ESMF_DIM_ARB else coordDimMap(3,1)=3 endif endif endif ! Return successfully if (present(rc)) rc = ESMF_SUCCESS end subroutine CoordInfoFromCoordDepArb subroutine Setup1PeriodicConn(dimCount, minIndex, maxIndex, & polekindflag, periodicDim, poleDim, connList, periodicDimOut, rc) integer, intent(in) :: dimCount integer, intent(in) :: minIndex(:) integer, intent(in) :: maxIndex(:) type(ESMF_PoleKind_Flag), intent(in), optional :: polekindflag(2) integer, intent(in), optional :: periodicDim integer, intent(in), optional :: poleDim type(ESMF_DistgridConnection), pointer :: connList(:) integer, intent(out) :: periodicDimOut integer, intent(out), optional :: rc type(ESMF_PoleKind_Flag) :: polekindflagLocal(2) integer :: periodicDimLocal integer :: poleDimLocal integer :: connListCount, connListPos,i integer :: posVec(ESMF_MAXDIM) integer :: orientVec(ESMF_MAXDIM) integer :: widthIndex(ESMF_MAXDIM) integer :: localrc ! Error check input if (present(periodicDim)) then if (periodicDim .gt. dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- periodicDim must be less than or equal to dimension of Grid", & ESMF_CONTEXT, rcToReturn=rc) return endif if (periodicDim .lt. 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- periodicDim must be at least 1", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(poleDim)) then if (poleDim .gt. dimCount) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- poleDim must be less than or equal to dimension of Grid", & ESMF_CONTEXT, rcToReturn=rc) return endif if (poleDim .lt. 1) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- poleDim must be at least 1", & ESMF_CONTEXT, rcToReturn=rc) return endif endif ! Set defaults if (present(polekindflag)) then polekindflagLocal(1)=polekindflag(1) polekindflagLocal(2)=polekindflag(2) else polekindflagLocal(1)=ESMF_POLEKIND_MONOPOLE polekindflagLocal(2)=ESMF_POLEKIND_MONOPOLE endif if (present(periodicDim)) then periodicDimLocal=periodicDim else periodicDimLocal=1 endif if (present(poleDim)) then poleDimLocal=poleDim else poleDimLocal=2 endif ! ...more error checking if (periodicDimLocal == poleDimLocal) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- periodicDim must not be equal to poleDim", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Output the localperiodicDim periodicDimOut=periodicDimLocal ! calculate the count of elements in each index widthIndex=0 do i=1,dimCount widthIndex(i)=maxIndex(i)-minIndex(i)+1 enddo ! Count number of connections connListCount=1 ! for periodic dim if (polekindflagLocal(1) .ne. ESMF_POLEKIND_NONE) then connListCount=connListCount+1 endif if (polekindflagLocal(2) .ne. ESMF_POLEKIND_NONE) then connListCount=connListCount+1 endif ! Allocate connection list allocate(connList(connListCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating connList", & ESMF_CONTEXT, rcToReturn=rc)) return ! Add periodic connection posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal) call ESMF_DistgridConnectionSet(connection=connList(1), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Init orient vec do i=1,ESMF_MAXDIM orientvec(i)=i enddo ! Fill in pole connections connListPos=2 ! 2 because periodic is 1 ! Lower end if (polekindflaglocal(1) .eq. ESMF_POLEKIND_MONOPOLE) then ! do pole connection posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)/2 posVec(poleDimLocal)=1 orientVec(poleDimLocal)=-orientVec(poleDimLocal) ! make pole dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return else if (polekindflaglocal(1) .eq. ESMF_POLEKIND_BIPOLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)+1 posVec(poleDimLocal)=1 orientVec(poleDimLocal)=-orientVec(poleDimLocal) ! make pole dim - orientVec(periodicDimLocal)=-orientVec(periodicDimLocal) ! make periodic dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif connListPos=connListPos+1 ! Reinit orient vec do i=1,ESMF_MAXDIM orientvec(i)=i enddo ! Upper end if (polekindflaglocal(2) .eq. ESMF_POLEKIND_MONOPOLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)/2 posVec(poleDimLocal)=2*widthIndex(poleDimLocal)+1 orientVec(poleDimLocal)=-orientVec(poleDimLocal) ! make pole dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return else if (polekindflaglocal(2) .eq. ESMF_POLEKIND_BIPOLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)+1 posVec(poleDimLocal)=2*widthIndex(poleDimLocal)+1 orientVec(poleDimLocal)=-orientVec(poleDimLocal) ! make pole dim - orientVec(periodicDimLocal)=-orientVec(periodicDimLocal) ! make periodic dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif end subroutine Setup1PeriodicConn subroutine Setup2PeriodicConn(dimCount, minIndex, maxIndex, & connList, rc) integer, intent(in) :: dimCount integer, intent(in) :: minIndex(:) integer, intent(in) :: maxIndex(:) type(ESMF_DistgridConnection), pointer :: connList(:) integer, intent(out), optional :: rc integer :: connListCount integer :: posVec(ESMF_MAXDIM) integer :: localrc ! Allocate connection list allocate(connList(2), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating connList", & ESMF_CONTEXT, rcToReturn=rc)) return ! Add dimension 1 periodic connection posVec=0 posVec(1)=maxIndex(1)-minIndex(1)+1 call ESMF_DistgridConnectionSet(connection=connList(1), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Add dimension 2 periodic connection posVec=0 posVec(2)=maxIndex(2)-minIndex(2)+1 call ESMF_DistgridConnectionSet(connection=connList(2), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return end subroutine Setup2PeriodicConn subroutine SetupTileConn(dimCount, minIndex, maxIndex, & connflagDim1, connflagDim2, connflagDim3, connList, rc) integer, intent(in) :: dimCount integer, intent(in) :: minIndex(:) integer, intent(in) :: maxIndex(:) type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim1(:) type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim2(:) type(ESMF_GridConn_Flag), intent(in), optional :: connflagDim3(:) type(ESMF_DistgridConnection), pointer :: connList(:) integer, intent(out), optional :: rc integer :: periodicDimLocal integer :: connListCount integer :: connListPos integer :: localrc type(ESMF_GridConn_Flag) :: connflagDim1Local(2) type(ESMF_GridConn_Flag) :: connflagDim2Local(2) type(ESMF_GridConn_Flag) :: connflagDim3Local(2) logical :: hasPeriod, hasPole integer :: posVec(ESMF_MAXDIM),i integer :: orientVec(ESMF_MAXDIM) integer :: widthIndex(ESMF_MAXDIM) if (present(connflagDim1)) then if (size(connflagDim1) .ne. 2) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- connflagDim1 must have size 2", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(connflagDim2)) then if (size(connflagDim2) .ne. 2) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- connflagDim2 must have size 2", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(connflagDim3)) then if (size(connflagDim3) .ne. 2) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- connflagDim3 must have size 2", & ESMF_CONTEXT, rcToReturn=rc) return endif endif if (present(connflagDim3) .and. (dimCount <3)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- connflagDim3 should not be specified if Grid dim <3", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Set defaults if (present(connflagDim1)) then connflagDim1Local=connflagDim1 else connflagDim1Local=ESMF_GRIDCONN_NONE endif if (present(connflagDim2)) then connflagDim2Local=connflagDim2 else connflagDim2Local=ESMF_GRIDCONN_NONE endif if (present(connflagDim3)) then connflagDim3Local=connflagDim3 else connflagDim3Local=ESMF_GRIDCONN_NONE endif ! more error checking if ((connflagDim1Local(1) .eq. ESMF_GRIDCONN_PERIODIC) .and. & (connflagDim1Local(2) .ne. ESMF_GRIDCONN_PERIODIC)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- periodicity must be specified on both ends", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((connflagDim1Local(1) .ne. ESMF_GRIDCONN_PERIODIC) .and. & (connflagDim1Local(2) .eq. ESMF_GRIDCONN_PERIODIC)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- periodicity must be specified on both ends", & ESMF_CONTEXT, rcToReturn=rc) return endif ! more error checking if ((connflagDim2Local(1) .eq. ESMF_GRIDCONN_PERIODIC) .and. & (connflagDim2Local(2) .ne. ESMF_GRIDCONN_PERIODIC)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- periodicity must be specified on both ends", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((connflagDim2Local(1) .ne. ESMF_GRIDCONN_PERIODIC) .and. & (connflagDim2Local(2) .eq. ESMF_GRIDCONN_PERIODIC)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- periodicity must be specified on both ends", & ESMF_CONTEXT, rcToReturn=rc) return endif ! more error checking if ((connflagDim3Local(1) .eq. ESMF_GRIDCONN_PERIODIC) .and. & (connflagDim3Local(2) .ne. ESMF_GRIDCONN_PERIODIC)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- periodicity must be specified on both ends", & ESMF_CONTEXT, rcToReturn=rc) return endif if ((connflagDim3Local(1) .ne. ESMF_GRIDCONN_PERIODIC) .and. & (connflagDim3Local(2) .eq. ESMF_GRIDCONN_PERIODIC)) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- periodicity must be specified on both ends", & ESMF_CONTEXT, rcToReturn=rc) return endif ! Check for periodicity hasPeriod=.false. if ((connflagDim1Local(1) .eq. ESMF_GRIDCONN_PERIODIC) .or. & (connflagDim1Local(2) .eq. ESMF_GRIDCONN_PERIODIC)) then hasPeriod=.true. periodicDimLocal=1 endif if ((connflagDim2Local(1) .eq. ESMF_GRIDCONN_PERIODIC) .or. & (connflagDim2Local(2) .eq. ESMF_GRIDCONN_PERIODIC)) then hasPeriod=.true. periodicDimLocal=2 endif if ((connflagDim3Local(1) .eq. ESMF_GRIDCONN_PERIODIC) .or. & (connflagDim3Local(2) .eq. ESMF_GRIDCONN_PERIODIC)) then hasPeriod=.true. periodicDimLocal=3 endif ! Check for poles hasPole=.false. if ((connflagDim1Local(1) .eq. ESMF_GRIDCONN_POLE) .or. & (connflagDim1Local(1) .eq. ESMF_GRIDCONN_BIPOLE) .or. & (connflagDim1Local(2) .eq. ESMF_GRIDCONN_POLE) .or. & (connflagDim1Local(2) .eq. ESMF_GRIDCONN_BIPOLE)) then hasPole=.true. endif if ((connflagDim2Local(1) .eq. ESMF_GRIDCONN_POLE) .or. & (connflagDim2Local(1) .eq. ESMF_GRIDCONN_BIPOLE) .or. & (connflagDim2Local(2) .eq. ESMF_GRIDCONN_POLE) .or. & (connflagDim2Local(2) .eq. ESMF_GRIDCONN_BIPOLE)) then hasPole=.true. endif if ((connflagDim3Local(1) .eq. ESMF_GRIDCONN_POLE) .or. & (connflagDim3Local(1) .eq. ESMF_GRIDCONN_BIPOLE) .or. & (connflagDim3Local(2) .eq. ESMF_GRIDCONN_POLE) .or. & (connflagDim3Local(2) .eq. ESMF_GRIDCONN_BIPOLE)) then hasPole=.true. endif ! Error check if (hasPole .and. .not. hasPeriod) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_BAD, & msg="- if a grid has a pole, it must be periodic", & ESMF_CONTEXT, rcToReturn=rc) return endif ! calculate the count of elements in each index widthIndex=0 do i=1,dimCount widthIndex(i)=maxIndex(i)-minIndex(i)+1 enddo ! Count connections connListCount=0 !!!!!!!!! Connections for 1 !!!!!!!!!!!!!!!!!!!!!1 if (connflagDim1Local(1) .eq. ESMF_GRIDCONN_PERIODIC) then connListCount=connListCount+1 else if (connflagDim1Local(1) .eq. ESMF_GRIDCONN_POLE) then connListCount=connListCount+1 else if (connflagDim1Local(1) .eq. ESMF_GRIDCONN_BIPOLE) then connListCount=connListCount+1 endif if (connflagDim1Local(2) .eq. ESMF_GRIDCONN_POLE) then connListCount=connListCount+1 else if (connflagDim1Local(2) .eq. ESMF_GRIDCONN_BIPOLE) then connListCount=connListCount+1 endif !!!!!!!!! Connections for 2 !!!!!!!!!!!!!!!!!!!!!1 if (connflagDim2Local(1) .eq. ESMF_GRIDCONN_PERIODIC) then connListCount=connListCount+1 else if (connflagDim2Local(1) .eq. ESMF_GRIDCONN_POLE) then connListCount=connListCount+1 else if (connflagDim2Local(1) .eq. ESMF_GRIDCONN_BIPOLE) then connListCount=connListCount+1 endif if (connflagDim2Local(2) .eq. ESMF_GRIDCONN_POLE) then connListCount=connListCount+1 else if (connflagDim2Local(2) .eq. ESMF_GRIDCONN_BIPOLE) then connListCount=connListCount+1 endif !!!!!!!!! Connections for 3 !!!!!!!!!!!!!!!!!!!!!1 if (connflagDim3Local(1) .eq. ESMF_GRIDCONN_PERIODIC) then connListCount=connListCount+1 else if (connflagDim3Local(1) .eq. ESMF_GRIDCONN_POLE) then connListCount=connListCount+1 else if (connflagDim3Local(1) .eq. ESMF_GRIDCONN_BIPOLE) then connListCount=connListCount+1 endif if (connflagDim3Local(2) .eq. ESMF_GRIDCONN_POLE) then connListCount=connListCount+1 else if (connflagDim3Local(2) .eq. ESMF_GRIDCONN_BIPOLE) then connListCount=connListCount+1 endif ! Allocate connection list to maximum number possible allocate(connList(connListCount), stat=localrc) if (ESMF_LogFoundAllocError(localrc, msg="Allocating connList", & ESMF_CONTEXT, rcToReturn=rc)) return ! init connectionCount connListPos=1 !!!!!!!!! Connections for 1 !!!!!!!!!!!!!!!!!!!!!1 ! Init orient vec do i=1,ESMF_MAXDIM orientvec(i)=i enddo if (connflagDim1Local(1) .eq. ESMF_GRIDCONN_PERIODIC) then posVec=0 posVec(1)=widthIndex(1) call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 else if (connflagDim1Local(1) .eq. ESMF_GRIDCONN_POLE) then ! do pole connection posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)/2 posVec(1)=1 orientVec(1)=-orientVec(1) ! make pole dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 else if (connflagDim1Local(1) .eq. ESMF_GRIDCONN_BIPOLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)+1 posVec(1)=1 orientVec(1)=-orientVec(1) ! make pole dim - orientVec(periodicDimLocal)=-orientVec(periodicDimLocal) ! make periodic dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 endif ! Init orient vec do i=1,ESMF_MAXDIM orientvec(i)=i enddo if (connflagDim1Local(2) .eq. ESMF_GRIDCONN_POLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)/2 posVec(1)=2*widthIndex(1)+1 orientVec(1)=-orientVec(1) ! make pole dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 else if (connflagDim1Local(2) .eq. ESMF_GRIDCONN_BIPOLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)+1 posVec(1)=2*widthIndex(1)+1 orientVec(1)=-orientVec(1) ! make pole dim - orientVec(periodicDimLocal)=-orientVec(periodicDimLocal) ! make periodic dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 endif !!!!!!!!! Connections for 2 !!!!!!!!!!!!!!!!!!!!!1 ! Init orient vec do i=1,ESMF_MAXDIM orientvec(i)=i enddo if (connflagDim2Local(1) .eq. ESMF_GRIDCONN_PERIODIC) then posVec=0 posVec(2)=widthIndex(2) call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 else if (connflagDim2Local(1) .eq. ESMF_GRIDCONN_POLE) then ! do pole connection posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)/2 posVec(2)=1 orientVec(2)=-orientVec(2) ! make pole dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 else if (connflagDim2Local(1) .eq. ESMF_GRIDCONN_BIPOLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)+1 posVec(2)=1 orientVec(2)=-orientVec(2) ! make pole dim - orientVec(periodicDimLocal)=-orientVec(periodicDimLocal) ! make periodic dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 endif ! Init orient vec do i=1,ESMF_MAXDIM orientvec(i)=i enddo if (connflagDim2Local(2) .eq. ESMF_GRIDCONN_POLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)/2 posVec(2)=2*widthIndex(2)+1 orientVec(2)=-orientVec(2) ! make pole dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 else if (connflagDim2Local(2) .eq. ESMF_GRIDCONN_BIPOLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)+1 posVec(2)=2*widthIndex(2)+1 orientVec(2)=-orientVec(2) ! make pole dim - orientVec(periodicDimLocal)=-orientVec(periodicDimLocal) ! make periodic dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 endif !!!!!!!!! Connections for 3 !!!!!!!!!!!!!!!!!!!!!1 ! Init orient vec do i=1,ESMF_MAXDIM orientvec(i)=i enddo if (connflagDim3Local(1) .eq. ESMF_GRIDCONN_PERIODIC) then posVec=0 posVec(3)=widthIndex(3) call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 else if (connflagDim3Local(1) .eq. ESMF_GRIDCONN_POLE) then ! do pole connection posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)/2 posVec(3)=1 orientVec(3)=-orientVec(3) ! make pole dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 else if (connflagDim3Local(1) .eq. ESMF_GRIDCONN_BIPOLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)+1 posVec(3)=1 orientVec(3)=-orientVec(3) ! make pole dim - orientVec(periodicDimLocal)=-orientVec(periodicDimLocal) ! make periodic dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 endif ! Init orient vec do i=1,ESMF_MAXDIM orientvec(i)=i enddo if (connflagDim3Local(2) .eq. ESMF_GRIDCONN_POLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)/2 posVec(3)=2*widthIndex(3)+1 orientVec(3)=-orientVec(3) ! make pole dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 else if (connflagDim3Local(2) .eq. ESMF_GRIDCONN_BIPOLE) then posVec=0 posVec(periodicDimLocal)=widthIndex(periodicDimLocal)+1 posVec(3)=2*widthIndex(3)+1 orientVec(3)=-orientVec(3) ! make pole dim - orientVec(periodicDimLocal)=-orientVec(periodicDimLocal) ! make periodic dim - call ESMF_DistgridConnectionSet(connection=connList(connListPos), & tileIndexA=1,tileIndexB=1, & positionVector=posVec(1:dimCount), & orientationVector=orientVec(1:dimCount), & rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return connListPos=connListPos+1 endif end subroutine SetupTileConn !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_PoleTypeEqual" !BOPI ! !IROUTINE: ESMF_PoleTypeEqual - Equality of PoleType statuses ! ! !INTERFACE: function ESMF_PoleTypeEqual(PoleType1, PoleType2) ! !RETURN VALUE: logical :: ESMF_PoleTypeEqual ! !ARGUMENTS: type (ESMF_PoleKind_Flag), intent(in) :: & PoleType1, &! Two igrid statuses to compare for PoleType2 ! equality ! !DESCRIPTION: ! This routine compares two ESMF PoleType statuses to see if ! they are equivalent. ! ! The arguments are: ! \begin{description} ! \item[PoleType1, PoleType2] ! Two igrid statuses to compare for equality ! \end{description} ! !EOPI ESMF_PoleTypeEqual = (PoleType1%polekind == & PoleType2%polekind) end function ESMF_PoleTypeEqual !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_PoleTypeNotEqual" !BOPI ! !IROUTINE: ESMF_PoleTypeNotEqual - Non-equality of PoleType statuses ! ! !INTERFACE: function ESMF_PoleTypeNotEqual(PoleType1, PoleType2) ! !RETURN VALUE: logical :: ESMF_PoleTypeNotEqual ! !ARGUMENTS: type (ESMF_PoleKind_Flag), intent(in) :: & PoleType1, &! Two PoleType Statuses to compare for PoleType2 ! inequality ! !DESCRIPTION: ! This routine compares two ESMF PoleType statuses to see if ! they are unequal. ! ! The arguments are: ! \begin{description} ! \item[PoleType1, PoleType2] ! Two statuses of PoleTypes to compare for inequality ! \end{description} ! !EOPI ESMF_PoleTypeNotEqual = (PoleType1%polekind /= & PoleType2%polekind) end function ESMF_PoleTypeNotEqual #undef ESMF_METHOD end module ESMF_GridMod