! $Id$ ! ! Earth System Modeling Framework ! Copyright (c) 2002-2023, 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_StaggerLoc.F90" ! ! ESMF Stagger Location module ESMF_StaggerLocMod ! !============================================================================== ! ! This file contains the Stagger Location subroutines ! !------------------------------------------------------------------------------ ! INCLUDES #include "ESMF.h" !============================================================================== !BOPI ! !MODULE: ESMF_StaggerMod - Stagger class ! ! !DESCRIPTION: ! ! The code in this file implements some routines for interacting with the general stagger. ! !------------------------------------------------------------------------------ ! !USES: use ESMF_UtilTypesMod ! ESMF base class use ESMF_StaggerLocTypeMod use ESMF_LogErrMod use ESMF_IOUtilMod implicit none !------------------------------------------------------------------------------ ! !PRIVATE TYPES: private !------------------------------------------------------------------------------ ! ! !PUBLIC TYPES: public ESMF_StaggerLoc !------------------------------------------------------------------------------ ! ! !PUBLIC MEMBER FUNCTIONS: public ESMF_StaggerLocGet public ESMF_StaggerLocSet public ESMF_StaggerLocString public ESMF_StaggerLocPrint public assignment(=) public operator(==), operator(/=) public operator(>), operator(>=) public operator(<), operator(<=) !------------------------------------------------------------------------------ ! ! !PUBLIC DATA MEMBERS: ! ! For definition of stagger locations see the file Grid\_options.tex. ! !!!!! !! Invalid stagger locations public ESMF_STAGGERLOC_INVALID, ESMF_STAGGERLOC_UNINIT !! 2D predefined stagger locations public ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_EDGE1, & ESMF_STAGGERLOC_EDGE2, ESMF_STAGGERLOC_CORNER !! 3D predefined stagger locations public ESMF_STAGGERLOC_CENTER_VCENTER, & ESMF_STAGGERLOC_EDGE1_VCENTER, & ESMF_STAGGERLOC_EDGE2_VCENTER, & ESMF_STAGGERLOC_CORNER_VCENTER, & ESMF_STAGGERLOC_CENTER_VFACE, & ESMF_STAGGERLOC_EDGE1_VFACE, & ESMF_STAGGERLOC_EDGE2_VFACE, & ESMF_STAGGERLOC_CORNER_VFACE !EOPI !------------------------------------------------------------------------------ ! The following line turns the CVS identifier string into a printable variable. character(*), parameter, private :: version = & '$Id$' !============================================================================== !============================================================================== ! ! INTERFACE BLOCKS ! !============================================================================== ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_StaggerLocGet -- Generic interface ! !INTERFACE: interface ESMF_StaggerLocGet ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_StaggerLocGetDim ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_StaggerLocGet} functions. !EOPI end interface ! -------------------------- ESMF-public method ------------------------------- !BOPI ! !IROUTINE: ESMF_StaggerLocSet -- Generic interface ! !INTERFACE: interface ESMF_StaggerLocSet ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_StaggerLocSetAllDim module procedure ESMF_StaggerLocSetDim ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_StaggerLocSet} functions. !EOPI end interface !============================================================================== contains !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_StaggerLocGetDim" !BOP ! !IROUTINE: ESMF_StaggerLocGet - Get the value of one dimension of a StaggerLoc ! !INTERFACE: ! Private name; call using ESMF_StaggerLocGet() subroutine ESMF_StaggerLocGetDim(staggerloc, dim, loc, & keywordEnforcer, rc) ! ! !ARGUMENTS: type (ESMF_StaggerLoc), intent(in) :: staggerloc integer, intent(in) :: dim type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, optional, intent(out) :: loc integer, optional :: rc ! !DESCRIPTION: ! Gets the position of a particular dimension of a cell {\tt staggerloc} ! The argument {\tt loc} will be only be 0,1. ! If {\tt loc} is 0 it means the position ! should be in the center in that dimension. If {\tt loc} is +1 then ! for the dimension, the position should be on the positive side of the cell. ! Please see Section~\ref{sec:usage:staggerloc:adv} for diagrams. ! ! The arguments are: ! \begin{description} ! \item[staggerloc] ! Stagger location for which to get information. ! \item[dim] ! Dimension for which to get information (1-7). ! \item[{[loc]}] ! Output position data (should be either 0,1). ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP integer :: tmp ! Initialize return code; assume routine not implemented if (present(rc)) rc = ESMF_RC_NOT_IMPL ! Get stagger location value if (present(loc)) then tmp=(staggerloc%staggerloc)/(2**(dim-1)) loc=mod(tmp,2) endif ! Set return values. if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_StaggerLocGetDim !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_StaggerLocSetAllDim" !BOP ! !IROUTINE: ESMF_StaggerLocSet - Set a StaggerLoc to a particular position in the cell ! !INTERFACE: ! Private name; call using ESMF_StaggerLocSet() subroutine ESMF_StaggerLocSetAllDim(staggerloc, loc, keywordEnforcer, rc) ! ! !ARGUMENTS: type (ESMF_StaggerLoc), intent(inout) :: staggerloc integer, intent(in) :: loc(:) type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, optional :: rc ! !STATUS: ! \begin{itemize} ! \item\apiStatusCompatibleVersion{5.2.0r} ! \end{itemize} ! ! !DESCRIPTION: ! Sets a custom {\tt staggerloc} to a position in a cell by using the array ! {\tt loc}. The values in the array should only be 0,1. If loc(i) is 0 it ! means the position should be in the center in that dimension. If loc(i) is 1 then ! for dimension i, the position should be on the side of the cell. ! Please see Section~\ref{sec:usage:staggerloc:adv} ! for diagrams and further discussion of custom stagger locations. ! ! The arguments are: ! \begin{description} ! \item[staggerloc] ! Grid location to be initialized ! \item[loc] ! Array holding position data. Each entry in {\tt loc} should only ! be 0 or 1. note that dimensions beyond those specified are set to 0. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP integer :: i,sl,loc_size ! Initialize return code; assume routine not implemented if (present(rc)) rc = ESMF_RC_NOT_IMPL !TODO: error checking here ! set stagger location value sl=0 loc_size=size(loc) do i=1,loc_size sl=sl+loc(i)*2**(i-1) enddo ! Set stagger location value staggerloc%staggerloc=sl ! Set return values. if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_StaggerLocSetAllDim !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_StaggerLocSetDim" !BOP ! !IROUTINE: ESMF_StaggerLocSet - Set one dimension of a StaggerLoc to a particular position ! !INTERFACE: ! Private name; call using ESMF_StaggerLocSet() subroutine ESMF_StaggerLocSetDim(staggerloc, dim, loc, & keywordEnforcer, rc) ! ! !ARGUMENTS: type (ESMF_StaggerLoc), intent(inout) :: staggerloc integer, intent(in) :: dim integer, intent(in) :: loc type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, optional :: rc ! !STATUS: ! \begin{itemize} ! \item\apiStatusCompatibleVersion{5.2.0r} ! \end{itemize} ! ! !DESCRIPTION: ! Sets a particular dimension of a custom {\tt staggerloc} to a position in a cell ! by using the variable {\tt loc}. The variable {\tt loc} should only be 0,1. ! If {\tt loc} is 0 it means the position ! should be in the center in that dimension. If {\tt loc} is +1 then ! for the dimension, the position should be on the positive side of the cell. ! Please see Section~\ref{sec:usage:staggerloc:adv} ! for diagrams and further discussion of custom stagger locations. ! ! The arguments are: ! \begin{description} ! \item[staggerloc] ! Stagger location to be initialized ! \item[dim] ! Dimension to be changed (1-7). ! \item[loc] ! Position data should be either 0,1. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP ! Initialize return code; assume routine not implemented if (present(rc)) rc = ESMF_RC_NOT_IMPL !TODO: error checking here ! Set stagger location value staggerloc%staggerloc=loc*2**(dim-1) ! Set return values. if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_StaggerLocSetDim !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_StaggerLocString" !BOP ! !IROUTINE: ESMF_StaggerLocString - Return a StaggerLoc as a string ! ! !INTERFACE: subroutine ESMF_StaggerLocString(staggerloc, string, & keywordEnforcer, rc) ! ! ! !ARGUMENTS: type(ESMF_StaggerLoc), intent(in) :: staggerloc character (len = *), intent(out) :: string type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, optional, intent(out) :: rc ! ! !STATUS: ! \begin{itemize} ! \item\apiStatusCompatibleVersion{5.2.0r} ! \end{itemize} ! ! !DESCRIPTION: ! Return an {\tt ESMF\_StaggerLoc} as a printable string. ! ! The arguments are: ! \begin{description} ! \item [staggerloc] ! The {\tt ESMF\_StaggerLoc} to be turned into a string. ! \item [string] ! Return string. ! \item [{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! ! !EOP ! Initialize return code; assume routine not implemented if (present(rc)) rc = ESMF_RC_NOT_IMPL ! translate staggerloc to string ! (Strings should be appropriate for 2D and 3D) if (staggerloc < ESMF_STAGGERLOC_CENTER) string="No String For This StaggerLoc" if (staggerloc == ESMF_STAGGERLOC_CENTER) string="Center" if (staggerloc == ESMF_STAGGERLOC_CORNER) string="Corner of Dim. 1 and Dim. 2" if (staggerloc == ESMF_STAGGERLOC_EDGE1) string="Middle of Face Offset in Dim. 1" if (staggerloc == ESMF_STAGGERLOC_EDGE2) string="Middle of Face Offset in Dim. 2" if (staggerloc == ESMF_STAGGERLOC_CENTER_VFACE) string="Middle of Face Offset in Dim. 3" if (staggerloc == ESMF_STAGGERLOC_EDGE1_VFACE) string="Middle of Edge Offset in Dim. 1 and Dim. 3" if (staggerloc == ESMF_STAGGERLOC_EDGE2_VFACE) string="Middle of Edge Offset in Dim. 2 and Dim. 3" if (staggerloc == ESMF_STAGGERLOC_CORNER_VFACE) string="Corner of Dim. 1, Dim. 2, and Dim. 3" if (staggerloc > ESMF_STAGGERLOC_CORNER_VFACE) string="No String For This StaggerLoc" if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_StaggerLocString !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_StaggerLocPrint" !BOP ! !IROUTINE: ESMF_StaggerLocPrint - Print StaggerLoc information ! !INTERFACE: subroutine ESMF_StaggerLocPrint(staggerloc, keywordEnforcer, rc) ! ! !ARGUMENTS: type (ESMF_StaggerLoc), intent(in) :: staggerloc type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, optional, intent(out) :: rc ! !STATUS: ! \begin{itemize} ! \item\apiStatusCompatibleVersion{5.2.0r} ! \end{itemize} ! ! !DESCRIPTION: ! Print the internal data members of an {\tt ESMF\_StaggerLoc} object. \\ ! ! The arguments are: ! \begin{description} ! \item[staggerloc] ! ESMF\_StaggerLoc object as the method input ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP ! Initialize return code; assume routine not implemented if (present(rc)) rc = ESMF_RC_NOT_IMPL write(ESMF_UtilIOStdout, *) "StaggerLoc Print Begins =====>" write(ESMF_UtilIOStdout, *) " staggerloc = ", staggerloc%staggerloc write(ESMF_UtilIOStdout, *) "StaggerLoc Print Ends =====>" rc = ESMF_SUCCESS end subroutine ESMF_StaggerLocPrint end module ESMF_StaggerLocMod