! $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_FieldPr.F90" !============================================================================== ! ! ESMF FieldPr module module ESMF_FieldPrMod ! !============================================================================== ! ! This file contains the Field class definition and all Field ! class method. ! !------------------------------------------------------------------------------ ! INCLUDES #include "ESMF.h" !------------------------------------------------------------------------------ ! !USES: use ESMF_UtilTypesMod use ESMF_UtilMod use ESMF_BaseMod use ESMF_VMMod use ESMF_LogErrMod use ESMF_ArraySpecMod use ESMF_LocalArrayMod use ESMF_DELayoutMod use ESMF_StaggerLocMod use ESMF_DistGridMod use ESMF_GridMod use ESMF_GeomMod use ESMF_ArrayMod use ESMF_ArrayCreateMod use ESMF_ArrayGetMod use ESMF_TimeMod use ESMF_InitMacrosMod use ESMF_IOUtilMod use ESMF_IOMod use ESMF_FieldMod use ESMF_FieldGetMod implicit none !------------------------------------------------------------------------------ ! !PRIVATE TYPES: private !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ ! ! !PUBLIC MEMBER FUNCTIONS: ! ! - ESMF-public methods: public ESMF_FieldPrint ! Print contents of a Field public ESMF_FieldRead ! Read Field data from a file !------------------------------------------------------------------------------ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! contains !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_FieldPrint" !BOP ! !IROUTINE: ESMF_FieldPrint - Print Field information ! !INTERFACE: subroutine ESMF_FieldPrint(field, keywordEnforcer, rc) ! ! ! !ARGUMENTS: type(ESMF_Field), intent(in) :: field type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(out), optional :: rc ! ! !STATUS: ! \begin{itemize} ! \item\apiStatusCompatibleVersion{5.2.0r} ! \end{itemize} ! ! !DESCRIPTION: ! Prints information about the {\tt field} to {\tt stdout}. ! This subroutine goes through the internal data members of a field ! data type and prints information of each data member. ! ! The arguments are: ! \begin{description} ! \item [field] ! An {\tt ESMF\_Field} object. ! \item [{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP character(len=ESMF_MAXSTR) :: name, str type(ESMF_FieldType), pointer :: fp integer :: i, localrc integer :: gridrank, arrayrank character(len=6) :: defaultopts type(ESMF_Status) :: fieldstatus ! Initialize localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! check variables ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) ! print option is not implemented, but it has to pass to c_ESMC_BasePrint() defaultopts = "brief" fp => field%ftypep call ESMF_BaseGetStatus(fp%base, fieldstatus, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !nsc call ESMF_LogWrite("Field Print:", ESMF_LOGMSG_INFO) write(ESMF_UtilIOStdout,*) "Field Print Starts ====>" call ESMF_StatusString(fieldstatus, str, localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return write(ESMF_UtilIOStdout,*) "Field base status = ", trim(str) if (fieldstatus .ne. ESMF_STATUS_READY) then write(ESMF_UtilIOStdout,*) "Empty or Uninitialized Field" write(ESMF_UtilIOStdout,*) "Field Print Ends ====>" if (present(rc)) rc = ESMF_SUCCESS return endif if (.not. associated(field%ftypep)) then !jw call ESMF_LogWrite("Empty or Uninitialized Field", ESMF_LOGMSG_INFO) write(ESMF_UtilIOStdout,*) "Empty or Uninitialized Field" write(ESMF_UtilIOStdout,*) "Field Print Ends ====>" if (present(rc)) rc = ESMF_SUCCESS return endif call ESMF_GetName(fp%base, name, localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return !jw write(msgbuf, *) " Name = '", trim(name), "'" !jw call ESMF_LogWrite(msgbuf, ESMF_LOGMSG_INFO) write(ESMF_UtilIOStdout,*) " Name = '", trim(name), "'" call ESMF_BasePrint(fp%base, options=defaultopts, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return write(ESMF_UtilIOStdout,*) "Field status = ", fp%status if (fp%status .eq. ESMF_FIELDSTATUS_GRIDSET .or. & fp%status .eq. ESMF_FIELDSTATUS_COMPLETE) then ! call ESMF_GeomPrint(fp%geom, "", localrc) ! if (ESMF_LogFoundError(localrc, & ! ESMF_ERR_PASSTHRU, & ! ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_GeomGet(fp%geom, dimCount=gridrank, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return write(ESMF_UtilIOStdout,*) "gridrank = ", gridrank endif if (fp%status .eq. ESMF_FIELDSTATUS_COMPLETE) then call ESMF_ArrayPrint(fp%array, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_ArrayGet(fp%array, rank=arrayrank, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return write(ESMF_UtilIOStdout,*) "arrayrank = ", arrayrank endif write(ESMF_UtilIOStdout,*) "gridToFieldMap ungriddedLBound ungriddedUBound totalLWidth", & " totalUWidth" do i = 1, ESMF_MAXDIM write(ESMF_UtilIOStdout,*) fp%gridToFieldMap(i), fp%ungriddedLBound(i), fp%ungriddedUBound(i), & " ", fp%totalLWidth(i), fp%totalUWidth(i) enddo write(ESMF_UtilIOStdout,*) "Field Print Ends ====>" if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_FieldPrint !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_FieldRead" !BOP ! !IROUTINE: ESMF_FieldRead - Read Field data from a file ! \label{api:FieldRead} ! !INTERFACE: subroutine ESMF_FieldRead(field, fileName, keywordEnforcer, & variableName, timeslice, iofmt, rc) ! ! ! !ARGUMENTS: type(ESMF_Field), intent(inout) :: field character(*), intent(in) :: fileName type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below character(*), intent(in), optional :: variableName integer, intent(in), optional :: timeslice type(ESMF_IOFmt_Flag), intent(in), optional :: iofmt integer, intent(out), optional :: rc ! ! !DESCRIPTION: ! Read Field data from a file and put it into an {ESMF\_Field} object. ! For this API to be functional, the environment variable {\tt ESMF\_PIO} ! should be set to either "internal" or "external" when the ESMF library is built. ! Please see the section on Data I/O,~\ref{io:dataio}. ! ! Limitations: ! \begin{itemize} ! \item Not supported in {\tt ESMF\_COMM=mpiuni} mode. ! \end{itemize} ! ! The arguments are: ! \begin{description} ! \item [field] ! The {\tt ESMF\_Field} object in which the read data is returned. ! \item[fileName] ! The name of the file from which Field data is read. ! If the Field is a multi-tile Array, then fileName must contain ! exactly one instance of "*"; this is a placeholder that will be replaced ! by the tile number, with each tile being read from a separate file. (For ! example, for a fileName of "myfile*.nc", tile 1 will be read from ! "myfile1.nc", tile 2 from "myfile2.nc", etc.) ! (This handling of the fileName for multi-tile I/O is subject to change.) ! \item[{[variableName]}] ! Variable name in the file; default is the "name" of Field. ! Use this argument only in the I/O format (such as NetCDF) that ! supports variable name. If the I/O format does not support this ! (such as binary format), ESMF will return an error code. ! \item[{[timeslice]}] ! Number of slices to be read from file, starting from the 1st slice ! \item[{[iofmt]}] ! \begin{sloppypar} ! The I/O format. Please see Section~\ref{opt:iofmtflag} for the list ! of options. If not present, defaults to {\tt ESMF\_IOFMT\_NETCDF}. ! \end{sloppypar} ! \item [{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP character(len=ESMF_MAXSTR) :: name type(ESMF_FieldType), pointer :: fp type(ESMF_Array) :: array integer :: localrc type(ESMF_FieldStatus_Flag) :: fieldstatus ! Field's status type(ESMF_IOFmt_Flag) :: opt_iofmt type(ESMF_IO) :: io ! The I/O object integer :: file_ext_p logical :: errorFound ! True if error condition integer :: time #ifdef ESMF_PIO ! Initialize localrc = ESMF_RC_NOT_IMPL if (present(rc)) rc = ESMF_RC_NOT_IMPL ! check variables ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit,field,rc) time = 0 if(present(timeslice)) time = timeslice ! Set iofmt based on file name extension (if present) if (present (iofmt)) then opt_iofmt = iofmt else opt_iofmt = ESMF_IOFMT_NETCDF end if if (present(variableName)) then name = variableName else fp => field%ftypep call ESMF_GetName(fp%base, name, localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif call ESMF_FieldGet(field, array=array, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! Create an I/O object io = ESMF_IOCreate(rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! From here on out, we need to clean up so no returning on error if (localrc .eq. ESMF_SUCCESS) then call ESMF_IOAddArray(io, array, variableName=name, rc=localrc) errorFound = ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc) endif if (.not. errorfound) then call ESMF_IORead(io, trim(fileName), timeslice=time, & iofmt=opt_iofmt, rc=localrc) errorFound = ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc) endif ! Set rc here in case we had an error but destroy succeeds if (present(rc)) rc = localrc call ESMF_IODestroy(io, rc=localrc) ! Log error but don't reset rc errorFound = ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=localrc) ! Last chance to return an error code (IODestroy failed) if (present(rc)) then if (rc .eq. ESMF_SUCCESS) rc = localrc end if #else ! Return indicating PIO not present if (present(rc)) rc = ESMF_RC_LIB_NOT_PRESENT #endif end subroutine ESMF_FieldRead !------------------------------------------------------------------------------ end module ESMF_FieldPrMod