! $Id: ESMF_LocalArrayGet.cppF90,v 1.32 2011/07/01 03:56:40 theurich 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_LocalArrayGet.F90" !============================================================================== ! ! ESMF LocalArrayCreate module module ESMF_LocalArrayGetMod ! !============================================================================== ! ! This file contains the LocalArray class definition and all LocalArray ! class methods. ! !------------------------------------------------------------------------------ ! INCLUDES ! < ignore blank lines below. they are created by the files which ! define various macros. > ^include "ESMF.h" #include "ESMF_TypeKindRankMacros.hcppF90" #define LocalArrayGetDataDoc() \ !------------------------------------------------------------------------------ @\ !BOP @\ ! !IROUTINE: ESMF_LocalArrayGet - Get access to data in a LocalArray object @\ ! @\ ! !INTERFACE: @\ ! ! Private name; call using ESMF_LocalArrayGet() @\ ! subroutine ESMF_LocalArrayGetData(localarray, farrayPtr, & @\ ! keywordEnforcer, datacopyflag, rc) @\ ! @\ ! !ARGUMENTS: @\ ! type(ESMF_LocalArray) :: localarray @\ ! (ESMF_KIND_), pointer :: farrayPtr @\ ! type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ ! type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ ! integer, intent(out), optional :: rc @\ ! @\ ! !STATUS: @\ ! \apiStatusCompatible @\ ! @\ ! !DESCRIPTION: @\ ! Return a Fortran pointer to the data buffer, or return a Fortran pointer @\ ! to a new copy of the data. @\ ! @\ ! The arguments are: @\ ! \begin{description} @\ ! \item[localarray] @\ ! The {\tt ESMF\_LocalArray} to get the value from. @\ ! \item[farrayPtr] @\ ! An unassociated or associated Fortran pointer correctly allocated.@\ ! \item[{[datacopyflag]}] @\ ! An optional copy flag which can be specified. @\ ! Can either make a new copy of the data or reference existing data. @\ ! See section \ref{const:datacopyflag} for a list of possible values. @\ ! \item[{[rc]}] @\ ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. @\ ! \end{description} @\ ! @\ !EOP @\ !------------------------------------------------------------------------------ @\ #define LocalArrayGetDataMacro(mname, mtypekind, mrank, mdim, mlen, mrng, mloc) \ !------------------------------------------------------------------------------ @\ ! @\ ^undef ESMF_METHOD @\ !define ESMF_METHOD "ESMF_LocalArrayGetData##mrank##D##mtypekind" @\ ^define ESMF_METHOD "ESMF_LocalArrayGetData" @\ subroutine ESMF_LocalArrayGetData##mrank##D##mtypekind(localarray, & @\ farrayPtr, keywordEnforcer, datacopyflag, rc) @\ @\ type(ESMF_LocalArray) :: localarray @\ type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below @\ mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: farrayPtr @\ type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag @\ integer, intent(out), optional :: rc @\ @\ ! Local variables @\ integer :: localrc ! local return code @\ logical :: copyreq ! did user specify copy? @\ integer :: rank @\ type(ESMF_TypeKind_Flag) :: typekind @\ @\ type (ESMF_LAWrap##mrank##D##mtypekind) :: wrap ! for passing f90 ptr to C++ @\ integer :: lb(mrank), ub(mrank) ! size info for the array @\ mname (ESMF_KIND_##mtypekind), dimension(mdim), pointer :: lp ! local copy @\ @\ ! Initialize return code; assume routine not implemented @\ localrc = ESMF_RC_NOT_IMPL @\ if (present(rc)) rc = ESMF_RC_NOT_IMPL @\ @\ ! Check datacopyflag argument and set copyreq @\ copyreq = .FALSE. ! default do not copy but return by reference @\ if (present(datacopyflag)) then @\ if (datacopyflag .eq. ESMF_DATACOPY_VALUE) copyreq = .TRUE. @\ endif @\ @\ ! Check tkr matching between localarray and farrayPtr @\ call ESMF_LocalArrayGet(localarray, typekind=typekind, rank=rank, rc=localrc) @\ if (ESMF_LogFoundError(localrc, & @\ ESMF_ERR_PASSTHRU, & @\ ESMF_CONTEXT, rcToReturn=rc)) return @\ ! check typekind match @\ if (typekind /= ESMF_TYPEKIND_##mtypekind) then @\ call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & @\ msg="- farrayPtr typekind does not match LocalArray typekind", & @\ ESMF_CONTEXT, rcToReturn=rc) @\ return @\ endif @\ ! check rank match @\ if (rank /= mrank) then @\ call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & @\ msg="- farrayPtr rank does not match LocalArray rank", & @\ ESMF_CONTEXT, rcToReturn=rc) @\ return @\ endif @\ @\ ! Gain access to the F90 array pointer stored in localarray @\ call c_ESMC_LocalArrayGetFPtr(localarray, wrap, localrc) @\ if (ESMF_LogFoundError(localrc, & @\ ESMF_ERR_PASSTHRU, & @\ ESMF_CONTEXT, rcToReturn=rc)) return @\ @\ ! Allocate a new buffer if requested and return a copy @\ if (copyreq) then @\ call c_ESMC_LocalArrayGetLbounds(localarray, lb, localrc) @\ if (ESMF_LogFoundError(localrc, & @\ ESMF_ERR_PASSTHRU, & @\ ESMF_CONTEXT, rcToReturn=rc)) return @\ call c_ESMC_LocalArrayGetUbounds(localarray, ub, localrc) @\ if (ESMF_LogFoundError(localrc, & @\ ESMF_ERR_PASSTHRU, & @\ ESMF_CONTEXT, rcToReturn=rc)) return @\ ! Macro mrng @\ ! is a macro that has correct construction of lb and ub elements @\ allocate(lp(mrng), stat=localrc) @\ if (ESMF_LogFoundAllocError(localrc, & @\ msg="local data space", & @\ ESMF_CONTEXT, rcToReturn=rc)) return @\ ! test if incoming pointer was associated @\ if (associated(farrayPtr)) then @\ if (size(farrayPtr) .ne. size(lp)) then @\ call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & @\ msg="- farrayPtr was associated but of incorrect size", & @\ ESMF_CONTEXT, rcToReturn=rc) @\ return @\ endif @\ ! this must do a contents assignment to perform a copy operation @\ farrayPtr = wrap%ptr##mrank##D##mtypekind @\ deallocate(lp) @\ else @\ ! this must do a contents assignment to perform a copy operation @\ lp = wrap%ptr##mrank##D##mtypekind @\ farrayPtr => lp @\ endif @\ else @\ farrayPtr => wrap%ptr##mrank##D##mtypekind ! return a reference @\ endif @\ @\ ! return successfully @\ if (present(rc)) rc = ESMF_SUCCESS @\ @\ end subroutine ESMF_LocalArrayGetData##mrank##D##mtypekind @\ @\ ! < end macro - do not edit directly > @\ !------------------------------------------------------------------------------ @\ !------------------------------------------------------------------------------ !BOPI ! !MODULE: ESMF_LocalArrayGetMod - Manage data uniformly between F90 and C++ ! ! !DESCRIPTION: ! ! The code in this file implements the {\tt ESMF\_LocalArray} class and ! associated functions and subroutines. ! ! C and C++ arrays are simple pointers to memory. ! Fortran arrays contain shape and stride definitions and are strongly ! typed. To enable interoperability between the languages the C++ code ! must be able to obtain this information from the Fortran description ! (which is called the "dope vector" in Fortran), either through a priori ! knowledge or through query. !EOPI !------------------------------------------------------------------------------ ! !USES: use ESMF_UtilTypesMod ! ESMF utility types use ESMF_InitMacrosMod ! ESMF initializer macros use ESMF_BaseMod ! ESMF base class use ESMF_LogErrMod ! ESMF error handling use ESMF_ArraySpecMod ! class sub modules use ESMF_LocalArrayWrapperTypeMod ! contains the LAWrapper derived type use ESMF_LocalArrayCreateMod ! contains the ESMF_LocalArray derived type implicit none !------------------------------------------------------------------------------ ! !PRIVATE TYPES: private !------------------------------------------------------------------------------ ! The following line turns the CVS identifier string into a printable variable. character(*), parameter, private :: version = & '$Id: ESMF_LocalArrayGet.cppF90,v 1.32 2011/07/01 03:56:40 theurich Exp $' !------------------------------------------------------------------------------ ! !PUBLIC MEMBER FUNCTIONS: public ESMF_LocalArrayGet !============================================================================== ! ! INTERFACE BLOCKS ! !============================================================================== !------------------------------------------------------------------------------ !BOPI ! !IROUTINE: ESMF_LocalArrayGet -- Get LocalArray internal information ! !INTERFACE: interface ESMF_LocalArrayGet ! !PRIVATE MEMBER FUNCTIONS: ! module procedure ESMF_LocalArrayGetDefault TypeKindRankInterfaceMacro(LocalArrayGetData) ! !DESCRIPTION: ! This interface provides a single entry point for the various ! types of {\tt ESMF\_LocalArrayGet} functions. ! !EOPI end interface !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! contains !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !============================================================================== !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ ! ! Query for information from the array. ! !------------------------------------------------------------------------------ ^undef ESMF_METHOD ^define ESMF_METHOD "ESMF_LocalArrayGetDefault" !BOP ! !IROUTINE: ESMF_LocalArrayGet - Return LocalArray information ! ! !INTERFACE: ! Private name; call using ESMF_LocalArrayGet() subroutine ESMF_LocalArrayGetDefault(localarray, keywordEnforcer, & typekind, rank, totalCount, totalLBound, totalUBound, rc) ! ! !ARGUMENTS: type(ESMF_LocalArray), intent(in) :: localarray type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below type(ESMF_TypeKind_Flag), intent(out), optional :: typekind integer, intent(out), optional :: rank integer, intent(out), optional :: totalCount(:) integer, intent(out), optional :: totalLBound(:) integer, intent(out), optional :: totalUBound(:) integer, intent(out), optional :: rc ! ! !STATUS: ! \apiStatusCompatible ! ! !DESCRIPTION: ! Returns information about the {\tt ESMF\_LocalArray}. ! ! The arguments are: ! \begin{description} ! \item[localarray] ! Queried {\tt ESMF\_LocalArray} object. ! \item[{[typekind]}] ! TypeKind of the LocalArray object. ! \item[{[rank]}] ! Rank of the LocalArray object. ! \item[{[totalCount]}] ! Count per dimension. ! \item[{[totalLBound]}] ! Lower bound per dimension. ! \item[{[totalUBound]}] ! Upper bound per dimension. ! \item[{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP !------------------------------------------------------------------------------ integer :: localrc ! local return code integer :: lrank ! Local use to get rank ! Initialize return code; assume routine not implemented if (present(rc)) rc = ESMF_RC_NOT_IMPL localrc = ESMF_RC_NOT_IMPL ! Check init status of arguments ESMF_INIT_CHECK_DEEP(ESMF_LocalArrayGetInit, localarray, rc) call c_ESMC_LocalArrayGetRank(localarray, lrank, localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(rank)) then rank = lrank endif if (present(typekind)) then call c_ESMC_LocalArrayGetTypeKind(localarray, typekind, localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif if (present(totalCount)) then if (size(totalCount) < lrank) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- size of totalCount argument is smaller than rank", & ESMF_CONTEXT, rcToReturn=rc) return endif call c_esmc_localarraygetcounts(localarray, totalCount, localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif if (present(totalLBound)) then if (size(totalLBound) < lrank) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- size of totalLBound argument is smaller than rank", & ESMF_CONTEXT, rcToReturn=rc) return endif call c_ESMC_LocalArrayGetLbounds(localarray, totalLBound, localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif if (present(totalUBound)) then if (size(totalUBound) < lrank) then call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_INCOMP, & msg="- size of totalUBound argument is smaller than rank", & ESMF_CONTEXT, rcToReturn=rc) return endif call c_ESMC_LocalArrayGetUbounds(localarray, totalUBound, 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_LocalArrayGetDefault !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ !! < start of macros which become actual function bodies after expansion > TypeKindRankDeclarationMacro(LocalArrayGetData) !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ end module ESMF_LocalArrayGetMod