diff --git a/docs/nightly/fix/reconcile-info/ESMC_crefdoc.pdf b/docs/nightly/fix/reconcile-info/ESMC_crefdoc.pdf new file mode 100644 index 000000000..00d6c537d Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMC_crefdoc.pdf differ diff --git a/docs/nightly/fix/reconcile-info/ESMC_crefdoc/ESMC_crefdoc.css b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/ESMC_crefdoc.css new file mode 100644 index 000000000..c24e7c803 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/ESMC_crefdoc.css @@ -0,0 +1,38 @@ +/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ +.MATH { font-family: "Century Schoolbook", serif; } +.MATH I { font-family: "Century Schoolbook", serif; font-style: italic } +.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold } + +/* implement both fixed-size and relative sizes */ +SMALL.XTINY { font-size : xx-small } +SMALL.TINY { font-size : x-small } +SMALL.SCRIPTSIZE { font-size : smaller } +SMALL.FOOTNOTESIZE { font-size : small } +SMALL.SMALL { } +BIG.LARGE { } +BIG.XLARGE { font-size : large } +BIG.XXLARGE { font-size : x-large } +BIG.HUGE { font-size : larger } +BIG.XHUGE { font-size : xx-large } + +/* heading styles */ +H1 { } +H2 { } +H3 { } +H4 { } +H5 { } + +/* mathematics styles */ +DIV.displaymath { } /* math displays */ +TD.eqno { } /* equation-number cells */ + + +/* document-specific styles come next */ +SPAN.bf { } +DIV.center { } +DIV.em { } +SPAN.it { } +DIV.navigation { } +PRE.preform { } +SPAN.tt { } +SPAN.arabic { } diff --git a/docs/nightly/fix/reconcile-info/ESMC_crefdoc/ESMC_crefdoc.html b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/ESMC_crefdoc.html new file mode 100644 index 000000000..5ec7d321f --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/ESMC_crefdoc.html @@ -0,0 +1,557 @@ + + + + +
++ +
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The ESMF software is based on the contributions of a broad community. +Below are the software packages that are included in ESMF or strongly +influenced our design. We'd like to express our gratitude to the +developers of these codes for access to their software as well as their +ideas and advice. + +
+ +
+
+
+
+
+
+
+
+
+
. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. ++
+ +
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The ESMF software is based on the contributions of a broad community. +Below are the software packages that are included in ESMF or strongly +influenced our design. We'd like to express our gratitude to the +developers of these codes for access to their software as well as their +ideas and advice. + +
+ +
+
+
+
+
+
+
+
+
+
+This document was generated using the +LaTeX2HTML translator Version 2018 (Released Feb 1, 2018) +
+Copyright © 1993, 1994, 1995, 1996,
+Nikos Drakos,
+Computer Based Learning Unit, University of Leeds.
+
+Copyright © 1997, 1998, 1999,
+Ross Moore,
+Mathematics Department, Macquarie University, Sydney.
+
+The command line arguments were:
+ latex2html -white -toc_depth 5 -split +1 -show_section_numbers -local_icons -address 'esmf_support@ucar.edu' ESMC_crefdoc.tex
+
+The translation was initiated on 2024-12-03
+
+ +
+The Earth System Modeling Framework (ESMF) is a suite of software +tools for developing high-performance, multi-component Earth science +modeling applications. Such applications may include a few or dozens +of components representing atmospheric, oceanic, terrestrial, or +other physical domains, and their constituent processes (dynamical, chemical, +biological, etc.). Often these components are developed by different +groups independently, and must be “coupled” together using software +that transfers and transforms data among the components in order to form +functional simulations. + +
+ESMF supports the development of these complex applications in a number +of ways. It introduces a set of simple, consistent component interfaces +that apply to all types of components, including couplers themselves. These +interfaces expose in an obvious way the inputs and outputs of each component. +It offers a variety of data structures for transferring data between components, +and libraries for regridding, time advancement, and other common modeling +functions. Finally, it provides a growing set of tools for using metadata +to describe components and their input and output fields. This capability +is important because components that are self-describing +can be integrated more easily into automated workflows, model and dataset +distribution and analysis portals, and other emerging “semantically enabled” +computational environments. + +
+ESMF is not a single Earth system model into which all components +must fit, and its distribution doesn't contain any scientific code. +Rather it provides a way of structuring components so that they can be used +in many different user-written applications and contexts with minimal code +modification, and so they can be coupled together in new configurations +with relative ease. The idea is to create many components across a +broad community, and so to encourage new collaborations and combinations. + +
+ESMF offers the flexibility needed by this diverse user base. It is tested +nightly on more than two dozen platform/compiler combinations; can be +run on one processor or thousands; supports shared and distributed memory +programming models and a hybrid model; can run components +sequentially (on all the same processors) or concurrently (on mutually +exclusive processors); and supports single executable or multiple +executable modes. + +
+ESMF's generality and breadth of function can make it daunting for the +novice user. To help users navigate the software, we try to apply +consistent names and behavior throughout and to provide many examples. +The large-scale structure of the software is straightforward. +The utilities and data structures for building modeling components +are called the ESMF infrastructure. The coupling interfaces and +drivers are called the superstructure. User code sits between +these two layers, making calls to the infrastructure +libraries underneath and being scheduled and synchronized by the +superstructure above. The configuration resembles a sandwich, as +shown in Figure 1. + +
+ESMF users may choose to extensively rewrite their codes +to take advantage of the ESMF infrastructure, or they may decide to +simply wrap their components in the ESMF superstructure in order to +utilize framework coupling services. Either way, we encourage users +to contact our +support team +if questions arise about how to best +use the software, or how to structure their application. ESMF is +more than software; it's a group of people dedicated to realizing +the vision of a collaborative model development community that spans +institutional and national bounds. + +
+ +
+ESMF has a complete set of Fortran interfaces and +some C interfaces. This ESMF Reference Manual is a listing of +ESMF interfaces for C. + +
+Interfaces are grouped by class. A class is comprised of the data and +methods for a specific concept like a physical field. Superstructure classes +are listed first in this Manual, followed by infrastructure +classes. + +
+The major classes in the ESMF superstructure are Components, which +usually represent +large pieces of functionality such as atmosphere and ocean models, +and States, which are the data structures +used to transfer data between Components. There are both data +structures and utilities in the ESMF +infrastructure. Data structures include multi-dimensional Arrays, Fields +that are comprised of an Array and a Grid, and collections of Arrays +and Fields called ArrayBundles and FieldBundles, respectively. +There are utility libraries for data decomposition and communications, +time management, logging and error handling, and application configuration. + +
+
+ |
+The website, http://www.earthsystemmodeling.org, provide more information of the ESMF project as a whole. +The website includes release notes and known bugs for each version of the +framework, supported platforms, project history, values, and metrics, related projects, +the ESMF management structure, and more. The ESMF User's Guide +contains build and installation instructions, an overview of the ESMF system and a description of +how its classes interrelate (this version of the document corresponds to the last public version of the framework). Also available on the ESMF website is the +ESMF Developer's Guide +that details ESMF procedures and conventions. + +
+ +
+ + +
+ +
+The ESMF Application Programming Interface (API) is based on the +object-oriented programming concept of a class. A class is a +software construct that is used for grouping a set of related variables +together with the subroutines and functions that operate on them. We +use classes in ESMF because they help to organize the code, and often +make it easier to maintain and understand. A particular instance +of a class is called an object. For example, Field is an +ESMF class. An actual Field called temperature is an object. +That is about as far as we will go into software engineering +terminology. + +
+The C interface is implemented so that the variables associated +with a class are stored in a C structure. For example, an +ESMC_Field structure stores the data array, grid +information, and metadata associated with a physical field. +The structure for each class is defined in a C header file. +The operations associated with each class are also +defined in the header files. + +
+The header files for ESMF are bundled together and can be accessed with a +single include statement, #include "ESMC.h". By convention, +the C entry points are named using “ESMC” as a prefix. + +
+ +
+ESMF defines a set of standard methods and interface rules that +hold across the entire API. These are: + +
+ +
+
+
+
+
+
+
+ +
+ESMF contains two types of classes. + +
+Deep classes require +ESMC_<Class>Create() and ESMC_<Class>Destroy() calls. +They involve memory allocation, take significant time to set up (due to +memory management) and should not be created in a time-critical portion of code. +Deep objects persist even after the method in which they were created has +returned. Most classes in ESMF, including GridComp, CplComp, State, Fields, FieldBundles, Arrays, ArrayBundles, Grids, and Clocks, fall into this category. + +
+Shallow classes do not possess ESMC_<Class>Create() +and ESMC_<Class>Destroy() calls. They are simply declared +and their values set using an ESMC_<Class>Set() call. +Examples of shallow classes are Time, TimeInterval, and ArraySpec. +Shallow classes do not take long to set up and can be declared and set within +a time-critical code segment. Shallow objects stop existing when execution +goes out of the declaring scope. + +
+An exception to this is when a shallow object, such as a Time, +is stored in a deep object such as a Clock. The deep Clock object then +becomes the declaring scope of the Time object, persisting in memory. +The Time object is deallocated with the ESMC_ClockDestroy() call. + +
+See Section 8, Overall Design and Implementation +Notes, for a brief discussion of deep and shallow classes from +an implementation perspective. For an in-depth look at the design + and inter-language issues related to deep and shallow classes, +see the ESMF Implementation Report. + +
+ +
+Deep objects, i.e. instances of ESMF deep classes created by the appropriate +ESMC_<Class>Create(), can be used with the standard assignment (=) +operator. + +
+The assignment +
+deep2 = deep1 ++makes deep2 an alias of deep1, meaning that both variables +reference the same deep allocation in memory. Many aliases of the same deep +object can be created. + +
+All the aliases of a deep object are equivalent. In particular, there is no +distinction between the variable on the left hand side of the actual +ESMC_<Class>Create() call, and any aliases created from it. All actions +taken on any of the aliases of a deep object affect the deep object, and thus +all other aliases. + +
+ +
+The following are special methods which, in one case, +are required by any application using ESMF, and in the +other case must be called by any application that is using +ESMF Components. + +
+ +
+
+ +
+The ESMF API is organized around a hierarchy of classes that +contain model data. The operations that are performed +on model data, such as regridding, redistribution, and halo +updates, are methods of these classes. + +
+The main data classes offered by the ESMF C API, in order of increasing complexity, are: + +
+
+Underlying these data classes are native language arrays. ESMF Arrays +and Fields can be queried for the C pointer to the actual data. You can +perform communication operations either on the ESMF data objects or +directly on C arrays through the VM class, which serves +as a unifying wrapper for distributed and shared memory communication +libraries. + +
+ +
+Like the hierarchy of model data classes, ranging from the +simple to the complex, ESMF is organized around a hierarchy of +classes that represent different spaces associated with a computation. +Each of these spaces can be manipulated, in order to give +the user control over how a computation is executed. For Earth system +models, this hierarchy starts with the address space associated +with the computer and extends to the physical region described by +the application. The main spatial classes in ESMF, from +those closest to the machine to those closest to the application, are: + +
+ +
+
+The current ESMF C API does not provide user access to the DELayout class. + +
+
+
+
+
+
+
+
+ +
+In order to define how the index spaces of the spatial classes relate +to each other, we require either implicit rules (in which case the +relationship between spaces is defined by default), or special Map arrays +that allow the user to specify the desired association. The form of the +specification is usually that the position of the array element carries +information about the first object, and the value of the array element carries +information about the second object. ESMF includes a distGridToArrayMap, +a gridToFieldMap, a distGridToGridMap, and others. + +
+ +
+It can be useful to make small packets +of descriptive parameters. ESMF has one of these: + +
+ +
+There are a number of utilities in ESMF that can be used independently. +These are: + +
+ +
+Depending on the requirements of the application, the user may +want to begin integrating ESMF in either a top-down or bottom-up +manner. In the top-down approach, tools at the superstructure +level are used to help reorganize and structure the interactions +among large-scale components in the application. It is appropriate +when interoperability is a primary concern; for example, when +several different versions or implementations of components are going +to be swapped in, or a particular component is going to be used +in multiple contexts. Another reason for deciding on a top-down +approach is that the application contains legacy code that for +some reason (e.g., intertwined functions, very large, +highly performance-tuned, resource limitations) there is little +motivation to fully restructure. The superstructure can usually be +incorporated into such applications in a way that is non-intrusive. + +
+In the bottom-up approach, the user selects desired utilities +(data communications, calendar management, performance profiling, +logging and error handling, etc.) from the ESMF infrastructure +and either writes new code using them, introduces them into +existing code, or replaces the functionality in existing code +with them. This makes sense when maximizing code reuse and +minimizing maintenance costs is a goal. There may be a specific +need for functionality or the component writer may be starting +from scratch. The calendar management utility is a popular +place to start. + +
+ +
+The following is a typical set of steps involved in adopting +the ESMF superstructure. The first two tasks, which occur +before an ESMF call is ever made, have the potential to be +the most difficult and time-consuming. They are the work +of splitting an application into components and ensuring that +each component has well-defined stages of execution. ESMF +aside, this sort of code structure helps to promote application +clarity and maintainability, and the effort put into it is likely +to be a good investment. + +
+ +
+
+
+
+
+
+
+
+ +
+Named constants are used throughout ESMF to specify the values of many +arguments with multiple well defined values in a consistent way. These +constants are defined by a derived type that follows this pattern: + +
+
+ESMF_<CONSTANT_NAME>_Flag ++ +
+The values of the constant are then specified by this pattern: + +
+
+ESMF_<CONSTANT_NAME>_<VALUE1> +ESMF_<CONSTANT_NAME>_<VALUE2> +ESMF_<CONSTANT_NAME>_<VALUE3> +... ++ +
+A master list of all available constants can be found in section +34. + +
+ +
+ +
+ESMF data objects such as Fields are distributed over +DEs, with each DE getting a portion of the data. Depending +on the task, a local or global view of the object may be +preferable. In a local view, data indices start with the first +element on the DE and end with the last element on the same DE. +In a global view, there is an assumed or specified order to +the set of DEs over which the object is distributed. Data +indices start with the first element on the first DE, and +continue across all the elements in the sequence of DEs. +The last data index represents the number of elements in the +entire object. The DistGrid provides the mapping between +local and global data indices. + +
+The convention in ESMF is that entities with a global view +have no prefix. Entities with a DE-local (and in some cases, +PET-local) view have the prefix “local.” + +
+Just as data is distributed over DEs, DEs themselves can be +distributed over PETs. This is an advanced feature for users +who would like to create multiple local chunks of data, for +algorithmic or performance reasons. +Local DEs are those DEs that are located on the local PET. +Local DE labeling always starts at 0 and goes to localDeCount-1, +where localDeCount is the number of DEs on the local PET. +Global DE numbers also start at 0 and go to deCount-1. +The DELayout class provides the mapping between local +and global DE numbers. + +
+ +
+The basic rule of allocation and deallocation for the ESMF is: +whoever allocates it is responsible for deallocating it. + +
+ESMF methods that allocate their own space for data will +deallocate that space when the object is destroyed. +Methods which accept a user-allocated buffer, for example +ESMC_FieldCreate() with the ESMF_DATACOPY_REFERENCE flag, +will not deallocate that buffer at the time the object is +destroyed. The user must deallocate the buffer +when all use of it is complete. + +
+Classes such as Fields, FieldBundles, and States may have Arrays, +Fields, Grids and FieldBundles created externally and associated with +them. These associated items are not destroyed along with the rest +of the data object since it is possible for the items to be added +to more than one data object at a time (e.g. the same Grid could +be part of many Fields). It is the user's responsibility to delete +these items when the last use of them is done. + +
+ +
+The equal sign assignment has not been overloaded in ESMF, thus resulting in +the standard C behavior. This behavior has been documented as the first +entry in the API documentation section for each ESMF class. For deep ESMF +objects the assignment results in setting an alias the the same ESMF object +in memory. For shallow ESMF objects the assignment is essentially a equivalent +to a copy of the object. For deep classes the equality operators have been +overloaded to test for the alias condition as a counter part to the assignment +behavior. This and the not equal operator are documented following the +assignment in the class API documentation sections. + +
+Deep object copies are implemented as a special variant of the +ESMC_<Class>Create() methods. It takes an existing deep object as +one of the required arguments. At this point not all deep classes have +ESMC_<Class>Create() methods that allow object copy. + +
+Due to the complexity of deep classes there are many aspects when comparing two +objects of the same class. ESMF provide ESMC_<Class>Match() methods, +which are functions that return a class specific match flag. At this point not +all deep classes have ESMC_<Class>Match() methods that allow deep object +comparison. + +
+ +
+ +
+
+
+The main product delivered by ESMF is the ESMF library that allows application +developers to write programs based on the ESMF API. In addition to the +programming library, ESMF distributions come with a small set of command line +tools (CLT) that are of general interest to the community. These CLTs utilize +the ESMF library to implement features such as printing general information +about the ESMF installation, or generating regrid weight files. The provided +ESMF CLTs are intended to be used as standard command line tools. + +
+The bundled ESMF CLTs are built and installed during the usual ESMF +installation process, which is described in detail in the ESMF User's Guide +section "Building and Installing the ESMF". After installation, the +CLTs will be located in the ESMF_APPSDIR directory, which can +be found as a Makefile variable in the esmf.mk file. The esmf.mk +file can be found in the ESMF_INSTALL_LIBDIR directory after a +successful installation. The ESMF User's Guide discusses the esmf.mk +mechanism to access the bundled CLTs in more detail in section +"Using Bundled ESMF Command Line Tools". + +
+The following sections provide in-depth documentation of the bundled ESMF
+CLTs. In addition, each tool supports the standard
+ --help
command line argument, providing a brief description of how
+to invoke the program.
+
+
+ +
+ESMF superstructure classes define an architecture for assembling +Earth system applications from modeling components. A component +may be defined in terms of the physical domain that it represents, +such as an atmosphere or sea ice model. It may also be defined in terms +of a computational function, such as a data assimilation system. +Earth system research often requires that such components be coupled +together to create an application. By coupling we mean the data +transformations and, on parallel computing systems, data transfers, +that are necessary to allow data from one component to be utilized by +another. ESMF offers regridding methods and other tools to simplify +the organization and execution of inter-component data exchanges. + +
+In addition to components defined at the level of major physical +domains and computational functions, components may be defined that +represent smaller computational functions within larger components, +such as the transformation of data between the physics and dynamics +in a spectral atmosphere model, +or the creation of nested higher resolution regions +within a coarser grid. The objective is to couple components at varying +scales both flexibly and efficiently. ESMF encourages a hierarchical +application structure, in which large components branch into +smaller sub-components (see Figure 2). ESMF also makes +it easier for the same component to be used in multiple contexts +without changes to its source code. + +
+
+ +Key Features |
+
Modular, component-based architecture. | +
Hierarchical assembly of components into applications. | +
Use of components in multiple contexts without modification. | +
Sequential or concurrent component execution. | +
Single program, multiple datastream (SPMD) applications for +maximum portability and reconfigurability. | +
Multiple program, multiple datastream (MPMD) option for +flexibility. | +
+ +
+There are a small number of classes in the ESMF superstructure: + +
+ +
+The second part of an ESMF Component is user code, such as a +model or data assimilation system. Users set entry points +within their code so that it is callable by the framework. +In practice, setting entry points means that within user code +there are calls to ESMF methods that associate the name of a +Fortran subroutine with a corresponding standard ESMF operation. +For example, a user-written initialization routine called +myOceanInit might be associated with the standard +initialize routine of an ESMF Gridded Component named “myOcean” +that represents an ocean model. + +
+
+
+An ESMF coupled application typically involves a parent Gridded Component, +two or more child Gridded Components and one or more Coupler +Components. + +
+The parent Gridded Component is responsible for creating the child +Gridded Components that are exchanging data, for creating the Coupler, +for creating the necessary Import and Export States, and for +setting up the desired sequencing. The application's “main” routine +calls the parent Gridded Component's initialize, run, and finalize +methods in order to execute the application. For each of these +standard methods, the parent Gridded Component in turn calls the +corresponding methods in the child Gridded Components and the +Coupler Component. For example, consider a simple coupled +ocean/atmosphere simulation. When the initialize method of the +parent Gridded Component is called by the application, it in turn +calls the initialize methods of its child atmosphere and ocean +Gridded Components, and the initialize method of an +ocean-to-atmosphere Coupler Component. Figure 3 +shows this schematically. + +
+
+ |
+ +
+Components are allocated computational resources in the form of +Persistent Execution Threads, or PETs. A list of a Component's +PETs is contained in a structure called a Virtual Machine, +or VM. The VM also contains information about the topology and +characteristics of the underlying computer. +Components are created hierarchically, with parent Components creating +child Components and allocating some or all of their PETs to each one. +By default ESMF creates a new VM for each child Component, which +allows Components to tailor their VM resources to match their needs. +In some cases, a child may want to share its parent's VM - ESMF +supports this, too. + +
+A Gridded Component may exist across all the PETs in an application. +A Gridded Component may also reside on a subset of PETs in an +application. These PETs may wholly coincide with, be wholly contained +within, or wholly contain another Component. + +
+
+ |
+ +
+When a set of Gridded Components and a Coupler runs in sequence +on the same set of PETs the application is executing in a sequential +mode. When Gridded Components are created and run on mutually exclusive +sets of PETs, and are coupled by a Coupler Component that extends over +the union of these sets, the mode of execution is concurrent. + +
+Figure 4 illustrates a typical configuration for +a simple coupled sequential +application, and Figure 5 shows a possible +configuration for the same application running in a concurrent mode. + +
+Parent Components can select if and when to wait for concurrently +executing child Components, synchronizing only when required. + +
+It is possible for ESMF applications to contain some Component sets +that are executing sequentially and others that are executing concurrently. +We might have, for example, atmosphere and land Components created +on the same subset of PETs, ocean and sea ice Components created on +the remainder of PETs, and a Coupler created across all the PETs in +the application. + +
+
+ |
+
+ |
+ +
+All data transfers within an ESMF application occur within a +component. For example, a Gridded Component may contain halo updates. +Another example is that a Coupler Component may redistribute +data between two Gridded Components. As a result, +the architecture of ESMF does not depend on any particular data +communication mechanism, and new communication schemes can be +introduced without affecting the overall structure of the application. + +
+Since all data communication happens within a component, a Coupler +Component must be created on the union of the PETs of all +the Gridded Components that it couples. + +
+ +
+The scope of distributed objects is the VM of the currently +executing Component. For this reason, all +PETs in the current VM must make the same distributed object +creation calls. When a Coupler Component running on a superset +of a Gridded Component's PETs needs to make communication calls +involving objects created by the Gridded Component, +an ESMF-supplied function called ESMF_StateReconcile() creates proxy +objects for those PETs that had no previous information about the +distributed objects. Proxy objects contain no local data but +can be used in communication calls (such as regrid or redistribute) +to describe the remote source for data being moved to the current PET, +or to describe the remote destination for data being moved from the local PET. +Figure 6 is a simple schematic that shows the +sequence of events in a reconcile call. + +
+
+ |
+ +
+The ESMF design enables the user to configure ESMF +applications so that data is transferred directly from one component +to another, without requiring that it be copied or sent to a different data +buffer as an interim step. This is likely to be the most efficient way +of performing inter-component coupling. However, if desired, an +application can also be configured so that data from a source component +is sent to a distinct set of Coupler Component PETs for processing +before being sent to its destination. + +
+The ability to overlap computation with communication is essential for +performance. When running with ESMF the user can initiate data +sends during Gridded Component execution, as soon as the data is ready. +Computations can then proceed simultaneously with the data transfer. + +
+ +
+The following is a simplified Unified Modeling Language (UML) diagram showing the relationships among +ESMF superstructure classes. See Appendix A, A Brief Introduction +to UML, for a translation table that lists the symbols in the diagram +and their meaning. + +
+
+ +
+Every ESMF application needs a driver code. Typically the driver layer is +implemented as the "main" of the application, although this is not strictly an +ESMF requirement. For most ESMF applications the task of the application driver +will be very generic: Initialize ESMF, create a top-level Component and call its +Initialize, Run and Finalize methods, before destroying the top-level Component +again and calling ESMF Finalize. + +
+ESMF provides a number of different application driver templates in the +$ESMF_DIR/src/Superstructure/AppDriver directory. An appropriate one +can be chosen depending on how the application is to be structured: + +
+
+In a sequential execution model, every Component executes +on all PETs, with each Component completing execution before +the next Component begins. This has the appeal of +simplicity of data consumption and production: when a Gridded +Component starts, all required data is available for use, and when +a Gridded Component finishes, all data produced is ready for consumption +by the next Gridded Component. This approach also has +the possibility of less data movement if the grid and +data decomposition is done such that each processor's memory contains +the data needed by the next Component. + +
+In a concurrent execution model, subgroups of PETs run +Gridded Components and multiple Gridded Components are active at the +same time. Data exchange must be coordinated between Gridded +Components so that data deadlock does not occur. This strategy +has the advantage of allowing coupling to other Gridded Components +at any time during the computational process, including not +having to return to the calling level of code before making +data available. + +
+
+Coupler Components are responsible for taking data from one +Gridded Component and putting it into the form expected by another +Gridded Component. This might include regridding, change of units, +averaging, or binning. + +
+Coupler Components can be written for pairwise data exchange: +the Coupler Component takes data from a single Component and transforms +it for use by another single Gridded Component. This simplifies the +structure of the Coupler Component code. + +
+Couplers can also be written using a hub and spoke model where a +single Coupler accepts data from all other Components, can do data +merging or splitting, and formats data for all other Components. + +
+Multiple Couplers, using either of the above two models or some mixture of +these approaches, are also possible. + +
+
+The ESMF framework currently has Fortran interfaces for all public functions. +Some functions also have C interfaces, and the number of these is expected to +increase over time. + +
+
+The simplest way to run an application +is to run the same executable program on all PETs. Different Components +can still be run on mutually exclusive PETs by using branching +(e.g., if this is PET 1, 2, or 3, run Component A, if it is +PET 4, 5, or 6 run Component B). This is a SPMD model, +Single Program Multiple Data. + +
+The alternative is to start a different executable program on different +PETs. This is a MPMD model, Multiple Program Multiple Data. +There are complications with many job control systems on multiprocessor +machines in getting the different executables started, and getting +inter-process communications established. ESMF currently has some +support for MPMD: different Components can run as separate executables, +but the Coupler that transfers data between the Components must still +run on the union of their PETs. This means that the Coupler Component +must be linked into all of the executables. + +
+
+ +
+There are a few methods that every ESMF application must contain. First, +ESMC_Initialize() and ESMC_Finalize() are in complete analogy +to MPI_Init() and MPI_Finalize() known from MPI. All ESMF +programs, serial or parallel, must initialize the ESMF system at the beginning, +and finalize it at the end of execution. The behavior of calling any +ESMF method before ESMC_Initialize(), or after ESMC_Finalize() +is undefined. + +
+Second, every ESMF Component that is accessed by an ESMF application requires +that its set services routine is called through +ESMC_<Grid/Cpl>CompSetServices(). The Component must implement +one public entry point, its set services routine, that can be called +through the ESMC_<Grid/Cpl>CompSetServices() library routine. The +Component set services routine is responsible for setting entry points +for the standard ESMF Component methods Initialize, Run, and Finalize. + +
+Finally, the Component can optionally call ESMC_<Grid/Cpl>CompSetVM()
+before calling
+ESMC_<Grid/Cpl>CompSetServices(). Similar to
+ESMC_<Grid/Cpl>CompSetServices(), the
+
+ESMC_<Grid/Cpl>CompSetVM()
+call requires a public entry point into the Component. It allows the Component
+to adjust certain aspects of its execution environment, i.e. its own VM, before
+it is started up.
+
+
+The following sections discuss the above mentioned aspects in more detail. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_Initialize( + int *rc, // return code + ...); // optional arguments (see below) +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Initialize the ESMF. This method must be called before + any other ESMF methods are used. The method contains a + barrier before returning, ensuring that all processes + made it successfully through initialization. + +
+Typically ESMC_Initialize() will call MPI_Init() + internally unless MPI has been initialized by the user code before + initializing the framework. If the MPI initialization is left to + ESMC_Initialize() it inherits all of the MPI implementation + dependent limitations of what may or may not be done before + MPI_Init(). For instance, it is unsafe for some MPI implementations, + such as MPICH1, to do I/O before the MPI environment is initialized. Please + consult the documentation of your MPI implementation for details. + +
+Optional arguments are recognised. To indicate the end of the optional + argument list, ESMC_ArgLast must be used. A minimal call to + ESMC_Initialize() would be: +
+ ESMC_Initialize (NULL, ESMC_ArgLast); ++ The optional arguments are specified using the ESMC_InitArg macros. + For example, to turn off logging so that no log files would be created, the + ESMC_Initialize() call would be coded as: +
+ ESMC_Initialize (&rc, + ESMC_InitArgLogKindFlag(ESMC_LOGKIND_NONE), + ESMC_ArgLast); ++ Before exiting the application the user must call ESMC_Finalize() + to release resources and clean up the ESMF gracefully. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_FinalizeWithFlag( + ESMC_End_Flag endFlag); // enumerator for exit action (see below) +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+This must be called once on each PET before the application exits to + allow ESMF to flush buffers, close open connections, and release + internal resources cleanly. + +
+The endFlag argument has one of three options: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_Finalize(void); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+This must be called once on each PET before the application exits to + allow ESMF to flush buffers, close open connections, and release + internal resources cleanly. + + +
+In Earth system modeling, the most natural way to think about an ESMF +Gridded Component, or ESMC_GridComp, is as a piece of code +representing a particular physical domain, such as an atmospheric +model or an ocean model. Gridded Components may also represent individual +processes, such as radiation or chemistry. It's up to the application +writer to decide how deeply to “componentize.” + +
+Earth system software components tend to share a number of basic +features. Most ingest and produce a variety of physical fields, refer to +a (possibly noncontiguous) spatial region and a grid that is +partitioned across a set of computational resources, and require +a clock for things like stepping a governing set of PDEs forward in time. +Most can also be divided into distinct initialize, run, and finalize +computational phases. These common characteristics are used +within ESMF to define a Gridded Component data structure that +is tailored for Earth system modeling and yet is still flexible +enough to represent a variety of domains. + +
+A well designed Gridded Component does not store information +internally about how it couples to other Gridded Components. That +allows it to be used in different contexts without changes to source +code. The idea here is to avoid situations in which slightly +different versions of the same model source are maintained for use in +different contexts - standalone vs. coupled versions, for example. +Data is passed in and out of Gridded Components using an ESMF State, +this is described in Section 14.1. + +
+An ESMF Gridded Component has two parts, one which is user-written +and another which is part of the framework. The user-written +part is software that represents a physical domain or performs some +other computational function. It forms the body of the Gridded +Component. It may be a piece of legacy code, or it may be developed +expressly for use with ESMF. It must contain routines with +standard ESMF interfaces that can be called to initialize, run, and +finalize the Gridded Component. These routines can have separate +callable phases, such as distinct first and second initialization steps. + +
+ESMF provides the Gridded Component derived type, +ESMC_GridComp. An ESMC_GridComp must be created +for every portion of the application that will be represented +as a separate component. For example, in a climate model, there may +be Gridded Components representing the land, ocean, sea ice, and +atmosphere. If the application contains an ensemble of identical +Gridded Components, every one has its own associated ESMC_GridComp. +Each Gridded Component has its own name and is allocated +a set of computational resources, in the form of an ESMF Virtual +Machine, or VM. + +
+The user-written part of a Gridded Component is associated with an +ESMC_GridComp derived type through a routine called +ESMC_SetServices(). +This is a routine that the user must write, and declare public. +Inside the SetServices routine the user must call +ESMC_SetEntryPoint() methods that associate a standard ESMF +operation with the name of the corresponding Fortran subroutine +in their user code. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_GridComp ESMC_GridCompCreate( + const char *name, // in + const char *configFile, // in + ESMC_Clock clock, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_GridComp object. ++DESCRIPTION: +
+This interface creates an ESMC_GridComp object. By default, a + separate VM context will be created for each component. This implies + creating a new MPI communicator and allocating additional memory to + manage the VM resources. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridCompDestroy( + ESMC_GridComp *comp // inout + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Releases all resources associated with this ESMC_GridComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridCompFinalize( + ESMC_GridComp comp, // inout + ESMC_State importState, // inout + ESMC_State exportState, // inout + ESMC_Clock clock, // in + int phase, // in + int *userRc // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Call the associated user finalize code for a GridComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void *ESMC_GridCompGetInternalState( + ESMC_GridComp comp, // in + int *rc // out + ); +RETURN VALUE: +
Pointer to private data block that is stored in the internal state. ++DESCRIPTION: +
+Available to be called by an ESMC_GridComp at any time after + ESMC_GridCompSetInternalState has been called. Since init, run, and + finalize must be separate subroutines, data that they need to share in + common can either be global data, or can be allocated in a private data + block and the address of that block can be registered with the framework + and retrieved by this call. When running multiple instantiations of an + ESMC_GridComp, for example during ensemble runs, it may be simpler + to maintain private data specific to each run with private data blocks. A + corresponding ESMC_GridCompSetInternalState call sets the data + pointer to this block, and this call retrieves the data pointer. + +
+Only the last data block set via ESMC_GridCompSetInternalState + will be accessible. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridCompInitialize( + ESMC_GridComp comp, // inout + ESMC_State importState, // inout + ESMC_State exportState, // inout + ESMC_Clock clock, // in + int phase, // in + int *userRc // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Call the associated user initialization code for a GridComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridCompPrint( + ESMC_GridComp comp // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Prints information about an ESMC_GridComp to stdout. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridCompRun( + ESMC_GridComp comp, // inout + ESMC_State importState, // inout + ESMC_State exportState, // inout + ESMC_Clock clock, // in + int phase, // in + int *userRc // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Call the associated user run code for a GridComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridCompSetEntryPoint( + ESMC_GridComp comp, // in + enum ESMC_Method method, // in + void (*userRoutine) // in + (ESMC_GridComp, ESMC_State, ESMC_State, ESMC_Clock *, int *), + int phase // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Registers a user-supplied userRoutine as the entry point for one of + the predefined Component methods. After this call the userRoutine + becomes accessible via the standard Component method API. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridCompSetInternalState( + ESMC_GridComp comp, // inout + void *data // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Available to be called by an ESMC_GridComp at any time, but + expected to be most useful when called during the registration process, + or initialization. Since init, run, and finalize must be separate + subroutines, data that they need to share in common can either be global + data, or can be allocated in a private data block and the address of that + block can be registered with the framework and retrieved by subsequent + calls. + When running multiple instantiations of an ESMC_GridComp, + for example during ensemble runs, it may be simpler to maintain private + data specific to each run with private data blocks. A corresponding + ESMC_GridCompGetInternalState call retrieves the data pointer. + +
+Only the last data block set via + ESMC_GridCompSetInternalState will be accessible. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridCompSetServices( + ESMC_GridComp comp, // in + void (*userRoutine)(ESMC_GridComp, int *), // in + int *userRc // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Call into user provided userRoutine which is responsible for setting + Component's Initialize(), Run() and Finalize() services. + +
+The arguments are: +
+The Component writer must supply a subroutine with the exact interface shown + above for the userRoutine argument. + +
+The userRoutine, when called by the framework, must make successive + calls to ESMC_GridCompSetEntryPoint() to preset callback routines for + standard Component Initialize(), Run() and Finalize() methods. + +
+ + +
+In a large, multi-component application such as a weather +forecasting or climate prediction system running within ESMF, +physical domains and major system functions are represented +as Gridded Components +(see Section 11.1). A Coupler Component, or +ESMC_CplComp, arranges and executes the data +transformations between the Gridded Components. Ideally, +Coupler Components should contain all the information +about inter-component communication for an application. +This enables the Gridded Components in the application to be +used in multiple contexts; that is, used in different coupled +configurations without changes to their source code. +For example, the same atmosphere might in one case be coupled +to an ocean in a hurricane prediction model, and to a +data assimilation system for numerical weather prediction in +another. A single Coupler Component can couple +two or more Gridded Components. + +
+Like Gridded Components, Coupler Components have two parts, one +that is provided by the user and another that is part of the +framework. The user-written portion of the software is the coupling +code necessary for a particular exchange between Gridded Components. +This portion of the Coupler Component code must be divided into +separately callable initialize, run, and finalize methods. The +interfaces for these methods are prescribed by ESMF. + +
+The term “user-written” is somewhat misleading here, since within +a Coupler Component the user can leverage ESMF infrastructure +software for regridding, redistribution, lower-level communications, +calendar management, and other functions. However, ESMF is unlikely +to offer all the software necessary to customize a data transfer +between Gridded Components. For instance, ESMF does not currently +offer tools for unit tranformations or time averaging operations, +so users must manage those operations themselves. + +
+The second part of a Coupler Component is the ESMC_CplComp +derived type within ESMF. The user must create one of these types +to represent a specific coupling function, such as the regular +transfer of data between a data assimilation system and an +atmospheric model. 1 +
+The user-written part of a Coupler Component is associated with an +ESMC_CplComp derived type through a routine called +ESMC_SetServices(). +This is a routine that the user must write and declare public. +Inside the ESMC_SetServices() routine the user must call +ESMC_SetEntryPoint() methods that associate a standard ESMF +operation with the name of the corresponding Fortran subroutine in +their user code. For example, a user routine called “couplerInit” +might be associated with the standard initialize routine in a +Coupler Component. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_CplComp ESMC_CplCompCreate( + const char *name, // in + const char *configFile, // in + ESMC_Clock clock, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_CplComp object. ++DESCRIPTION: +
+This interface creates an ESMC_CplComp object. By default, a + separate VM context will be created for each component. This implies + creating a new MPI communicator and allocating additional memory to + manage the VM resources. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_CplCompDestroy( + ESMC_CplComp *comp // inout + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Releases all resources associated with this ESMC_CplComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_CplCompFinalize( + ESMC_CplComp comp, // inout + ESMC_State importState, // inout + ESMC_State exportState, // inout + ESMC_Clock clock, // in + int phase, // in + int *userRc // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Call the associated user finalize code for a CplComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void *ESMC_CplCompGetInternalState( + ESMC_CplComp comp, //in + int *rc // out + ); +RETURN VALUE: +
Pointer to private data block that is stored in the internal state. ++DESCRIPTION: +
+Available to be called by an ESMC_CplComp at any time after + ESMC_CplCompSetInternalState has been called. Since init, run, and + finalize must be separate subroutines, data that they need to share in + common can either be global data, or can be allocated in a private data + block and the address of that block can be registered with the framework + and retrieved by this call. When running multiple instantiations of an + ESMC_CplComp, for example during ensemble runs, it may be simpler + to maintain private data specific to each run with private data blocks. A + corresponding ESMC_CplCompSetInternalState call sets the data + pointer to this block, and this call retrieves the data pointer. + +
+Only the last data block set via ESMC_CplCompSetInternalState + will be accessible. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_CplCompInitialize( + ESMC_CplComp comp, // inout + ESMC_State importState, // inout + ESMC_State exportState, // inout + ESMC_Clock clock, // in + int phase, // in + int *userRc // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Call the associated user initialize code for a CplComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_CplCompPrint( + ESMC_CplComp comp // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Prints information about an ESMC_CplComp to stdout. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_CplCompRun( + ESMC_CplComp comp, // inout + ESMC_State importState, // inout + ESMC_State exportState, // inout + ESMC_Clock clock, // in + int phase, // in + int *userRc // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Call the associated user run code for a CplComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_CplCompSetEntryPoint( + ESMC_CplComp comp, // in + enum ESMC_Method method, // in + void (*userRoutine) // in + (ESMC_CplComp, ESMC_State, ESMC_State, ESMC_Clock *, int *), + int phase // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Registers a user-supplied userRoutine as the entry point for one of + the predefined Component methods. After this call the userRoutine + becomes accessible via the standard Component method API. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_CplCompSetInternalState( + ESMC_CplComp comp, // inout + void *data // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Available to be called by an ESMC_CplComp at any time, but + expected to be most useful when called during the registration process, + or initialization. Since init, run, and finalize must be separate + subroutines, data that they need to share in common can either be global + data, or can be allocated in a private data block and the address of that + block can be registered with the framework and retrieved by subsequent + calls. + When running multiple instantiations of an ESMC_CplComp, + for example during ensemble runs, it may be simpler to maintain private + data specific to each run with private data blocks. A corresponding + ESMC_CplCompGetInternalState call retrieves the data pointer. + +
+Only the last data block set via + ESMC_CplCompSetInternalState will be accessible. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_CplCompSetServices( + ESMC_CplComp comp, // in + void (*userRoutine)(ESMC_CplComp, int *), // in + int *userRc // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Call into user provided userRoutine which is responsible for setting + Component's Initialize(), Run() and Finalize() services. + +
+The arguments are: +
+The Component writer must supply a subroutine with the exact interface shown + above for the userRoutine argument. + +
+The userRoutine, when called by the framework, must make successive + calls to ESMC_CplCompSetEntryPoint() to preset callback routines for + standard Component Initialize(), Run() and Finalize() methods. + +
+ + +
+In Earth system modeling, a particular piece of code representing a physical +domain, such as an atmospheric model or an ocean model, is typically +implemented as an ESMF Gridded Component, or ESMC_GridComp. +However, there are times when physical domains, or realms, need to be +represented, but aren't actual pieces of code, or software. These domains +can be implemented as ESMF Science Components, or ESMC_SciComp. + +
+Unlike Gridded and Coupler Components, Science Components are not associated +with software; they don't include execution routines such as initialize, +run and finalize. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_SciComp ESMC_SciCompCreate( + const char *name, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_SciComp object. ++DESCRIPTION: +
+This interface creates an ESMC_SciComp object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_SciCompDestroy( + ESMC_SciComp *comp // inout + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Releases all resources associated with this ESMC_SciComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_SciCompPrint( + ESMC_SciComp comp // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Prints information about an ESMC_SciComp to stdout. + +
+The arguments are: +
+ + +
+A State contains the data and metadata to be transferred between +ESMF Components. It is an important class, because it defines a +standard for how data is represented in data transfers between Earth +science components. The +State construct is a rational compromise between a fully prescribed +interface - one that would dictate what specific fields should be +transferred between components - and an interface in which data structures +are completely ad hoc. + +
+There are two types of States, import and export. +An import State contains data that is necessary for a Gridded Component +or Coupler Component to execute, and an export State contains the data +that a Gridded Component or Coupler Component can make available. + +
+States can contain Arrays, ArrayBundles, Fields, FieldBundles, +and other States. However, the current C API only provides State access to +Arrays, Fields and nested States. +States cannot directly contain native language arrays +(i.e. Fortran or C style arrays). Objects in a State must span +the VM on which they are running. For sequentially executing components +which run on the same set of PETs this happens by calling the object +create methods on each PET, creating the object in unison. For +concurrently executing components which are running on subsets of PETs, +an additional method, called ESMF_StateReconcile(), is provided by +ESMF to broadcast information +about objects which were created in sub-components. +Currently this method is only available through the ESMF Fortran API. Hence +the Coupler Component reponsible for reconciling States from Component that +execute on subsets of PETs must be written in Fortran. + +
+State methods include creation and deletion, adding and retrieving +data items, and performing queries. + +
+ +
+ +
+One important request by the user community during the ESMF object design was +that there be no communication overhead or synchronization when creating +distributed ESMF objects. As a consequence it is required to create these +objects in unison across all PETs in order to keep the ESMF object +identification in sync. + +
+
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_StateAddArray( + ESMC_State state, // in + ESMC_Array array // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Add an Array object to a ESMC_State object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_StateAddField( + ESMC_State state, // in + ESMC_Field field // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Add an Array object to a ESMC_State object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_State ESMC_StateCreate( + const char *name, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_State object. ++DESCRIPTION: +
+Create an ESMC_State object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_StateDestroy( + ESMC_State *state // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Destroy a ESMC_State object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_StateGetArray( + ESMC_State state, // in + const char *name, // in + ESMC_Array *array // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Obtain a pointer to an ESMC_Array object contained within + a State. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_StateGetField( + ESMC_State state, // in + const char *name, // in + ESMC_Field *field // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Obtain a pointer to a ESMC_Field object contained within + a State. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_StatePrint( + ESMC_State state // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Prints the contents of a ESMC_State object. + +
+The arguments are: +
+ + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMC_crefdoc/node5.html b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/node5.html new file mode 100644 index 000000000..6f87a3ccb --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/node5.html @@ -0,0 +1,6306 @@ + + + + + ++ +
+The ESMF infrastructure data classes are part of the framework's +hierarchy of structures for handling Earth system model data and +metadata on parallel platforms. The hierarchy is in complexity; the +simplest data class in the infrastructure represents a distributed data +array and the most complex data class represents a bundle of physical +fields that are discretized on the same grid. However, the current C API +does not support bundled data structures yet. Array and Field are the two +data classes offered by the ESMF C language binding. Data class methods +are called both from user-written code and from other classes +internal to the framework. + +
+Data classes are distributed over DEs, or Decomposition Elements. +A DE represents a piece of a decomposition. A DELayout is a collection +of DEs with some associated connectivity that describes a specific +distribution. For example, the distribution of a grid divided +into four segments in the x-dimension would be expressed in ESMF as +a DELayout with four DEs lying along an x-axis. This abstract concept +enables a data decomposition to be defined in +terms of threads, MPI processes, virtual decomposition elements, or +combinations of these without changes to user code. This is a +primary strategy for ensuring optimal performance and portability +for codes using the ESMF for communications. + +
+ESMF data classes provide a standard, +convenient way for developers to collect together information +related to model or observational data. The information assembled +in a data class includes a data pointer, a set of attributes +(e.g. units, although attributes can also be user-defined), and a +description of an associated grid. The same set of information within +an ESMF data object can be used by the framework to arrange +intercomponent data transfers, to perform I/O, for communications +such as gathers and scatters, for simplification of interfaces +within user code, for debugging, and for other functions. +This unifies and organizes codes overall so that the user need not +define different representations of metadata for the same field +for I/O and for component coupling. + +
+Since it is critical that users be able to introduce ESMF into their +codes easily and incrementally, ESMF data classes can be created based +on native Fortran pointers. Likewise, there are methods for retrieving +native Fortran pointers from within ESMF data objects. This allows +the user to perform allocations using ESMF, and to retrieve Fortran +arrays later for optimized model calculations. The ESMF data classes +do not have associated differential operators or other mathematical +methods. + +
+For flexibility, it is not necessary to build an ESMF data object +all at once. For example, it's possible to create a +field but to defer allocation of the associated field data until +a later time. + +
+
+ +Key Features |
+
Hierarchy of data structures designed specifically for the Earth +system domain and high performance, parallel computing. | +
Multi-use ESMF structures simplify user code overall. | +
Data objects support incremental construction and deferred allocation. | +
Native Fortran arrays can be associated with or retrieved from ESMF data +objects, for ease of adoption, convenience, and performance. | +
+ +
+The main classes that are used for model and observational data manipulation +are as follows: + +
+ +
+Data elements in Arrays are partitioned into categories +defined by the role the data element plays in distributed halo +operations. Haloing - sometimes called ghosting - is the +practice of copying portions of array data to multiple memory +locations to ensure that data dependencies can be satisfied +quickly when performing a calculation. ESMF Arrays contain +an exclusive domain, which contains data elements +updated exclusively and definitively by a given DE; a +computational domain, which contains all data elements +with values that are updated by the DE in computations; and +a total domain, which includes both the computational +domain and data elements from other DEs which may be read +but are not updated in computations. + +
+
+
+ +
+ +
+ +
+
+An ESMF Field represents a physical field, such as temperature. +The motivation for including Fields in ESMF is that bundles of +Fields are the entities that are normally exchanged when coupling +Components. + +
+The ESMF Field class contains distributed and discretized field data, a reference +to its associated grid, and metadata. The Field class stores the grid staggering +for that physical field. +This is the relationship of how the data array of a field maps onto a grid +(e.g. one item per +cell located at the cell center, one item per cell located at the NW +corner, one item per cell vertex, etc.). This means that different Fields +which are on the same underlying ESMF Grid but have different +staggerings can share the same Grid object without needing to replicate +it multiple times. + +
+Fields can be added to States for use in inter-Component +data communications. + +
+Field communication capabilities include: data redistribution, regridding, scatter, +gather, sparse-matrix multiplication, and halo update. These are discussed +in more detail in the documentation for the specific method calls. +ESMF does not currently support vector fields, so the components of +a vector field must be stored as separate Field objects. + +
+ +
+DESCRIPTION:
+
+Specify which interpolation method to use during regridding.
+
+
+The type of this flag is: + +
+type(ESMC_RegridMethod_Flag) + +
+The valid values are: +
+A Field serves as an annotator of data, since it carries +a description of the grid it is associated with and metadata +such as name and units. Fields can be used in this capacity +alone, as convenient, descriptive containers into which arrays +can be placed and retrieved. However, for most codes the primary +use of Fields is in the context of import and export States, +which are the objects that carry coupling information between +Components. Fields enable data to be self-describing, and a +State holding ESMF Fields contains data in a standard format +that can be queried and manipulated. + +
+The sections below go into more detail about Field usage. + +
+ +
+Fields can be created and destroyed at any time during +application execution. However, these Field methods require +some time to complete. We do not recommend that the user +create or destroy Fields inside performance-critical +computational loops. + +
+All versions of the ESMC_FieldCreate() +routines require a Mesh object as input. +The Mesh contains the information needed to know which +Decomposition Elements (DEs) are participating in +the processing of this Field, and which subsets of the data +are local to a particular DE. + +
+The details of how the create process happens depend +on which of the variants of the ESMC_FieldCreate() +call is used. + +
+When finished with an ESMC_Field, the ESMC_FieldDestroy method +removes it. However, the objects inside the ESMC_Field +created externally should be destroyed separately, +since objects can be added to +more than one ESMC_Field. For example, the same ESMF_Mesh +can be referenced by multiple ESMC_Fields. In this case the +internal Mesh is not deleted by the ESMC_FieldDestroy call. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Field ESMC_FieldCreateGridArraySpec( + ESMC_Grid grid, // in + ESMC_ArraySpec arrayspec, // in + enum ESMC_StaggerLoc staggerloc, // in + ESMC_InterArrayInt *gridToFieldMap, // in + ESMC_InterArrayInt *ungriddedLBound, // in + ESMC_InterArrayInt *ungriddedUBound, // in + const char *name, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_Field object. ++DESCRIPTION: +
+Creates a ESMC_Field object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Field ESMC_FieldCreateGridTypeKind( + ESMC_Grid grid, // in + enum ESMC_TypeKind_Flag typekind, // in + enum ESMC_StaggerLoc staggerloc, // in + ESMC_InterArrayInt *gridToFieldMap, // in + ESMC_InterArrayInt *ungriddedLBound, // in + ESMC_InterArrayInt *ungriddedUBound, // in + const char *name, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_Field object. ++DESCRIPTION: +
+Creates a ESMC_Field object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Field ESMC_FieldCreateMeshArraySpec( + ESMC_Mesh mesh, // in + ESMC_ArraySpec arrayspec, // in + ESMC_InterArrayInt *gridToFieldMap, // in + ESMC_InterArrayInt *ungriddedLBound, // in + ESMC_InterArrayInt *ungriddedUBound, // in + const char *name, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_Field object. ++DESCRIPTION: +
+Creates a ESMC_Field object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Field ESMC_FieldCreateMeshTypeKind( + ESMC_Mesh mesh, // in + enum ESMC_TypeKind_Flag typekind, // in + enum ESMC_MeshLoc_Flag meshloc, // in + ESMC_InterArrayInt *gridToFieldMap, // in + ESMC_InterArrayInt *ungriddedLBound, // in + ESMC_InterArrayInt *ungriddedUBound, // in + const char *name, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_Field object. ++DESCRIPTION: +
+Creates a ESMC_Field object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Field ESMC_FieldCreateLocStreamArraySpec( + ESMC_LocStream locstream, // in + ESMC_ArraySpec arrayspec, // in + ESMC_InterArrayInt *gridToFieldMap, // in + ESMC_InterArrayInt *ungriddedLBound, // in + ESMC_InterArrayInt *ungriddedUBound, // in + const char *name, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_Field object. ++DESCRIPTION: +
+Creates a ESMC_Field object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Field ESMC_FieldCreateLocStreamTypeKind( + ESMC_LocStream locstream, // in + enum ESMC_TypeKind_Flag typekind, // in + ESMC_InterArrayInt *gridToFieldMap, // in + ESMC_InterArrayInt *ungriddedLBound, // in + ESMC_InterArrayInt *ungriddedUBound, // in + const char *name, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_Field object. ++DESCRIPTION: +
+Creates a ESMC_Field object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_FieldDestroy( + ESMC_Field *field // inout + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Releases all resources associated with this ESMC_Field. + Return code; equals ESMF_SUCCESS if there are no errors. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Array ESMC_FieldGetArray( + ESMC_Field field, // in + int *rc // out + ); +RETURN VALUE: +
The ESMC_Array object stored in the ESMC_Field. ++DESCRIPTION: +
+Get the internal Array stored in the ESMC_Field. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Mesh ESMC_FieldGetMesh( + ESMC_Field field, // in + int *rc // out + ); +RETURN VALUE: +
The ESMC_Mesh object stored in the ESMC_Field. ++DESCRIPTION: +
+Get the internal Mesh stored in the ESMC_Field. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void *ESMC_FieldGetPtr( + ESMC_Field field, // in + int localDe, // in + int *rc // out + ); +RETURN VALUE: +
The Fortran data pointer stored in the ESMC_Field. ++DESCRIPTION: +
+Get the internal Fortran data pointer stored in the ESMC_Field. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_FieldGetBounds( + ESMC_Field field, // in + int *localDe, + int *exclusiveLBound, + int *exclusiveUBound, + int rank + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Get the Field bounds from the ESMC_Field. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_FieldPrint( + ESMC_Field field // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Print the internal information within this ESMC_Field. + +
+The arguments are: +
+ +
+ +
+conservative interpolation + +
+ +
+
+INTERFACE:
+
int ESMC_FieldRegridGetArea( + ESMC_Field field // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+This subroutine gets the area of the cells used for conservative interpolation for the grid object + associated with areaField and puts them into areaField. If created on a 2D Grid, it must + be built on the ESMF_STAGGERLOC_CENTER stagger location. + If created on a 3D Grid, it must be built on the ESMF_STAGGERLOC_CENTER_VCENTER stagger + location. If created on a Mesh, it must be built on the ESMF_MESHLOC_ELEMENT mesh location. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_FieldRegridStore( + ESMC_Field srcField, // in + ESMC_Field dstField, // in + ESMC_InterArrayInt *srcMaskValues, // in + ESMC_InterArrayInt *dstMaskValues, // in + ESMC_RouteHandle *routehandle, // inout + enum ESMC_RegridMethod_Flag *regridmethod, // in + enum ESMC_PoleMethod_Flag *polemethod, // in + int *regridPoleNPnts, // in + enum ESMC_LineType_Flag *lineType, // in + enum ESMC_NormType_Flag *normType, // in + enum ESMC_ExtrapMethod_Flag *extrapMethod, // in + int *extrapNumSrcPnts, // in + float *extrapDistExponent, // in + int *extrapNumLevels, // in + enum ESMC_UnmappedAction_Flag *unmappedaction, // in + enum ESMC_Logical *ignoreDegenerate, // in + double **factorList, // inout + int **factorIndexList, // inout + int *numFactors, // inout + ESMC_Field *srcFracField, // inout + ESMC_Field *dstFracField); // inout +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Creates a sparse matrix operation (stored in routehandle) that contains + the calculations and communications necessary to interpolate from srcField + to dstField. The routehandle can then be used in the call ESMC_FieldRegrid() + to interpolate between the Fields. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_FieldRegridStoreFile( + ESMC_Field srcField, // in + ESMC_Field dstField, // in + const char *filename, // in + ESMC_InterArrayInt *srcMaskValues, // in + ESMC_InterArrayInt *dstMaskValues, // in + ESMC_RouteHandle *routehandle, // inout + enum ESMC_RegridMethod_Flag *regridmethod, // in + enum ESMC_PoleMethod_Flag *polemethod, // in + int *regridPoleNPnts, // in + enum ESMC_LineType_Flag *lineType, // in + enum ESMC_NormType_Flag *normType, // in + enum ESMC_UnmappedAction_Flag *unmappedaction, // in + enum ESMC_Logical *ignoreDegenerate, // in + enum ESMC_Logical *create_rh, // in + enum ESMC_FileMode_Flag *filemode, // in + const char *srcFile, // in + const char *dstFile, // in + enum ESMC_FileFormat_Flag *srcFileType, // in + enum ESMC_FileFormat_Flag *dstFileType, // in + enum ESMC_Logical *largeFileFlag, // in + ESMC_Field *srcFracField, // out + ESMC_Field *dstFracField); // out +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Creates a sparse matrix operation (stored in routehandle) that contains + the calculations and communications necessary to interpolate from srcField + to dstField. The routehandle can then be used in the call ESMC_FieldRegrid() + to interpolate between the Fields. The weights will be output to the file + with name filename. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_FieldRegrid( + ESMC_Field srcField, // in + ESMC_Field dstField, // inout + ESMC_RouteHandle routehandle, // in + enum ESMC_Region_Flag *zeroregion); // in +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Execute the precomputed regrid operation stored in routehandle to interpolate + from srcField to dstField. See ESMF_FieldRegridStore() on how to precompute + the routehandle. It is erroneous to specify the identical Field object for + srcField and dstField arguments. This call is collective across the + current VM. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_FieldRegridRelease(ESMC_RouteHandle *routehandle); // inout +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Free resources used by regrid object + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_FieldSMMStore( + ESMC_Field srcField, // in + ESMC_Field dstField, // in + const char *filename, // in + ESMC_RouteHandle *routehandle, // out + enum ESMC_Logical *ignoreUnmatchedIndices, // in + int *srcTermProcessing, // in + int *pipeLineDepth); // in +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Creates a sparse matrix operation (stored in routehandle) that contains + the calculations and communications necessary to interpolate from srcField + to dstField. The routehandle can then be used in the call ESMC_FieldRegrid() + to interpolate between the Fields. + +
+The arguments are: +
+ + +
+The Array class is an alternative to the Field class for representing +distributed, structured data. Unlike Fields, which are built to carry +grid coordinate information, Arrays can only carry information about the +indices associated with grid cells. Since they do not have coordinate +information, Arrays cannot be used to calculate interpolation weights. +However, if the user can supply interpolation weights, the Array sparse +matrix multiply operation can be used to apply the weights and transfer +data to the new grid. Arrays can also perform redistribution, scatter, +and gather communication operations. + +
+Like Fields, Arrays can be added to a State and used in inter-Component +data communications. + +
+From a technical standpoint, the ESMF Array class is an index space +based, distributed data storage class. It provides DE-local memory allocations +within DE-centric index regions and defines the relationship to the index +space described by the ESMF DistGrid. The Array class offers common +communication patterns within the index space formalism. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Array ESMC_ArrayCreate( + ESMC_ArraySpec arrayspec, // in + ESMC_DistGrid distgrid, // in + const char* name, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_Array object. ++DESCRIPTION: +
+Create an ESMC_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ArrayDestroy( + ESMC_Array *array // inout + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Destroy an ESMC_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
const char *ESMC_ArrayGetName( + ESMC_Array array, // in + int *rc // out + ); +RETURN VALUE: +
Pointer to the Array name string. ++DESCRIPTION: +
+Get the name of the specified ESMC_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void *ESMC_ArrayGetPtr( + ESMC_Array array, // in + int localDe, // in + int *rc // out + ); +RETURN VALUE: +
Pointer to the Array data. ++DESCRIPTION: +
+Get pointer to the data of the specified ESMC_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ArrayPrint( + ESMC_Array array // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Print internal information of the specified ESMC_Array object. + +
+The arguments are: +
+ + +
+An ArraySpec is a very simple class that contains type, kind, and +rank information about an Array. This information is stored in two +parameters. TypeKind describes the data type of the elements +in the Array and their precision. Rank is the number of dimensions +in the Array. + +
+The only methods that are associated with the ArraySpec class are those +that allow you to set and retrieve this information. + +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ArraySpecGet( + ESMC_ArraySpec arrayspec, // in + int *rank, // out + enum ESMC_TypeKind_Flag *typekind // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Returns information about the contents of an ESMC_ArraySpec. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ArraySpecSet( + ESMC_ArraySpec *arrayspec, // inout + int rank, // in + enum ESMC_TypeKind_Flag typekind // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Set an Array specification - typekind, and rank. + +
+The arguments are: +
+ + +
+The ESMF Grid class is used to describe the geometry and discretization +of logically rectangular physical grids. It also contains the +description of the grid's underlying topology and the decomposition +of the physical grid across the available computational resources. +The most frequent use of the Grid class is to describe physical grids +in user code so that sufficient information is available to perform ESMF +methods such as regridding. + +
+
+ +Key Features |
+
Representation of grids formed by logically rectangular regions, +including uniform and rectilinear grids (e.g. lat-lon grids), +curvilinear grids (e.g. displaced pole grids), and grids formed +by connected logically rectangular regions (e.g. cubed sphere grids). | +
Support for 1D, 2D, 3D, and higher dimension grids. | +
Distribution of grids across computational resources for parallel +operations - users set which grid dimensions are distributed. | +
Grids can be created already distributed, so that no single +resource needs global information during the creation process. | +
Options to define periodicity and other edge connectivities either +explicitly or implicitly via shape shortcuts. | +
Options for users to define grid coordinates themselves or call +prefabricated coordinate generation routines for standard grids +[NO GENERATION ROUTINES YET]. | +
Options for incremental construction of grids. | +
Options for using a set of pre-defined stagger locations or for setting +custom stagger locations. | +
+ +
+ESMF Grids are based on the concepts described in A Standard +Description of Grids Used in Earth System Models [Balaji 2006]. In this document +Balaji introduces the mosaic concept as a means of describing +a wide variety of Earth system model grids. A mosaic is +composed of grid tiles connected at their edges. Mosaic grids +includes simple, single tile grids as a special case. + +
+The ESMF Grid class is a representation of a mosaic grid. Each ESMF +Grid is constructed of one or more logically rectangular Tiles. +A Tile will usually have some physical significance (e.g. the region +of the world covered by one face of a cubed sphere grid). + +
+The piece of a Tile that resides on one DE (for simple cases, a DE +can be thought of as a processor - see section on the DELayout) +is called a LocalTile. For example, the six faces of a cubed +sphere grid are each Tiles, and each Tile can be divided into many +LocalTiles. + +
+Every ESMF Grid contains a DistGrid object, which defines the Grid's +index space, topology, distribution, and connectivities. It enables +the user to define the complex edge relationships of tripole and other +grids. The DistGrid can be created explicitly and passed into a Grid +creation routine, or it can be created implicitly if the user takes +a Grid creation shortcut. The DistGrid used +in Grid creation describes the properties of the Grid cells. In addition +to this one, the Grid internally creates DistGrids for each stagger location. +These stagger DistGrids are related to the original DistGrid, but may +contain extra padding to represent the extent of the index space of +the stagger. These DistGrids are what are used when a Field is created +on a Grid. + +
+ +
+The range of supported grids in ESMF can be defined by: + +
+ +
+The first set of these are a group of overloaded +calls broken up by the number of periodic dimensions they specify. With these the user can pick +the method which creates a Grid with the number of periodic dimensions they need, and then specify other connectivity +options via arguments to the method. The following is a description of these methods: + +
+ +
+
+
+
+
+
+
+More detailed information can be found in the API description of each. + +
+ +
+
+
+
+The second set of shortcut methods is a set of methods overloaded under the name ESMF_GridCreate(). These methods +allow the user to specify the connectivites at the end of each dimension, by using the ESMF_GridConn_Flag flag. The table below shows the ESMF_GridConn_Flag settings used to create +standard shapes in 2D using the ESMF_GridCreate() call. Two values +are specified for each dimension, one for the low end and one for +the high end of the dimension's index values. + +
+ +
+
+
2D Shape | +connflagDim1(1) | +connflagDim1(2) | +connflagDim2(1) | +connflagDim2(2) | +
Rectangle | +NONE | +NONE | +NONE | +NONE | +
Bipole Sphere | +POLE | +POLE | +PERIODIC | +PERIODIC | +
Tripole Sphere | +POLE | +BIPOLE | +PERIODIC | +PERIODIC | +
Cylinder | +NONE | +NONE | +PERIODIC | +PERIODIC | +
Torus | +PERIODIC | +PERIODIC | +PERIODIC | +PERIODIC | +
+
+
+
+If the user's grid shape is too complex for an ESMF shortcut routine, +or involves more than three dimensions, a DistGrid can be created +to specify the shape in detail. This DistGrid is then passed +into a Grid create call. + +
+ +
+ESMF Grids have several options for data distribution (also referred to +as decomposition). As ESMF Grids are cell based, these +options are all specified in terms of how the cells in the Grid +are broken up between DEs. + +
+The main distribution options are regular, irregular, and arbitrary. +A regular distribution is one in which the same number of +contiguous grid cells are assigned to each DE in the +distributed dimension. An irregular distribution is one in which +unequal numbers of contiguous grid cells are assigned to each +DE in the distributed dimension. An arbitrary distribution is +one in which any grid cell can be assigned to any DE. Any of these +distribution options can be applied to any of the grid shapes (i.e., +rectangle) or types (i.e., rectilinear). Support for arbitrary distribution +is limited in the current version of ESMF. + +
+Figure 7 illustrates options for distribution. + +
+ |
+A distribution can also be specified using the DistGrid, by passing +object into a Grid create call. + +
+ +
+ +
+ |
+Each of these coordinate types can be set for each of the standard grid shapes +described in section 19.1.3. + +
+The table below shows how examples of common single Tile grids fall +into this shape and coordinate taxonomy. Note that any +of the grids in the table can have a regular or arbitrary distribution. + +
+ +
+
+
+ | Uniform | +Rectilinear | +Curvilinear | +
Sphere | +Global uniform lat-lon grid | +Gaussian grid | +Displaced pole grid | +
Rectangle | +Regional uniform lat-lon grid | +Gaussian grid section | +Polar stereographic grid section | +
+ +
+There are two ways of specifying coordinates in ESMF. The +first way is for the user to set the coordinates. The second +way is to take a shortcut and have the framework generate +the coordinates. + +
+No ESMF generation routines are currently available. + +
+ +
+Staggering is a finite difference technique in which the values +of different physical quantities are placed at different locations +within a grid cell. + +
+The ESMF Grid class supports a variety of stagger locations, including +cell centers, corners, and edge centers. The default stagger location in +ESMF is the cell center, and cell counts in Grid are based on this assumption. +Combinations of the 2D ESMF stagger locations are sufficient to specify any of the +Arakawa staggers. ESMF also supports staggering in 3D and higher dimensions. +There are shortcuts for standard staggers, and interfaces through which users +can create custom staggers. + +
+As a default the ESMF Grid class provides symmetric staggering, so +that cell centers are enclosed by cell perimeter (e.g. corner) +stagger locations. This means the coordinate arrays for stagger +locations other than the center will have an additional element of +padding in order to enclose the cell center locations. +However, to achieve other types of staggering, the user may alter +or eliminate this padding by using the appropriate options when adding +coordinates to a Grid. + +
+ +
+Masking is the process whereby parts of a grid can be marked to be +ignored during an operation, such as regridding. Masking can be +used on a source grid to indicate that certain portions of the grid +should not be used to generate regridded data. This is useful, for +example, if a portion of the source grid contains unusable values. +Masking can also be used on a destination grid to indicate that the +portion of the field built on that part of the Grid should not +receive regridded data. This is useful, for example, when part of +the grid isn't being used (e.g. the land portion of an ocean grid). + +
+ESMF regrid currently supports masking for Fields built on +structured Grids and element masking for Fields built on +unstructured Meshes. The user may mask out points in the source +Field or destination Field or both. To do masking the user sets +mask information in the Grid +or Mesh +upon which the Fields passed into the +ESMC_FieldRegridStore() call are built. The srcMaskValues +and dstMaskValues arguments to that +call can then be used to specify which values in that mask +information indicate that a location should be masked out. For +example, if dstMaskValues is set to (/1,2/), then any location that +has a value of 1 or 2 in the mask information of the Grid or Mesh +upon which the destination Field is built will be masked out. + +
+Masking behavior differs slightly between regridding methods. For +non-conservative regridding methods (e.g. bilinear or high-order +patch), masking is done on points. For these methods, masking a +destination point means that that point won't participate in +regridding (e.g. won't be interpolated to). For these methods, +masking a source point means that the entire source cell using +that point is masked out. In other words, if any corner point +making up a source cell is masked then the cell is masked. For +conservative regridding methods (e.g. first-order conservative) +masking is done on cells. Masking a destination cell means that +the cell won't participate in regridding (e.g. won't be +interpolated to). Similarly, masking a source cell means that the +cell won't participate in regridding (e.g. won't be interpolated +from). For any type of interpolation method (conservative or +non-conservative) the masking is set on the location upon +which the Fields passed into the regridding call are built. +For example, if Fields built on ESMC_STAGGERLOC_CENTER are +passed into the ESMC_FieldRegridStore() call then the masking +should also be set on ESMC_STAGGERLOC_CENTER. + +
+ +
+DESCRIPTION:
+
+ A set of values which indicates in which system the coordinates in the Grid are. This value is useful both to indicate to
+other users the type of the coordinates, but also to control how the coordinates are interpreted in regridding methods
+(e.g. ESMC_FieldRegridStore()).
+
+
+The type of this flag is: + +
+type(ESMC_CoordSys_Flag) + +
+The valid values are: +
+
+
+
+ +
+DESCRIPTION:
+
+The ESMC Grid can contain other kinds of data besides coordinates.
+This data is referred to as Grid “items”. Some items may be used
+by ESMC for calculations involving the Grid. The following
+are the valid values of ESMC_GridItem_Flag.
+
+
+The type of this flag is: + +
+type(ESMC_GridItem_Flag) + +
+The valid values are:
+
+
Item Label | +Type Restriction | +Type Default | +ESMC Uses | +Controls | +
ESMC_GRIDITEM_MASK | +ESMC_TYPEKIND_I4 | +ESMC_TYPEKIND_I4 | +YES | +Masking in Regrid | +
ESMC_GRIDITEM_AREA | +NONE | +ESMC_TYPEKIND_R8 | +YES | +Conservation in Regrid | +
+ +
+DESCRIPTION:
+
+The ESMC Grid class can exist in two states. These states are
+present so that the library code can detect if a Grid has been
+appropriately setup for the task at hand. The following
+are the valid values of ESMC_GRIDSTATUS.
+
+
+The type of this flag is: + +
+type(ESMC_GridStatus_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+This type describes the type of connection that occurs at the pole when a Grid is
+created with ESMC_GridCreate1PeriodicDim().
+
+
+The type of this flag is: + +
+type(ESMC_PoleKind_Flag) + +
+The valid values are: +
+
+
+ +
+DESCRIPTION:
+
+ In the ESMC Grid class, data can be located at different positions in a
+ Grid cell. When setting or retrieving coordinate data the stagger location is
+ specified to tell the Grid method from where in the cell to get the data.
+ Although the user may define their own custom stagger locations,
+ ESMC provides a set of predefined locations for ease of use. The
+following are the valid predefined stagger locations.
+
+
+ +
+
+
+
+
+The 2D predefined stagger locations (illustrated in figure 9) are:
+
+ +
+
+
+
+
+The 3D predefined stagger locations (illustrated in figure 10) are:
+
+ +
+DESCRIPTION:
+
+This option is used by ESMC_GridCreateFromFile to specify the type of the input grid file.
+
+
+The type of this flag is: + +
+type(ESMC_FileFormat_Flag) + +
+The valid values are: +
+
+ +
+
+
+
+
+ +
+The ESMF_Grid class depends upon the ESMF_DistGrid class +for the specification of its topology. That is, when +creating a Grid, first an ESMF_DistGrid is created to describe the +appropriate index space topology. This decision was +made because it seemed redundant to have a system for doing this +in both classes. It also seems most appropriate for +the machinary for topology creation to be located at the lowest +level possible so that it can be used by other +classes (e.g. the ESMF_Array class). Because of this, however, +the authors recommend that as a natural part of the +implementation of subroutines to generate standard grid shapes +(e.g. ESMF_GridGenSphere) a set of standard +topology generation subroutines be implemented (e.g. ESMF_DistGridGenSphere) for users who want to create a standard topology, but a custom geometry. + +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Grid ESMC_GridCreateNoPeriDim( + ESMC_InterArrayInt *maxIndex, // in + enum ESMC_CoordSys_Flag *coordSys, // in + enum ESMC_TypeKind_Flag *coordTypeKind, // in + enum ESMC_IndexFlag *indexflag, // in + int *rc // out + ); +RETURN VALUE: +
type(ESMC_Grid) ++DESCRIPTION: +
+This call creates an ESMC_Grid with no periodic dimensions. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Grid ESMC_GridCreate1PeriDim( + ESMC_InterArrayInt *maxIndex, // in + ESMC_InterArrayInt *polekindflag, // in + int *periodicDim, // in + int *poleDim, // in + enum ESMC_CoordSys_Flag *coordSys, // in + enum ESMC_TypeKind_Flag *coordTypeKind, // in + enum ESMC_IndexFlag *indexflag, // in + int *rc // out + ); +RETURN VALUE: +
type(ESMC_Grid) ++DESCRIPTION: +
+This call creates an ESMC_Grid with 1 periodic dimension. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Grid ESMC_GridCreateCubedSphere( + int *tilesize, // in + ESMC_InterArrayInt *regDecompPTile, // in + //ESMC_InterArrayInt *decompFlagPTile, // in + //ESMC_InterArrayInt *deLabelList, // in + //ESMC_DELayout *delayout, // in + ESMC_InterArrayInt *staggerLocList, // in + const char *name, // in + int *rc); // out +RETURN VALUE: +
type(ESMC_Grid) ++DESCRIPTION: +
+Create a six-tile ESMC_Grid for a cubed sphere grid using regular + decomposition. Each tile can have different decomposition. The grid + coordinates are generated based on the algorithm used by GEOS-5. The tile + resolution is defined by tileSize. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Grid ESMC_GridCreateFromFile(const char *filename, int fileTypeFlag, + int *regDecomp, int *decompflag, + int *isSphere, ESMC_InterArrayInt *polekindflag, + int *addCornerStagger, + int *addUserArea, enum ESMC_IndexFlag *indexflag, + int *addMask, const char *varname, + const char **coordNames, int *rc); +RETURN VALUE: +
type(ESMC_Grid) ++DESCRIPTION: +
+This function creates a ESMC_Grid object from the specification in + a NetCDF file. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridDestroy( + ESMC_Grid *grid // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Destroy the Grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridAddItem( + ESMC_Grid grid, // in + enum ESMC_GridItem_Flag itemflag, // in + enum ESMC_StaggerLoc staggerloc // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Add an item (e.g. a mask) to the Grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void * ESMC_GridGetItem( + ESMC_Grid grid, // in + enum ESMC_GridItem_Flag itemflag, // in + enum ESMC_StaggerLoc staggerloc, // in + int *localDE, // in + int *rc // out + ); +RETURN VALUE: +
A pointer to the item data. ++DESCRIPTION: +
+Get a pointer to item data (e.g. mask data) in the Grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridAddCoord( + ESMC_Grid grid, // in + enum ESMC_StaggerLoc staggerloc // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Add coordinates to the Grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void * ESMC_GridGetCoord( + ESMC_Grid grid, // in + int coordDim, // in + enum ESMC_StaggerLoc staggerloc, // in + int *localDE, + int *exclusiveLBound, // out + int *exclusiveUBound, // out + int *rc // out + ); +RETURN VALUE: +
A pointer to coordinate data in the Grid. ++DESCRIPTION: +
+Get a pointer to coordinate data in the Grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_GridGetCoordBounds( + ESMC_Grid grid, // in + enum ESMC_StaggerLoc staggerloc, // in + int *localDE, // in + int *exclusiveLBound, // out + int *exclusiveUBound, // out + int *rc // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Get coordinates bounds from the Grid. + +
+The arguments are: +
+ + +
+Unstructured grids are commonly used in the computational solution of Partial Differential equations. These are especially useful for problems that involve complex geometry, where using the less flexible structured grids can +result in grid representation of regions where no computation is needed. Finite +element and finite volume methods map naturally to unstructured grids and are used commonly +in hydrology, ocean modeling, and many other applications. + +
+In order to provide support for application codes using unstructured grids, the ESMF library provides a class for representing +unstructured grids called the Mesh. Fields can be created on a Mesh to hold data. In Fortran, Fields created on a Mesh can also be used +as either the source or destination or both of an interpolation (i.e. an ESMF_FieldRegridStore() call). This capability is currently +not supported with the C interface, however, if the C Field is passed via a State to a component written in Fortran then the regridding +can be performed there. The rest of this section describes the Mesh class and how to create and use them in ESMF. + +
+ +
+A Mesh in ESMF is described in terms of nodes and elements. A node is a point in space which represents where the coordinate +information in a Mesh is located. An element is a higher dimensional shape constructed of nodes. Elements give a Mesh its shape and define the relationship of the nodes to one another. Field data may be located on a Mesh's nodes. + +
+ +
+The range of Meshes supported by ESMF are defined by several factors: dimension, element types, and distribution. + +
+ESMF currently only supports Meshes whose number of coordinate dimensions (spatial dimension) is 2 or 3. The dimension of the elements in a Mesh +(parametric dimension) must be less than or equal to the spatial dimension, but also must be either 2 or 3. This means that an ESMF mesh may be +either 2D elements in 2D space, 3D elements in 3D space, or a manifold constructed of 2D elements embedded in 3D space. + +
+ESMF currently supports two types of elements for each Mesh parametric dimension. For a parametric dimension of 2 the +supported element types are triangles or quadrilaterals. For a parametric dimension of 3 the supported element types are tetrahedrons +and hexahedrons. See Section 20.2.1 for diagrams of these. The Mesh supports any combination of element types within a particular +dimension, but types from different dimensions may not be mixed, for example, a Mesh cannot be constructed of both quadrilaterals and tetrahedra. + +
+ESMF currently only supports distributions where every node on a PET must be a part of an element on that PET. In other words, there +must not be nodes without an element on a PET. + +
+ +
+DESCRIPTION:
+
+ An ESMF Mesh can be constructed from a combination of different elements. The type of elements that can
+be used in a Mesh depends on the Mesh's parametric dimension, which is set during Mesh creation. The
+following are the valid Mesh element types for each valid Mesh parametric dimension (2D or 3D) .
+
+
+ +
+
+
+
+
+ 3 4 ---------- 3 + / \ | | + / \ | | + / \ | | + / \ | | + / \ | | + 1 --------- 2 1 ---------- 2 + + ESMC_MESHELEMTYPE_TRI ESMC_MESHELEMTYPE_QUAD + +2D element types (numbers are the order for elementConn during + Mesh create) ++ +
+For a Mesh with parametric dimension of 2 the valid element types (illustrated above) are: + +
+ +
+ ++
Element Type | +Number of Nodes | +Description | +
ESMC_MESHELEMTYPE_TRI | +3 | +A triangle | +
ESMC_MESHELEMTYPE_QUAD | +4 | +A quadrilateral (e.g. a rectangle) | +
+ +
+
+
+
+
+
+
+
+ + 3 8---------------7 + /|\ /| /| + / | \ / | / | + / | \ / | / | + / | \ / | / | + / | \ 5---------------6 | + 4-----|-----2 | | | | + \ | / | 4----------|----3 + \ | / | / | / + \ | / | / | / + \ | / | / | / + \|/ |/ |/ + 1 1---------------2 + + ESMC_MESHELEMTYPE_TETRA ESMC_MESHELEMTYPE_HEX + +3D element types (numbers are the order for elementConn during + Mesh create) ++ +
+For a Mesh with parametric dimension of 3 the valid element types (illustrated above) are: + +
+ +
+ ++
Element Type | +Number of Nodes | +Description | +
ESMC_MESHELEMTYPE_TETRA | +4 | +A tetrahedron (CAN'T BE USED IN REGRID) | +
ESMC_MESHELEMTYPE_HEX | +8 | +A hexahedron (e.g. a cube) | +
+ +
+DESCRIPTION:
+
+This option is used by ESMF_MeshCreate to specify the type of the input grid file.
+
+
+The type of this flag is: + +
+type(ESMF_FileFormat_Flag) + +
+The valid values are: +
+
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
void ESMC_MeshGetMOAB( + bool *moabOn, + int *rc + ); +RETURN VALUE: +
None ++DESCRIPTION: +
+This call will query whether or not the MOAB mesh backend is enabled. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void ESMC_MeshSetMOAB( + bool moabOn, + int *rc + ); +RETURN VALUE: +
None ++DESCRIPTION: +
+This call will toggle the MOAB mesh backend. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_MeshAddElements( + ESMC_Mesh mesh, // inout + int elementCount, // in + int *elementIds, // in + int *elementTypes, // in + int *elementConn, // in + int *elementMask, // in + double *elementArea, // in + double *elementCoords // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+This call is the third and last part of the three part mesh create + sequence and should be called after the mesh is created with ESMF_MeshCreate() + (20.3.5) + and after the nodes are added with ESMF_MeshAddNodes() (20.3.4). + This call adds the elements to the + mesh and finalizes the create. After this call the Mesh is usable, for + example a Field may be built on the created Mesh object and + this Field may be used in a ESMF_FieldRegridStore() call. + +
+The parameters to this call elementIds, elementTypes, and + elementConn describe the elements to be created. The description + for a particular element lies at the same index location in elementIds + and elementTypes. Each entry in elementConn consists of the list of + nodes used to create that element, so the connections for element in the + elementIds array will start at + in elementConn. + +
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_MeshAddNodes( + ESMC_Mesh mesh, // inout + int nodeCount, // in + int *nodeIds, // in + double *nodeCoords, // in + int *nodeOwners, // in + int *nodeMask // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+This call is the second part of the three part mesh create + sequence and should be called after the mesh's dimensions are set + using ESMC_MeshCreate(). + This call adds the nodes to the + mesh. The next step is to call ESMC_MeshAddElements() (20.3.5). + +
+The parameters to this call nodeIds, nodeCoords, and + nodeOwners describe the nodes to be created on this PET. + The description for a particular node lies at the same index location in + nodeIds and nodeOwners. Each entry + in nodeCoords consists of spatial dimension coordinates, so the coordinates + for node in the nodeIds array will start at +. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Mesh ESMC_MeshCreate( + int parametricDim, // in + int spatialDim, // in + enum ESMC_CoordSys_Flag *coordSys, // in + int *rc // out + ); +RETURN VALUE: +
type(ESMC_Mesh) :: ESMC_MeshCreate ++DESCRIPTION: +
+This call is the first part of the three part mesh create sequence. This call sets the dimension of the elements + in the mesh (parametricDim) and the number of coordinate dimensions in the mesh (spatialDim). + The next step is to call ESMC_MeshAddNodes() (20.3.4) to add the nodes and then + ESMC_MeshAddElements() (20.3.3) + to add the elements and finalize the mesh. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Mesh ESMC_MeshCreateFromFile( + const char *filename, // in (required) + int fileTypeFlag, // in (required) + int *convertToDual, // in (optional) + int *addUserArea, // in (optional) + const char *meshname, // in (optional) + int *maskFlag, // in (optional) + const char *varname, // in (optional) + int *rc // out + ); +RETURN VALUE: +
type(ESMC_Mesh) :: ESMC_MeshCreateFromFile ++DESCRIPTION: +
+Method to create a Mesh object from a NetCDF file in either SCRIP, UGRID, + or ESMF file formats. + +
+The required arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void ESMC_MeshGetCoord( + ESMC_Mesh mesh_in, // in (required) + double *nodeCoord, // out + int *num_nodes, // out + int *num_dims, // out + int *rc // out + ); +RETURN VALUE: +
None ++DESCRIPTION: +
+This call returns the node coordinates of the given ESMC_Mesh + in the provided nodeCoord buffer of doubles. At completion, this + buffer is a 1-D array with the coordinates for a given node + in adjacent indices. For example, for -dimensional coordinates, the first + values in the returned array are the coordinates for the first node, + the second values are the coordinates for the second node, etc. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void ESMC_MeshGetElemCoord( + ESMC_Mesh mesh_in, // in (required) + double *elemCoord, // out + int *num_elems, // out + int *num_dims, // out + int *rc // out + ); +RETURN VALUE: +
None ++DESCRIPTION: +
+This call returns the element coordinates of the given ESMC_Mesh + in the provided elemCoord buffer of doubles. At completion, this + buffer is a 1-D array with the coordinates for a given element + in adjacent indices. For example, for -dimensional coordinates, the first + values in the returned array are the coordinates for the first element, + the second values are the coordinates for the second element, etc. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void ESMC_MeshGetConnectivity( + ESMC_Mesh mesh_in, // in (required) + double *connCoord, // out + int *nodesPerElem, // out + int *rc // out + ); +RETURN VALUE: +
None ++DESCRIPTION: +
+NOTE: At this time the connectivity that is returned from this call is + not necessarily in the same format as how it was passed into the + creation routine. + +
+This call returns the connectivity of the given ESMC_Mesh + in the provided connCoord buffer of doubles. At completion, this + buffer is a 1-D array with the coordinates for the nodes of a given element + in counterclockwise order. The /tt nodesPerElem buffer of integers + contains the number of nodes to expect per element. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_MeshDestroy( + ESMC_Mesh *mesh // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Destroy the Mesh. This call removes all internal memory associated with mesh. After this call mesh will no longer be usable. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_MeshFreeMemory( + ESMC_Mesh mesh // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+This call removes the portions of mesh which contain connection and coordinate + information. After this call, Fields build on mesh will no longer be usable + as part of an ESMF_FieldRegridStore() operation. However, after this call + Fields built on mesh can still be used in an ESMF_FieldRegrid() + operation if the routehandle was generated beforehand. New Fields may also + be built on mesh after this call. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_MeshGetElementCount( + ESMC_Mesh mesh, // in + int *elementCount // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Query the number of elements in a mesh on the local PET. + The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_MeshGetNodeCount( + ESMC_Mesh mesh, // in + int *nodeCount // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Query the number of nodes in a mesh on the local PET. + The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_MeshGetOwnedElementCount( + ESMC_Mesh mesh, // in + int *elementCount // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Query the number of elements in a mesh owned by the local PET. This number will be equal or less than the + local element count. + The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_MeshGetOwnedNodeCount( + ESMC_Mesh mesh, // in + int *nodeCount // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Query the number of nodes in a mesh owned by the local PET. This number will be equal or less than the + local node count. + The arguments are: +
+ + +
+An exchange grid represents the 2D boundary layer usually between the +atmosphere on one side and ocean and land on the other in an Earth +system model. There are dynamical and thermodynamical processes on +either side of the boundary layer and on the boundary layer itself. +The boundary layer exchanges fluxes from either side and adjusts +boundary conditions for the model components involved. For climate modeling, +it is critical that the fluxes transferred by the boundary layer are +conservative. + +
+The ESMF exchange grid is implemented as the ESMC_XGrid class. +Internally it's represented by a collection of the intersected cells +between atmosphere and ocean/land[2] grids. +These polygonal cells can have irregular shapes +and can be broken down into triangles facilitating a finite element +approach. + +
+Through the C API there is one way to create an ESMC_XGrid object from +user supplied information. The ESMC_XGrid takes +two lists of ESMC_Grid or ESMC_Mesh that represent the model component grids on +either side of the exchange grid. From the two lists of ESMC_Grid or ESMC_Mesh, +information required for flux exchange calculation between any pair of the +model components from either side of the exchange grid is computed. In addition, the +internal representation of the ESMC_XGrid is computed and can be optionally stored +as an ESMC_Mesh. This internal representation is the collection of the intersected +polygonal cells as a result of merged ESMC_Meshes from both sides of the exchange grid. +ESMC_Field can be created on the ESMC_XGrid and used for weight generation +and regridding as the internal representation in the ESMC_XGrid has +a complete geometrical description of the exchange grid. + +
+Once an ESMC_XGrid has been created, information describing it (e.g. cell areas, mesh representation, etc.) +can be retrieved from the object using a set of get calls (e.g. ESMC_XGridGetElementArea()). The full extent of these +can be found in the API section below. + +
+ +
+
+ +
+ +
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_XGrid ESMC_XGridCreate( + int sideAGridCount, ESMC_Grid *sideAGrid, // in + int sideAMeshCount, ESMC_Mesh *sideAMesh, // in + int sideBGridCount, ESMC_Grid *sideBGrid, // in + int sideBMeshCount, ESMC_Mesh *sideBMesh, // in + ESMC_InterArrayInt *sideAGridPriority, // in + ESMC_InterArrayInt *sideAMeshPriority, // in + ESMC_InterArrayInt *sideBGridPriority, // in + ESMC_InterArrayInt *sideBMeshPriority, // in + ESMC_InterArrayInt *sideAMaskValues, // in + ESMC_InterArrayInt *sideBMaskValues, // in + int storeOverlay, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_XGrid object. ++DESCRIPTION: +
+Create an ESMC_XGrid object from user supplied input: the list of Grids or Meshes on side A and side B, + and other optional arguments. A user can supply both Grids and Meshes on one side to create + the XGrid. By default, the Grids have a higher priority over Meshes but the order of priority + can be adjusted by the optional GridPriority and MeshPriority arguments. The priority order + of Grids and Meshes can also be interleaved by rearranging the optional + GridPriority and MeshPriority arguments accordingly. + +
+Sparse matrix multiplication coefficients are internally computed and + uniquely determined by the Grids or Meshes provided in sideA and sideB. User can supply + a single ESMC_Grid or an array of ESMC_Grid on either side of the + ESMC_XGrid. For an array of ESMC_Grid or ESMC_Mesh in sideA or sideB, + a merging process concatenates all the ESMC_Grids and ESMC_Meshes + into a super mesh represented + by ESMC_Mesh. The super mesh is then used to compute the XGrid. + Grid or Mesh objects in sideA and sideB arguments must have coordinates defined for + the corners of a Grid or Mesh cell. XGrid creation can be potentially memory expensive given the + size of the input Grid and Mesh objects. By default, the super mesh is not stored + to reduce memory usage. + +
+If sideA and sideB have a single + Grid or Mesh object, it's erroneous + if the two Grids or Meshes are spatially disjoint. + It is also erroneous to specify a Grid or Mesh object in sideA or sideB + that is spatially disjoint from the ESMC_XGrid. + +
+This call is collective across the current VM. For more details please refer to the description + 21.1 of the XGrid class. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_XGridDestroy( + ESMC_XGrid *xgrid // inout + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Releases all resources associated with this ESMC_XGrid. + Return code; equals ESMF_SUCCESS if there are no errors. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_XGridGetSideAGridCount( + ESMC_XGrid xgrid, // in + int *rc // out + ); +RETURN VALUE: +
The number of Grids on side A. ++DESCRIPTION: +
+Get the number of Grids on side A. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_XGridGetSideAMeshCount( + ESMC_XGrid xgrid, // in + int *rc // out + ); +RETURN VALUE: +
The number of Meshes on side A. ++DESCRIPTION: +
+Get the number of Meshes on side A. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_XGridGetSideBGridCount( + ESMC_XGrid xgrid, // in + int *rc // out + ); +RETURN VALUE: +
The number of Grids on side B. ++DESCRIPTION: +
+Get the number of Grids on side B. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_XGridGetSideBMeshCount( + ESMC_XGrid xgrid, // in + int *rc // out + ); +RETURN VALUE: +
The number of Meshes on side B. ++DESCRIPTION: +
+Get the number of Meshes on side B. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_XGridGetDimCount( + ESMC_XGrid xgrid, // in + int *rc // out + ); +RETURN VALUE: +
The dimension of the XGrid. ++DESCRIPTION: +
+Get the dimension of the XGrid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_XGridGetElementCount( + ESMC_XGrid xgrid, // in + int *rc // out + ); +RETURN VALUE: +
The number of elements in the XGrid. ++DESCRIPTION: +
+Get the number of elements in the XGrid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Mesh ESMC_XGridGetMesh( + ESMC_XGrid xgrid, // in + int *rc // out + ); +RETURN VALUE: +
The ESMC_Mesh object representing the XGrid. ++DESCRIPTION: +
+Get the ESMC_Mesh object representing the XGrid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void ESMC_XGridGetElementArea( + ESMC_XGrid xgrid, // in + ESMC_R8 *area, // out + int *rc // out + ); +RETURN VALUE: +
The number of elements in the XGrid. ++DESCRIPTION: +
+Get the number of elements in the XGrid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void ESMC_XGridGetElementCentroid( + ESMC_XGrid xgrid, // in + ESMC_R8 *centroid, // out + int *rc // out + ); +RETURN VALUE: +
The number of elements in the XGrid. ++DESCRIPTION: +
+Get the centroid for each element in the exchange grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void ESMC_XGridGetSparseMatA2X( + ESMC_XGrid xgrid, // in + int sideAIndex, // in + int *factorListCount, // out + double **factorList, // out + int **factorIndexList, // out + int *rc); +RETURN VALUE: +
N/A ++DESCRIPTION: +
+Get the sparse matrix that goes from a side A grid to the exchange grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void ESMC_XGridGetSparseMatX2A( + ESMC_XGrid xgrid, // in + int sideAIndex, // in + int *factorListCount, // out + double **factorList, // out + int **factorIndexList, // out + int *rc); +RETURN VALUE: +
N/A ++DESCRIPTION: +
+Get the sparse matrix that goes from the exchange grid to a side A grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void ESMC_XGridGetSparseMatB2X( + ESMC_XGrid xgrid, // in + int sideBIndex, // in + int *factorListCount, // out + double **factorList, // out + int **factorIndexList, // out + int *rc); +RETURN VALUE: +
N/A ++DESCRIPTION: +
+Get the sparse matrix that goes from a side B grid to the exchange grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
void ESMC_XGridGetSparseMatX2B( + ESMC_XGrid xgrid, // in + int sideBIndex, // in + int *factorListCount, // out + double **factorList, // out + int **factorIndexList, // out + int *rc); +RETURN VALUE: +
N/A ++DESCRIPTION: +
+Get the sparse matrix that goes from the exchange grid to a side B grid. + +
+The arguments are: +
+ + +
+The ESMF DistGrid class sits on top of the DELayout class (not currently +directly accessible through the ESMF C API) and holds domain +information in index space. +A DistGrid object captures the index space topology +and describes its decomposition in terms of DEs. Combined with DELayout and VM +the DistGrid defines the data distribution of a domain decomposition across the +computational resources of an ESMF Component. + +
+The global domain is defined as the union of logically +rectangular (LR) sub-domains or tiles. The DistGrid create methods allow +the specification of such a multi-tile global domain and its decomposition into +exclusive, DE-local LR regions according to various degrees of user specified +constraints. Complex index space topologies can be constructed by specifying +connection relationships between tiles during creation. + +
+The DistGrid class holds domain information for all DEs. Each DE is associated +with a local LR region. No overlap of the regions is allowed. The DistGrid +offers query methods that allow DE-local topology information to be extracted, +e.g. for the construction of halos by higher classes. + +
+A DistGrid object only contains decomposable dimensions. The minimum rank for a +DistGrid object is 1. A maximum rank does not exist for DistGrid objects, +however, ranks greater than 7 may lead to difficulties with respect to the +Fortran API of higher classes based on DistGrid. The rank of a DELayout object +contained within a DistGrid object must be equal to the DistGrid rank. Higher +class objects that use the DistGrid, such as an Array object, may be of +different rank than the associated DistGrid object. The higher class object +will hold the mapping information between its dimensions and the DistGrid +dimensions. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_DistGrid ESMC_DistGridCreate( + ESMC_InterArrayInt minIndexInterfaceArg, // in + ESMC_InterArrayInt maxIndexInterfaceArg, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_DistGrid object. ++DESCRIPTION: +
+Create an ESMC_DistGrid from a single logically rectangular (LR) + tile with default decomposition. The default decomposition is + deCount +, where deCount is the + number of DEs in a default DELayout, equal to petCount. This means + that the default decomposition will be into as many DEs as there are PETs, + with 1 DE per PET. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_DistGridDestroy( + ESMC_DistGrid *distgrid // inout + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Destroy an ESMC_DistGrid object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_DistGridPrint( + ESMC_DistGrid distgrid // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Print internal information of the specified ESMC_DistGrid object. + +
+The arguments are: +
+ + +
+The ESMF RouteHandle class provides a unified interface for all route-based communication methods across the Field, FieldBundle, Array, and ArrayBundle classes. All route-based communication methods implement a pre-computation step, returning a RouteHandle, an execution step, and a release step. Typically the pre-computation, or Store() step will be a lot more expensive (both in memory and time) than the execution step. The idea is that once precomputed, a RouteHandle will be executed many times over during a model run, making the execution time a very performance critical piece of code. In ESMF, Regridding, Redisting, and Haloing are implemented as route-based communication methods. The following sections discuss the RouteHandle concepts that apply uniformly to all route-based communication methods, across all of the above mentioned classes. + +
+ +
+The user interacts with the RouteHandle class through the route-based communication methods of Field, FieldBundle, Array, and ArrayBundle. The usage of these methods are described in detail under their respective class documentation section. The following examples focus on the RouteHandle aspects common across classes and methods. + +
+ +
+
+ +
+
+
+
+
+
+Internally all route-based communication calls are implemented as sparse matrix multiplications. The precompute step for all of the supported communication methods can be broken up into three steps: + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_RouteHandle ESMC_RouteHandleCreateFromFile( + char *filename, + int *rc + ); +RETURN VALUE: +
ESMC_RouteHandle ++DESCRIPTION: +
+Create an ESMC_RouteHandle object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_RouteHandlePrint( + ESMC_RouteHandle rh // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Print internal information of the specified ESMC_RouteHandle object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_RouteHandleWrite( + ESMC_RouteHandle rh, // in + char *filename // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Write ESMC_RouteHandle object to file to save regrid information for + fast input for regridding operations during runtime. + +
+The arguments are: +
+ + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMC_crefdoc/node6.html b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/node6.html new file mode 100644 index 000000000..2e03a73f7 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/node6.html @@ -0,0 +1,2746 @@ + + + + + ++ +
+The ESMF utilities are a set of tools for quickly assembling modeling applications. + +
+The Time Management Library provides utilities for time and time interval representation, as well as a higher-level utility, a clock, that controls model time stepping. + +
+The ESMF Config class provides configuration management based on NASA DAO's Inpak package, a collection of methods for accessing files containing input parameters stored in an ASCII format. + +
+The ESMF LogErr class consists of a method for writing error, warning, and informational messages to a default Log file that is created during ESMF initialization. + +
+The ESMF VM (Virtual Machine) class provides methods for querying information about a VM. A VM is a generic representation of hardware and system software resources. There is exactly one VM object per ESMF Component, providing the execution environment for the Component code. The VM class handles all resource management tasks for the Component class and provides a description of the underlying configuration of the compute resources used by a Component. In addition to resource description and management, the VM class offers the lowest level of ESMF communication methods. + +
+The ESMF Time Manager utility includes software for time and time interval +representation, as well as model time advancement. Since multi-component +geophysical applications often require synchronization across +the time management schemes of the individual components, the +Time Manager's standard calendars and consistent time representation +promote component interoperability. +
+ +Key Features |
+
Drift-free timekeeping through an integer-based internal time +representation. Both integers and reals can be specified at the interface. | +
Support for many calendar kinds. | +
Support for both concurrent and sequential modes of component execution. | +
+ +
+ +
+ +
+ +
+The Calendar class represents the standard calendars used in +geophysical modeling: Gregorian, Julian, Julian Day, Modified Julian Day, +no-leap, 360-day, and no-calendar. Brief descriptions are provided for each calendar below. + +
+ +
+DESCRIPTION:
+
+Supported calendar kinds.
+
+
+The type of this flag is: + +
+type(ESMF_CalKind_Flag) + +
+The valid values are: +
+
+
+
+
+MJD = JD - 2400000.5 + +
+The half day is subtracted so that the day starts at midnight. + +
+
+
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Calendar ESMC_CalendarCreate( + const char *name, // in + enum ESMC_CalKind_Flag calkindflag, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_Calendar object. ++DESCRIPTION: +
+Creates and sets a ESMC_Calendar object to the given built-in + ESMC_CalKind_Flag. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_CalendarDestroy( + ESMC_Calendar *calendar // inout + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Releases all resources associated with this ESMC_Calendar. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_CalendarPrint( + ESMC_Calendar calendar // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Prints out an ESMC_Calendar's properties to stdio, + in support of testing and debugging. + +
+The arguments are: +
+ + +
+A Time represents a specific point in time. + +
+There are Time methods defined for setting and getting a Time. + +
+A Time that is specified in hours does not need to be associated with a +standard calendar; use ESMC_CALKIND_NOCALENDAR. A Time whose specification +includes time units of a year must be associated with a standard calendar. +The ESMF representation of a calendar, the Calendar class, is described in +Section 26.1. The ESMC_TimeSet method is used to +initialize a Time as well as associate it with a Calendar. If a Time method +is invoked in which a Calendar is necessary and one has not been set, the +ESMF method will return an error condition. + +
+In the ESMF the TimeInterval class is used to represent time periods. +This class is frequently used in combination with the Time class. +The Clock class, for example, advances model time by incrementing a +Time with a TimeInterval. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_TimeGet( + ESMC_Time time, // in + ESMC_I4 *yy, // out + ESMC_I4 *h, // out + ESMC_Calendar *calendar, // out + enum ESMC_CalKind_Flag *calkindflag, // out + int *timeZone // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Gets the value of an ESMC_Time in units specified by the user. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_TimePrint( + ESMC_Time time // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Prints out an ESMC_Time's properties to stdio, + in support of testing and debugging. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_TimeSet( + ESMC_Time *time, // inout + ESMC_I4 yy, // in + ESMC_I4 h, // in + ESMC_Calendar calendar, // in + enum ESMC_CalKind_Flag calkindflag, // in + int timeZone // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Initializes an ESMC_Time with a set of user-specified units. + +
+The arguments are: +
+ + +
+A TimeInterval represents a period between time instants. +It can be either positive or negative. + +
+There are TimeInterval methods defined for setting and getting +a TimeInterval, for printing the contents of a TimeInterval. + +
+The class used to represent time instants in ESMF is Time, +and this class is frequently used in operations along with +TimeIntervals. The Clock class, for example, advances model time by +incrementing a Time with a TimeInterval. + +
+TimeIntervals are used by other parts of the ESMF timekeeping +system, such as Clocks; see Section 29.1. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_TimeIntervalGet( + ESMC_TimeInterval timeinterval, // in + ESMC_I8 *s_i8, // out + ESMC_R8 *h_r8 // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Gets the value of an ESMC_TimeInteval in units specified by the user. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_TimeIntervalPrint( + ESMC_TimeInterval timeinterval // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Prints out an ESMC_TimeInterval's properties to stdio, + in support of testing and debugging. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_TimeIntervalSet( + ESMC_TimeInterval *timeinterval, // inout + ESMC_I4 h // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Sets the value of the ESMC_TimeInterval in units specified by + the user. + +
+The arguments are: +
+ + +
+The Clock class advances model time and tracks its associated +date on a specified Calendar. It stores start time, stop time, +current time, and a time step. + +
+There are methods for setting and getting the Times associated +with a Clock. Methods are defined for advancing the Clock's +current time and printing a Clock's contents. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ClockAdvance( + ESMC_Clock clock // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Advances the ESMC_Clock's current time by one time step. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Clock ESMC_ClockCreate( + const char *name, // in + ESMC_TimeInterval timeStep, // in + ESMC_Time startTime, // in + ESMC_Time stopTime, // in + int *rc // out + ); +RETURN VALUE: +
Newly created ESMC_Clock object. ++DESCRIPTION: +
+Creates and sets the initial values in a new ESMC_Clock object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ClockDestroy( + ESMC_Clock *clock // inout + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Releases all resources associated with this ESMC_Clock. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ClockGet( + ESMC_Clock clock, // in + ESMC_TimeInterval *currSimTime, // out + ESMC_I8 *advanceCount // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Gets one or more of the properties of an ESMC_Clock. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ClockPrint( + ESMC_Clock clock // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Prints out an ESMC_Clock's properties to stdio, + in support of testing and debugging. + +
+The arguments are: +
+ + +
+ESMF Configuration Management is based on NASA DAO's
+Inpak 90 package, a Fortran 90 collection of routines/functions
+for accessing Resource Files in ASCII format.The package
+is optimized for minimizing formatted I/O, performing all of its
+string operations in memory using Fortran intrinsic functions.
+
+
+ +
+The ESMF Configuration Management Package was evolved by +Leonid Zaslavsky and Arlindo da Silva from Ipack90 package +created by Arlindo da Silva at NASA DAO. + +
+Back in the 70's Eli Isaacson wrote IOPACK in Fortran +66. In June of 1987 Arlindo da Silva wrote Inpak77 using +Fortran 77 string functions; Inpak 77 is a vastly +simplified IOPACK, but has its own goodies not found in +IOPACK. Inpak 90 removes some obsolete functionality in +Inpak77, and parses the whole resource file in memory for +performance. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Config ESMC_ConfigCreate( + int* rc // out + ); +RETURN VALUE: +
ESMC_Config* to newly allocated ESMC_Config ++DESCRIPTION: +
+Creates an ESMC_Config for use in subsequent calls. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ConfigDestroy( + ESMC_Config* config // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Destroys the config object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_Config ESMC_ConfigCreateFromSection( + ESMC_Config config, // in + const char* olabel, // in + const char* clabel, // in + int* rc // out + ); +RETURN VALUE: +
ESMC_Config* to newly allocated ESMC_Config ++DESCRIPTION: +
+Instantiates an ESMC_Config object from a section of an existing + ESMC_Config object delimited by openlabel and closelabel. + An error is returned if neither of the input labels is found in input + config. + +
+Note that a section is intended as the content of a given ESMC_Config + object delimited by two distinct labels. Such content, as well as each of the + surrounding labels, are still within the scope of the parent ESMC_Config + object. Therefore, including in a section labels used outside that + section should be done carefully to prevent parsing conflicts. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ConfigFindLabel( + ESMC_Config config, // in + const char* label, // in + int *isPresent // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. + If label not found, and the {\tt isPresent} pointer is {\tt NULL}, + an error will be returned. ++DESCRIPTION: +
+Finds the label (key) in the config file. + +
+Since the search is done by looking for a word in the + whole resource file, it is important to use special + conventions to distinguish labels from other words + in the resource files. The DAO convention is to finish + line labels by : and table labels by ::. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ConfigFindNextLabel( + ESMC_Config config, // in + const char* label, // in + int *isPresent // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. + If label not found, and the {\tt isPresent} pointer is {\tt NULL}, + an error will be returned. ++DESCRIPTION: +
+Finds the label (key) string in the config object, + starting from the current position pointer. + +
+This method is equivalent to ESMC_ConfigFindLabel, but the search + is performed starting from the current position pointer. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ConfigGetDim( + ESMC_Config config, // in + int* lineCount, // out + int* columnCount, // out + ... // optional argument list + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Returns the number of lines in the table in lineCount and + the maximum number of words in a table line in columnCount. + +
+The arguments are: +
+Due to this method accepting optional arguments, the final argument + must be ESMC_ArgLast. + +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ConfigGetLen( + ESMC_Config config, // in + int* wordCount, // out + ... // optional argument list + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Gets the length of the line in words by counting words + disregarding types. Returns the word count as an integer. + +
+The arguments are: +
+Due to this method accepting optional arguments, the final argument + must be ESMC_ArgLast. + +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ConfigLoadFile( + ESMC_Config config, // in + const char* file, // in + ... // optional argument list + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Resource file with filename is loaded into memory. + +
+The arguments are: +
+Due to this method accepting optional arguments, the final argument + must be ESMC_ArgLast. + +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ConfigNextLine( + ESMC_Config config, // in + int *tableEnd // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Selects the next line (for tables). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ConfigPrint( + ESMC_Config config // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Write content of a ESMC_Config object to standard output. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_ConfigValidate( + ESMC_Config config, // in + ... // optional argument list + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. + Equals ESMF_RC_ATTR_UNUSED if any unused attributes are found + with option "unusedAttributes" below. ++DESCRIPTION: +
+Checks whether a config object is valid. + +
+The arguments are: +
+Due to this method accepting optional arguments, the final argument + must be ESMC_ArgLast. + +
+ + +
+The Log class consists of a variety of methods for writing error, warning, and +informational messages to files. A default Log is created at ESMF +initialization. + +
+When ESMF is started with ESMC_Initialize(), multiple Log files will +be created by PET number. The PET number (in the format +PETx.) will be prepended to each file name where x is the PET number. +The ESMC_LogWrite() call is used to issue messages to the log. As +part of the call, a message can be tagged as either an informational, +warning, or error message. + +
+The messages may be buffered within ESMF before appearing in the log. +All messages will be properly flushed to the log files when ESMC_Finalize() +is called. + +
+ +
+DESCRIPTION:
+
+Specifies a single log file, multiple log files (one per PET), or no log files.
+
+
+The valid values are: +
+ +
+DESCRIPTION:
+
+
+Specifies a message level.
+
+
+The valid values are: +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_LogWrite( + const char msg[], // in + int msgtype // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Write an entry into the Log file. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_LogSet( + int flush // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Set Log properties. + +
+The arguments are: +
+ + +
+The ESMF VM (Virtual Machine) class is a generic representation of hardware and system software resources. There is exactly one VM object per ESMF Component, providing the execution environment for the Component code. The VM class handles all resource management tasks for the Component class and provides a description of the underlying configuration of the compute resources used by a Component. + +
+In addition to resource description and management, the VM class offers the lowest level of ESMF communication methods. The VM communication calls are very similar to MPI. Data references in VM communication calls must be provided as raw, language-specific, one-dimensional, contiguous data arrays. The similarity between VM and MPI communication calls is striking and there are many equivalent point-to-point and collective communication calls. However, unlike MPI, the VM communication calls support communication between threaded PETs in a completely transparent fashion. + +
+Many ESMF applications do not interact with the VM class directly very much. The resource management aspect is wrapped completely transparent into the ESMF Component concept. Often the only reason that user code queries a Component +object for the associated VM object is to inquire about resource information, such as the localPet or the petCount. Further, for most applications the use of higher level communication APIs, such as provided by Array and Field, are much more convenient than using the low level VM communication calls. + +
+The basic elements of a VM are called PETs, which stands for Persistent Execution Threads. These are equivalent to OS threads with a lifetime of at least that of the associated component. All VM functionality is expressed in terms of PETs. In the simplest, and most common case, a PET is equivalent to an MPI process. However, ESMF also supports multi-threading, where multiple PETs run as Pthreads inside the same virtual address space (VAS). + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_VMBarrier( + ESMC_VM vm // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Collective ESMC_VM communication call that blocks calling PET until + all PETs of the VM context have issued the call. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_VMBroadcast(ESMC_VM vm, + void *bcstData, + int count, + enum ESMC_TypeKind_Flag *typekind, + int rootPet); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Collective ESMC_VM communication call that broadcasts a contiguous + data array from rootPet to all other PETs of the ESMC_VM + object. + +
+This method is overloaded for: + ESMC_TYPEKIND_I4, ESMC_TYPEKIND_I8, + ESMC_TYPEKIND_R4, ESMC_TYPEKIND_R8, + ESMC_TYPEKIND_LOGICAL. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_VMGet( + ESMC_VM vm, // in + int *localPet, // out + int *petCount, // out + int *peCount, // out + MPI_Comm *mpiCommunicator, // out + int *pthreadsEnabledFlag, // out + int *openMPEnabledFlag // out + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Get internal information about the specified ESMC_VM object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_VM ESMC_VMGetCurrent( + int *rc // out + ); +RETURN VALUE: +
VM object of the current execution context. ++DESCRIPTION: +
+Get the ESMC_VM object of the current execution context. Calling + ESMC_VMGetCurrent() within an ESMC Component, will return the + same VM object as ESMC_GridCompGet(..., vm=vm, ...) or + ESMC_CplCompGet(..., vm=vm, ...). + +
+The main purpose of providing ESMC_VMGetCurrent() is to simplify ESMF + adoption in legacy code. Specifically, code that uses MPI_COMM_WORLD + deep within its calling tree can easily be modified to use the correct MPI + communicator of the current ESMF execution context. The advantage is that + these modifications are very local, and do not require wide reaching + interface changes in the legacy code to pass down the ESMF component object, + or the MPI communicator. + +
+The use of ESMC_VMGetCurrent() is strongly discouraged in newly + written Component code. Instead, the ESMF Component object should be used as + the appropriate container of ESMF context information. This object should be + passed between the subroutines of a Component, and be queried for any + Component specific information. + +
+Outside of a Component context, i.e. within the driver context, the call
+ to ESMC_VMGetCurrent() is identical to ESMC_VMGetGlobal().
+
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
ESMC_VM ESMC_VMGetGlobal( + int *rc // out + ); +RETURN VALUE: +
VM object of the global execution context. ++DESCRIPTION: +
+Get the global ESMC_VM object. This is the VM object + that is created during ESMC_Initialize() and is the ultimate + parent of all VM objects in an ESMF application. It is identical to the VM + object returned by ESMC_Initialize(..., vm=vm, ...). + +
+The ESMC_VMGetGlobal() call provides access to information about the + global execution context via the global VM. This call is necessary because + ESMF does not create a global ESMF Component during + ESMC_Initialize() that could be queried for information about + the global execution context of an ESMF application. + +
+Usage of ESMC_VMGetGlobal() from within Component code is
+ strongly discouraged. ESMF Components should only access their own VM
+ objects through Component methods. Global information, if required by
+ the Component user code, should be passed down to the Component from the
+ driver through the Component calling interface.
+
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_VMLogMemInfo( + const char *prefix // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Write memory info to the log file. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_VMPrint( + ESMC_VM vm // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Print internal information of the specified ESMC_VM object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_VMReduce(ESMC_VM vm, + void *sendData, + void *recvData, + int count, + enum ESMC_TypeKind_Flag *typekind, + enum ESMC_Reduce_Flag *reduceflag, + int rootPet); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Collective ESMC_VM communication call that reduces a contiguous data + array across the ESMC_VM object into a contiguous data array of + the same <type><kind>. The result array is returned on rootPet. + Different reduction operations can be specified. + +
+This method is overloaded for: + ESMC_TYPEKIND_I4, ESMC_TYPEKIND_I8, + ESMC_TYPEKIND_R4, ESMC_TYPEKIND_R8. + +
+The arguments are: +
+ + +
+ +
+ESMF's built in profiling capability collects runtime statistics +of an executing ESMF application through both automatic and manual code +instrumentation. Timing information for all phases of all ESMF components +executing in an application can be automatically collected using the +ESMF_RUNTIME_PROFILE environment variable (see below for settings). +Additionally, arbitrary user-defined code regions can be timed by +manually instrumenting code with special API calls. Timing profiles +of component phases and user-defined regions can be output in several +different formats: + +
+The following table lists important environment variables that control +aspects of ESMF profiling. + +
+
Environment Variable | +Description | +Example Values | +Default | +
ESMF_RUNTIME_PROFILE | +Enable/disables all profiling functions | +ON or OFF | +OFF | +
ESMF_RUNTIME_PROFILE_PETLIST | +Limits profiling to an explicit list of PETs | +“0-9 50 99” | +profile all PETs | +
ESMF_RUNTIME_PROFILE_OUTPUT | +Controls output format of profiles; multiple can be specified in a space separated list | +TEXT, SUMMARY, BINARY | +TEXT | +
+ +
+Whereas profiling collects summary information from an application, +tracing records a more detailed set of events for later analysis. Trace +analysis can be used to understand what happened during a program's +execution and is often used for diagnosing problems, debugging, and +performance analysis. + +
+ESMF has a built-in tracing capability that records events into special +binary log files. Unlike log files written by the ESMF_Log class, +which are primarily for human consumption (see Section 31.1), +the trace output files are +recorded in a compact binary representation and are processed by tools +to produce various analyses. ESMF event streams are recorded in the +Common Trace Format +(CTF). +CTF traces include one or more event streams, +as well as a metadata file describing the events in the streams. + +
+Several tools are available for reading in the CTF traces output by ESMF. +Of the tools listed below, the first one is designed specifically for +analyzing ESMF applications and the second two are general purpose tools +for working with all CTF traces. + +
+Events that can be captured by the ESMF tracer include the following. Events +are recorded with a high-precision timestamp to allow timing analyses. +
+The following table lists important environment variables that control +aspects of ESMF tracing. + +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_TraceRegionEnter( + const char* name // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Enter a named trace region. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
int ESMC_TraceRegionExit( + const char* name // in + ); +RETURN VALUE: +
Return code; equals ESMF_SUCCESS if there are no errors. ++DESCRIPTION: +
+Exit a named trace region. + +
+The arguments are: +
+ + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMC_crefdoc/node7.html b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/node7.html new file mode 100644 index 000000000..b22d1525e --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/node7.html @@ -0,0 +1,59 @@ + + + + + ++ +
+ +
+ +
+ +
+The type of this flag is: + +
+type(ESMC_Decomp_Flag) + +
+The valid values are: +
+subsection(ESMC_ExtrapMethod_Flag)
+DESCRIPTION:
+
+Specify which extrapolation method to use on unmapped destination points after
+regridding.
+
+
+The type of this flag is: + +
+type(ESMC_ExtrapMethod_Flag) + +
+The valid values are: +
+ +
+subsection(ESMC_FileMode_Flag)
+DESCRIPTION:
+
+Specify which mode to use when writing a weight file.
+
+
+The type of this flag is: + +
+type(ESMC_FileMode_Flag) + +
+The valid values are: +
+ +
+ +
+ +
+DESCRIPTION:
+
+Indicates whether index is local (per DE) or global (per object).
+
+
+The type of this flag is: + +
+type(ESMC_IndexFlag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
This argument allows the user to select the path of the
+line which connects two points on the surface of a sphere.
+This in turn controls the path along which distances are calculated and the
+shape of the edges that make up a cell.
+
+
+The type of this flag is: + +
+type(ESMC_LineType_Flag) + +
+The valid values are: +
+ +
+ +
+ +
+ +
+DESCRIPTION:
+
+Specify standard ESMF Component method.
+
+
+The type of this flag is: + +
+type(ESMF_Method_Flag) + +
+The valid values are: +
+ +
+ +
+The type of this flag is: + +
+type(ESMC_Reduce_Flag) + +
+The valid values are: +
+ +
+The type of this flag is: + +
+type(ESMC_Region_Flag) + +
+The valid values are: +
+ +
+ +
+ +
+DESCRIPTION:
+
+Named constants used to indicate type and kind combinations supported by the
+overloaded ESMC interfaces. The corresponding Fortran kind-parameter constants
+are described in the ESMF_TYPEKIND section of Appendices of the ESMF Fortran
+reference manual.
+
+
+The type of these named constants is: + +
+type(ESMC_TypeKind_Flag) + +
+The named constants are: +
+ +
+The type of this flag is: + +
+type(ESMC_UnmappedAction_Flag) + +
+The valid values are: +
+ +
+The schematic below shows the Unified Modeling Language (UML) notation +for the class diagrams presented in this Reference Manual. For +more on UML, see references such as The Unified Modeling Language +Reference Manual, Rumbaugh et al, [3]. + +
+
+ +
+The tables below show the possible error return codes for Fortran and +C methods. + +
+ +
+ +
+ +
+
+ + ===================================== + Fortran Symmetric Return Codes 1-500 + ===================================== + + ESMF_SUCCESS 0 + ESMF_RC_OBJ_BAD 1 + ESMF_RC_OBJ_INIT 2 + ESMF_RC_OBJ_CREATE 3 + ESMF_RC_OBJ_COR 4 + ESMF_RC_OBJ_WRONG 5 + ESMF_RC_ARG_BAD 6 + ESMF_RC_ARG_RANK 7 + ESMF_RC_ARG_SIZE 8 + ESMF_RC_ARG_VALUE 9 + ESMF_RC_ARG_DUP 10 + ESMF_RC_ARG_SAMETYPE 11 + ESMF_RC_ARG_SAMECOMM 12 + ESMF_RC_ARG_INCOMP 13 + ESMF_RC_ARG_CORRUPT 14 + ESMF_RC_ARG_WRONG 15 + ESMF_RC_ARG_OUTOFRANGE 16 + ESMF_RC_ARG_OPT 17 + ESMF_RC_NOT_IMPL 18 + ESMF_RC_FILE_OPEN 19 + ESMF_RC_FILE_CREATE 20 + ESMF_RC_FILE_READ 21 + ESMF_RC_FILE_WRITE 22 + ESMF_RC_FILE_UNEXPECTED 23 + ESMF_RC_FILE_CLOSE 24 + ESMF_RC_FILE_ACTIVE 25 + ESMF_RC_PTR_NULL 26 + ESMF_RC_PTR_BAD 27 + ESMF_RC_PTR_NOTALLOC 28 + ESMF_RC_PTR_ISALLOC 29 + ESMF_RC_MEM 30 + ESMF_RC_MEM_ALLOCATE 31 + ESMF_RC_MEM_DEALLOCATE 32 + ESMF_RC_MEMC 33 + ESMF_RC_DUP_NAME 34 + ESMF_RC_LONG_NAME 35 + ESMF_RC_LONG_STR 36 + ESMF_RC_COPY_FAIL 37 + ESMF_RC_DIV_ZERO 38 + ESMF_RC_CANNOT_GET 39 + ESMF_RC_CANNOT_SET 40 + ESMF_RC_NOT_FOUND 41 + ESMF_RC_NOT_VALID 42 + ESMF_RC_INTNRL_LIST 43 + ESMF_RC_INTNRL_INCONS 44 + ESMF_RC_INTNRL_BAD 45 + ESMF_RC_SYS 46 + ESMF_RC_BUSY 47 + ESMF_RC_LIB 48 + ESMF_RC_LIB_NOT_PRESENT 49 + ESMF_RC_ATTR_UNUSED 50 + ESMF_RC_OBJ_NOT_CREATED 51 + ESMF_RC_OBJ_DELETED 52 + ESMF_RC_NOT_SET 53 + ESMF_RC_VAL_WRONG 54 + ESMF_RC_VAL_ERRBOUND 55 + ESMF_RC_VAL_OUTOFRANGE 56 + ESMF_RC_ATTR_NOTSET 57 + ESMF_RC_ATTR_WRONGTYPE 58 + ESMF_RC_ATTR_ITEMSOFF 59 + ESMF_RC_ATTR_LINK 60 + ESMF_RC_BUFFER_SHORT 61 + ESMF_RC_TIMEOUT 62 + ESMF_RC_FILE_EXISTS 63 + ESMF_RC_FILE_NOTDIR 64 + ESMF_RC_MOAB_ERROR 65 + ESMF_RC_NOOP 66 + ESMF_RC_NETCDF_ERROR 67 + + 68-499 reserved for future Fortran symmetric return code definitions + + ===================================== + C/C++ Symmetric Return Codes 501-999 + ===================================== + + ESMC_RC_OBJ_BAD 501 + ESMC_RC_OBJ_INIT 502 + ESMC_RC_OBJ_CREATE 503 + ESMC_RC_OBJ_COR 504 + ESMC_RC_OBJ_WRONG 505 + ESMC_RC_ARG_BAD 506 + ESMC_RC_ARG_RANK 507 + ESMC_RC_ARG_SIZE 508 + ESMC_RC_ARG_VALUE 509 + ESMC_RC_ARG_DUP 510 + ESMC_RC_ARG_SAMETYPE 511 + ESMC_RC_ARG_SAMECOMM 512 + ESMC_RC_ARG_INCOMP 513 + ESMC_RC_ARG_CORRUPT 514 + ESMC_RC_ARG_WRONG 515 + ESMC_RC_ARG_OUTOFRANGE 516 + ESMC_RC_ARG_OPT 517 + ESMC_RC_NOT_IMPL 518 + ESMC_RC_FILE_OPEN 519 + ESMC_RC_FILE_CREATE 520 + ESMC_RC_FILE_READ 521 + ESMC_RC_FILE_WRITE 522 + ESMC_RC_FILE_UNEXPECTED 523 + ESMC_RC_FILE_CLOSE 524 + ESMC_RC_FILE_ACTIVE 525 + ESMC_RC_PTR_NULL 526 + ESMC_RC_PTR_BAD 527 + ESMC_RC_PTR_NOTALLOC 528 + ESMC_RC_PTR_ISALLOC 529 + ESMC_RC_MEM 530 + ESMC_RC_MEM_ALLOCATE 531 + ESMC_RC_MEM_DEALLOCATE 532 + ESMC_RC_MEMC 533 + ESMC_RC_DUP_NAME 534 + ESMC_RC_LONG_NAME 535 + ESMC_RC_LONG_STR 536 + ESMC_RC_COPY_FAIL 537 + ESMC_RC_DIV_ZERO 538 + ESMC_RC_CANNOT_GET 539 + ESMC_RC_CANNOT_SET 540 + ESMC_RC_NOT_FOUND 541 + ESMC_RC_NOT_VALID 542 + ESMC_RC_INTNRL_LIST 543 + ESMC_RC_INTNRL_INCONS 544 + ESMC_RC_INTNRL_BAD 545 + ESMC_RC_SYS 546 + ESMC_RC_BUSY 547 + ESMC_RC_LIB 548 + ESMC_RC_LIB_NOT_PRESENT 549 + ESMC_RC_ATTR_UNUSED 550 + ESMC_RC_OBJ_NOT_CREATED 551 + ESMC_RC_OBJ_DELETED 552 + ESMC_RC_NOT_SET 553 + ESMC_RC_VAL_WRONG 554 + ESMC_RC_VAL_ERRBOUND 555 + ESMC_RC_VAL_OUTOFRANGE 556 + ESMC_RC_ATTR_NOTSET 557 + ESMC_RC_ATTR_WRONGTYPE 558 + ESMC_RC_ATTR_ITEMSOFF 559 + ESMC_RC_ATTR_LINK 560 + ESMC_RC_BUFFER_SHORT 561 + ESMC_RC_TIMEOUT 562 + ESMC_RC_FILE_EXISTS 563 + ESMC_RC_FILE_NOTDIR 564 + ESMC_RC_MOAB_ERROR 565 + ESMC_RC_NOOP 566 + ESMC_RC_NETCDF_ERROR 567 + + 568-999 reserved for future C/C++ symmetric return code definitions + + ===================================== + C/C++ Non-symmetric Return Codes 1000 + ===================================== + + ESMC_RC_OPTARG_BAD 1000 ++ + +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMC_crefdoc/prev.png b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/prev.png new file mode 100644 index 000000000..e60b8b407 Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/prev.png differ diff --git a/docs/nightly/fix/reconcile-info/ESMC_crefdoc/prev_g.png b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/prev_g.png new file mode 100644 index 000000000..ac6f0bceb Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/prev_g.png differ diff --git a/docs/nightly/fix/reconcile-info/ESMC_crefdoc/up.png b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/up.png new file mode 100644 index 000000000..3937e168f Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/up.png differ diff --git a/docs/nightly/fix/reconcile-info/ESMC_crefdoc/up_g.png b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/up_g.png new file mode 100644 index 000000000..fb36cf765 Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMC_crefdoc/up_g.png differ diff --git a/docs/nightly/fix/reconcile-info/ESMF_refdoc.pdf b/docs/nightly/fix/reconcile-info/ESMF_refdoc.pdf new file mode 100644 index 000000000..e57d109da Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMF_refdoc.pdf differ diff --git a/docs/nightly/fix/reconcile-info/ESMF_refdoc/ESMF_refdoc.css b/docs/nightly/fix/reconcile-info/ESMF_refdoc/ESMF_refdoc.css new file mode 100644 index 000000000..410279303 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_refdoc/ESMF_refdoc.css @@ -0,0 +1,42 @@ +/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ +.MATH { font-family: "Century Schoolbook", serif; } +.MATH I { font-family: "Century Schoolbook", serif; font-style: italic } +.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold } + +/* implement both fixed-size and relative sizes */ +SMALL.XTINY { font-size : xx-small } +SMALL.TINY { font-size : x-small } +SMALL.SCRIPTSIZE { font-size : smaller } +SMALL.FOOTNOTESIZE { font-size : small } +SMALL.SMALL { } +BIG.LARGE { } +BIG.XLARGE { font-size : large } +BIG.XXLARGE { font-size : x-large } +BIG.HUGE { font-size : larger } +BIG.XHUGE { font-size : xx-large } + +/* heading styles */ +H1 { } +H2 { } +H3 { } +H4 { } +H5 { } + +/* mathematics styles */ +DIV.displaymath { } /* math displays */ +TD.eqno { } /* equation-number cells */ + + +/* document-specific styles come next */ +SPAN.bf { } +DIV.center { } +DIV.em { } +SPAN.it { } +DIV.navigation { } +PRE.preform { } +DIV.quote { } +SPAN.sc { } +SPAN.tt { } +SPAN.arabic { } +SPAN.textbf { font-weight: bold } +SPAN.textit { font-style: italic } diff --git a/docs/nightly/fix/reconcile-info/ESMF_refdoc/ESMF_refdoc.html b/docs/nightly/fix/reconcile-info/ESMF_refdoc/ESMF_refdoc.html new file mode 100644 index 000000000..6f7440320 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_refdoc/ESMF_refdoc.html @@ -0,0 +1,1010 @@ + + + + + ++ +
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The ESMF software is based on the contributions of a broad community. +Below are the software packages that are included in ESMF or strongly +influenced our design. We'd like to express our gratitude to the +developers of these codes for access to their software as well as their +ideas and advice. + +
+ +
+
+
+
+
+
+
+
+
+
. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. ++
. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. +. ++
+ +
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The ESMF software is based on the contributions of a broad community. +Below are the software packages that are included in ESMF or strongly +influenced our design. We'd like to express our gratitude to the +developers of these codes for access to their software as well as their +ideas and advice. + +
+ +
+
+
+
+
+
+
+
+
+
+This document was generated using the +LaTeX2HTML translator Version 2018 (Released Feb 1, 2018) +
+Copyright © 1993, 1994, 1995, 1996,
+Nikos Drakos,
+Computer Based Learning Unit, University of Leeds.
+
+Copyright © 1997, 1998, 1999,
+Ross Moore,
+Mathematics Department, Macquarie University, Sydney.
+
+The command line arguments were:
+ latex2html -white -toc_depth 5 -split +1 -show_section_numbers -local_icons -address 'esmf_support@ucar.edu' ESMF_refdoc.tex
+
+The translation was initiated on 2024-12-03
+
+ +
+The Earth System Modeling Framework (ESMF) is a suite of software +tools for developing high-performance, multi-component Earth science +modeling applications. Such applications may include a few or dozens +of components representing atmospheric, oceanic, terrestrial, or +other physical domains, and their constituent processes (dynamical, chemical, +biological, etc.). Often these components are developed by different +groups independently, and must be “coupled” together using software +that transfers and transforms data among the components in order to form +functional simulations. + +
+ESMF supports the development of these complex applications in a number +of ways. It introduces a set of simple, consistent component interfaces +that apply to all types of components, including couplers themselves. These +interfaces expose in an obvious way the inputs and outputs of each component. +It offers a variety of data structures for transferring data between components, +and libraries for regridding, time advancement, and other common modeling +functions. Finally, it provides a growing set of tools for using metadata +to describe components and their input and output fields. This capability +is important because components that are self-describing +can be integrated more easily into automated workflows, model and dataset +distribution and analysis portals, and other emerging “semantically enabled” +computational environments. + +
+ESMF is not a single Earth system model into which all components +must fit, and its distribution doesn't contain any scientific code. +Rather it provides a way of structuring components so that they can be used +in many different user-written applications and contexts with minimal code +modification, and so they can be coupled together in new configurations +with relative ease. The idea is to create many components across a +broad community, and so to encourage new collaborations and combinations. + +
+ESMF offers the flexibility needed by this diverse user base. It is tested +nightly on more than two dozen platform/compiler combinations; can be +run on one processor or thousands; supports shared and distributed memory +programming models and a hybrid model; can run components +sequentially (on all the same processors) or concurrently (on mutually +exclusive processors); and supports single executable or multiple +executable modes. + +
+ESMF's generality and breadth of function can make it daunting for the +novice user. To help users navigate the software, we try to apply +consistent names and behavior throughout and to provide many examples. +The large-scale structure of the software is straightforward. +The utilities and data structures for building modeling components +are called the ESMF infrastructure. The coupling interfaces and +drivers are called the superstructure. User code sits between +these two layers, making calls to the infrastructure +libraries underneath and being scheduled and synchronized by the +superstructure above. The configuration resembles a sandwich, as +shown in Figure 1. + +
+ESMF users may choose to extensively rewrite their codes +to take advantage of the ESMF infrastructure, or they may decide to +simply wrap their components in the ESMF superstructure in order to +utilize framework coupling services. Either way, we encourage users +to contact our +support team +if questions arise about how to best +use the software, or how to structure their application. ESMF is +more than software; it's a group of people dedicated to realizing +the vision of a collaborative model development community that spans +institutional and national bounds. + +
+ +
+ESMF has a complete set of Fortran interfaces and +some C interfaces. This ESMF Reference Manual is a listing of +ESMF interfaces for Fortran.1 + +
+Interfaces are grouped by class. A class is comprised of the data and +methods for a specific concept like a physical field. Superstructure classes +are listed first in this Manual, followed by infrastructure +classes. + +
+The major classes in the ESMF superstructure are Components, which +usually represent +large pieces of functionality such as atmosphere and ocean models, +and States, which are the data structures +used to transfer data between Components. There are both data +structures and utilities in the ESMF +infrastructure. Data structures include multi-dimensional Arrays, Fields +that are comprised of an Array and a Grid, and collections of Arrays +and Fields called ArrayBundles and FieldBundles, respectively. +There are utility libraries for data decomposition and communications, +time management, logging and error handling, and application configuration. + +
+
+ |
+The website, http://www.earthsystemmodeling.org, provide more information of the ESMF project as a whole. +The website includes release notes and known bugs for each version of the +framework, supported platforms, project history, values, and metrics, related projects, +the ESMF management structure, and more. The ESMF User's Guide +contains build and installation instructions, an overview of the ESMF system and a description of +how its classes interrelate (this version of the document corresponds to the last public version of the framework). Also available on the ESMF website is the +ESMF Developer's Guide +that details ESMF procedures and conventions. + +
+ +
+ +
+ +
+ +
+The following conventions for fonts and capitalization are used
+in this and other ESMF documents.
+
+
+
Style | +Meaning | +Example | +
italics | +documents | +ESMF Reference Manual | +
courier | +code fragments | +ESMF_TRUE | +
courier() | +ESMF method name | +ESMF_FieldGet() | +
boldface | +first definitions | +An address space is ... | +
boldface | +web links and tabs | +Developers tab on the website | +
Capitals | +ESMF class name | +DataMap | +
+ESMF class names frequently coincide with words commonly +used within the Earth system domain (field, grid, component, array, +etc.) The convention we adopt in this manual is that if a word is +used in the context of an ESMF class name it is capitalized, and +if the word is used in a more general context it remains in lower +case. We would write, for example, that an ESMF Field class +represents a physical field. + +
+Diagrams are drawn using the Unified Modeling Language (UML). UML +is a visual tool that can illustrate the structure of +classes, define relationships between classes, and describe sequences +of actions. A reader interested in more detail can refer to a +text such as The Unified Modeling Language Reference Manual. + [29] + +
+ +
+Method names begin with ESMF_, followed by the class name, +followed by the name of the operation being performed. Each new +word is capitalized. Although Fortran interfaces are not case-sensitive, +we use case to help parse multi-word names. + +
+For method arguments that are multi-word, the first word is lower +case and subsequent words begin with upper case. ESMF class +names (including typed flags) are an exception. When multi-word +class names appear in argument lists, all letters after the first +are lower case. The first letter is lower case if the class is the +first word in the argument and upper case otherwise. For +example, in an argument list the DELayout class name may appear +as delayout or srcDelayout. + +
+Most Fortran calls in the ESMF are subroutines, with +any returned values passed through the interface. For the sake of +convenience, some ESMF calls are written as functions. + +
+A typical ESMF call looks like this: + +
+
+call ESMF_<ClassName><Operation>(classname, firstArgument, + secondArgument, ..., rc) ++ +
+where
+<ClassName> is the class name,
+<Operation> is the name of the action to be performed,
+classname is a variable of the derived type associated
+with the class,
+the arg* arguments are whatever other variables are required
+for the operation,
+and rc is a return code.
+
+
+ +
+The ESMF Application Programming Interface (API) is based on the +object-oriented programming concept of a class. A class is a +software construct that is used for grouping a set of related variables +together with the subroutines and functions that operate on them. We +use classes in ESMF because they help to organize the code, and often +make it easier to maintain and understand. A particular instance +of a class is called an object. For example, Field is an +ESMF class. An actual Field called temperature is an object. +That is about as far as we will go into software engineering +terminology. + +
+The Fortran interface is implemented so that the variables associated +with a class are stored in a derived type. For example, an +ESMF_Field derived type stores the data array, grid +information, and metadata associated with a physical field. +The derived type for each class is stored in a Fortran module, and +the operations associated with each class are defined as module +procedures. We use the Fortran features of generic functions and +optional arguments extensively to simplify our interfaces. + +
+The modules for ESMF are bundled together and can be accessed with a +single USE statement, USE ESMF. + +
+ +
+ESMF defines a set of standard methods and interface rules that +hold across the entire API. These are: + +
+ +
+
+ +
+
+
+
+
+ +
+ESMF contains two types of classes. + +
+Deep classes require +ESMF_<Class>Create() and ESMF_<Class>Destroy() calls. +They involve memory allocation, take significant time to set up (due to +memory management) and should not be created in a time-critical portion of code. +Deep objects persist even after the method in which they were created has +returned. Most classes in ESMF, including GridComp, CplComp, State, Fields, +FieldBundles, Arrays, ArrayBundles, Grids, and Clocks, fall into this category. + +
+Shallow classes do not possess ESMF_<Class>Create() +and ESMF_<Class>Destroy() calls. They are simply declared +and their values set using an ESMF_<Class>Set() call. +Examples of shallow classes are Time, TimeInterval, and ArraySpec. +Shallow classes do not take long to set up and can be declared and set within +a time-critical code segment. Shallow objects stop existing when execution +goes out of the declaring scope. + +
+An exception to this is when a shallow object, such as a Time, +is stored in a deep object such as a Clock. The deep Clock object then +becomes the declaring scope of the Time object, persisting in memory. +The Time object is deallocated with the ESMF_ClockDestroy() call. + +
+See Section 9, Overall Design and Implementation +Notes, for a brief discussion of deep and shallow classes from +an implementation perspective. For an in-depth look at the design +and inter-language issues related to deep and shallow classes, +see the ESMF Implementation Report. + +
+ +
+Deep objects, i.e. instances of ESMF deep classes created by the appropriate +ESMF_<Class>Create(), can be used with the standard assignment (=), +equality (==), and not equal (/=) operators. + +
+The assignment +
+deep2 = deep1 ++makes deep2 an alias of deep1, meaning that both variables +reference the same deep allocation in memory. Many aliases of the same deep +object can be created. + +
+All the aliases of a deep object are equivalent. In particular, there is no +distinction between the variable on the left hand side of the actual +ESMF_<Class>Create() call, and any aliases created from it. All actions +taken on any of the aliases of a deep object affect the deep object, and thus +all other aliases. + +
+The equality and not equal operators for deep objects are implemented as simple +alias checks. For a more general comparison of two distinct deep objects, a +deep class might provide the ESMF_<Class>Match() method. + +
+ESMF provides the concept of a named alias. A named alias behaves just +like an alias in all aspects, except when it comes to setting and getting the +name of the deep object it is associated with. While regular aliases +all access the same name string in the actual deep object, a named alias keeps +its private name string. This allows the same deep object to be known under a +different name in different contexts. + +
+The assignment +
+deep2 = ESMF_NamedAlias(deep1) ++makes deep2 a named alias of deep1. Any name changes on +deep2 only affect deep2. However, the name retrieved from +deep1, or from any regular aliases created from deep1, is +unaffected. + +
+Notice that aliases generated from a named alias are again named aliases. This +is true even when using the regular assignment operator with a named alias on +the right hand side. Named aliases own their unique name string that cannot +be accessed or altered through any other alias. + +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_NamedAlias(object, name, rc) +RETURN VALUE: +
type(ESMF_*) :: ESMF_NamedAlias +ARGUMENTS: +
type(ESMF_*), intent(in) :: object + character(len = *), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Generate a named alias to object. The supported classes are: + +
+The arguments are: +
+ + +
+ +
+The following are special methods which, in one case, +are required by any application using ESMF, and in the +other case must be called by any application that is using +ESMF Components. + +
+ +
+
+ +
+The ESMF API is organized around a hierarchy of classes that +contain model data. The operations that are performed +on model data, such as regridding, redistribution, and halo +updates, are methods of these classes. + +
+The main data classes in ESMF, in order of increasing complexity, are: + +
+
+Underlying these data classes are native language arrays. ESMF allows +you to reference an existing Fortran array to an ESMF Array or +Field so that ESMF data classes can be readily +introduced into existing code. You can perform communication operations +directly on Fortran arrays through the VM class, which serves +as a unifying wrapper for distributed and shared memory communication +libraries. + +
+ +
+Like the hierarchy of model data classes, ranging from the +simple to the complex, ESMF is organized around a hierarchy of +classes that represent different spaces associated with a computation. +Each of these spaces can be manipulated, in order to give +the user control over how a computation is executed. For Earth system +models, this hierarchy starts with the address space associated +with the computer and extends to the physical region described by +the application. The main spatial classes in ESMF, from +those closest to the machine to those closest to the application, are: + +
+ +
+
+
+
+
+
+
+
+
+ +
+In order to define how the index spaces of the spatial classes relate +to each other, we require either implicit rules (in which case the +relationship between spaces is defined by default), or special Map arrays +that allow the user to specify the desired association. The form of the +specification is usually that the position of the array element carries +information about the first object, and the value of the array element carries +information about the second object. ESMF includes a distGridToArrayMap, +a gridToFieldMap, a distGridToGridMap, and others. + +
+ +
+It can be useful to make small packets +of descriptive parameters. ESMF has one of these: + +
+ +
+There are a number of utilities in ESMF that can be used independently. +These are: + +
+ +
+Depending on the requirements of the application, the user may +want to begin integrating ESMF in either a top-down or bottom-up +manner. In the top-down approach, tools at the superstructure +level are used to help reorganize and structure the interactions +among large-scale components in the application. It is appropriate +when interoperability is a primary concern; for example, when +several different versions or implementations of components are going +to be swapped in, or a particular component is going to be used +in multiple contexts. Another reason for deciding on a top-down +approach is that the application contains legacy code that for +some reason (e.g., intertwined functions, very large, +highly performance-tuned, resource limitations) there is little +motivation to fully restructure. The superstructure can usually be +incorporated into such applications in a way that is non-intrusive. + +
+In the bottom-up approach, the user selects desired utilities +(data communications, calendar management, performance profiling, +logging and error handling, etc.) from the ESMF infrastructure +and either writes new code using them, introduces them into +existing code, or replaces the functionality in existing code +with them. This makes sense when maximizing code reuse and +minimizing maintenance costs is a goal. There may be a specific +need for functionality or the component writer may be starting +from scratch. The calendar management utility is a popular +place to start. + +
+ +
+The following is a typical set of steps involved in adopting +the ESMF superstructure. The first two tasks, which occur +before an ESMF call is ever made, have the potential to be +the most difficult and time-consuming. They are the work +of splitting an application into components and ensuring that +each component has well-defined stages of execution. ESMF +aside, this sort of code structure helps to promote application +clarity and maintainability, and the effort put into it is likely +to be a good investment. + +
+ +
+
+
+
+
+
+
+
+ +
+ +
+All ESMF methods pass a return code back to the caller via the rc +argument. If no errors are encountered during the method execution, a +value of ESMF_SUCCESS is returned. Otherwise one of the predefined +error codes is returned to the caller. See the appendix, section +56, for a full list of the ESMF error return codes. + +
+Any code calling an ESMF method must check the return code. If rc is not +equal to ESMF_SUCCESS, the calling code is expected to break out of its +execution and pass the rc to the next level up. All ESMF errors are to be +handled as fatal, i.e. the calling code must bail-on-all-errors. + +
+ESMF provides a number of methods, described under section 49, +that make implementation of the bail-on-all-errors stategy more convenient. +Consistent use of these methods will ensure that a full back trace is generated +in the ESMF log output whenever an error condition is triggered. + +
+Note that in ESMF requesting not present information, e.g. via a Get() +method, will trigger an error condition. Combined with the bail-on-all-errors +strategy this has the advantage of producing an error trace pointing to the +earliest location in the code that attempts to access unavailable information. +In cases where the calling side is able to handle the presence or absence of +certain pieces of of information, the code first must query for the resepctive +isPresent argument. If this argument comes back as .true. it is +safe to query for the actual information. + +
+ +
+ESMF data objects such as Fields are distributed over +DEs, with each DE getting a portion of the data. Depending +on the task, a local or global view of the object may be +preferable. In a local view, data indices start with the first +element on the DE and end with the last element on the same DE. +In a global view, there is an assumed or specified order to +the set of DEs over which the object is distributed. Data +indices start with the first element on the first DE, and +continue across all the elements in the sequence of DEs. +The last data index represents the number of elements in the +entire object. The DistGrid provides the mapping between +local and global data indices. + +
+The convention in ESMF is that entities with a global view +have no prefix. Entities with a DE-local (and in some cases, +PET-local) view have the prefix “local.” + +
+Just as data is distributed over DEs, DEs themselves can be +distributed over PETs. This is an advanced feature for users +who would like to create multiple local chunks of data, for +algorithmic or performance reasons. +Local DEs are those DEs that are located on the local PET. +Local DE labeling always starts at 0 and goes to localDeCount-1, +where localDeCount is the number of DEs on the local PET. +Global DE numbers also start at 0 and go to deCount-1. +The DELayout class provides the mapping between local +and global DE numbers. + +
+ +
+The basic rule of allocation and deallocation for the ESMF is: +whoever allocates it is responsible for deallocating it. + +
+ESMF methods that allocate their own space for data will +deallocate that space when the object is destroyed. +Methods which accept a user-allocated buffer, for example +ESMF_FieldCreate() with the ESMF_DATACOPY_REFERENCE flag, +will not deallocate that buffer at the time the object is +destroyed. The user must deallocate the buffer +when all use of it is complete. + +
+Classes such as Fields, FieldBundles, and States may have Arrays, +Fields, Grids and FieldBundles created externally and associated with +them. These associated items are not destroyed along with the rest +of the data object since it is possible for the items to be added +to more than one data object at a time (e.g. the same Grid could +be part of many Fields). It is the user's responsibility to delete +these items when the last use of them is done. + +
+ +
+Deep object copies are implemented as a special variant of the +ESMF_<Class>Create() methods. It takes an existing deep object as +one of the required arguments. At this point not all deep classes have +ESMF_<Class>Create() methods that allow object copy. + +
+Due to the complexity of deep classes there are many aspects when comparing two +objects of the same class. ESMF provide ESMF_<Class>Match() methods, +which are functions that return a class specific match flag. At this point not +all deep classes have ESMF_<Class>Match() methods that allow deep object +comparison. + +
+ +
+Attributes are (name, value) pairs, where +the name is a character string and the value can be either a single +value or list of integer, real, double precision, +logical, or character values. +Attributes can be associated with Fields, FieldBundles, and States. +Mixed types are not allowed in a single attribute, and all attribute +names must be unique within a single object. Attributes are set +by name, and can be retrieved either directly by name or by querying +for a count of attributes and retrieving names and values +by index number. + +
+ +
+Named constants are used throughout ESMF to specify the values of many +arguments with multiple well defined values in a consistent way. These +constants are defined by a derived type that follows this pattern: + +
+
+ESMF_<CONSTANT_NAME>_Flag ++ +
+The values of the constant are then specified by this pattern: + +
+
+ESMF_<CONSTANT_NAME>_<VALUE1> +ESMF_<CONSTANT_NAME>_<VALUE2> +ESMF_<CONSTANT_NAME>_<VALUE3> +... ++ +
+A master list of all available constants can be found in section +54. + +
+ +
+ +
+
+
+ +
+ +
+
+The main product delivered by ESMF is the ESMF library that allows application +developers to write programs based on the ESMF API. In addition to the +programming library, ESMF distributions come with a small set of command line +tools (CLT) that are of general interest to the community. These CLTs utilize +the ESMF library to implement features such as printing general information +about the ESMF installation, or generating regrid weight files. The provided +ESMF CLTs are intended to be used as standard command line tools. + +
+The bundled ESMF CLTs are built and installed during the usual ESMF +installation process, which is described in detail in the ESMF User's Guide +section "Building and Installing the ESMF". After installation, the +CLTs will be located in the ESMF_APPSDIR directory, which can +be found as a Makefile variable in the esmf.mk file. The esmf.mk +file can be found in the ESMF_INSTALL_LIBDIR directory after a +successful installation. The ESMF User's Guide discusses the esmf.mk +mechanism to access the bundled CLTs in more detail in section +"Using Bundled ESMF Command Line Tools". + +
+The following sections provide in-depth documentation of the bundled ESMF
+CLTs. In addition, each tool supports the standard
+ --help
command line argument, providing a brief description of how
+to invoke the program.
+
+
+ +
+ +
+The ESMF_PrintInfo command line tool that prints basic information about the +ESMF installation to stdout. + +
+The command line tool usage is as follows: + +
+
+ESMF_PrintInfo [--help] + +where + --help prints a brief usage message ++` + +
+ +
+This section describes the offline regrid weight generation application provided by ESMF (for a description of ESMF regridding in general see Section 24.2). Regridding, also called remapping or interpolation, is the process of changing the grid that underlies data values while preserving qualities of the original data. Different kinds of transformations are appropriate for different problems. Regridding may be needed when communicating data between Earth system model components such as land and atmosphere, or between different data sets to support operations such as visualization. + +
+Regridding can be broken into two stages. The first stage is generation of an interpolation weight matrix that describes how points in +the source grid contribute to points in the destination grid. The second stage is the multiplication of values on the source grid by the +interpolation weight matrix to produce values on the destination grid. This is implemented as a parallel sparse matrix multiplication. + +
+There are two options for accessing ESMF regridding functionality: integrated and offline. Integrated regridding is a process whereby interpolation +weights are generated via subroutine calls during the execution of the user's code. The integrated regridding can also perform the parallel sparse +matrix multiplication. In other words, ESMF integrated regridding allows a user to perform the whole process of interpolation within their code. +For a further description of ESMF integrated regridding please see Section 26.3.25. +In contrast to integrated regridding, +offline regridding is a process whereby interpolation weights are generated by a separate ESMF command line tool, not within the user code. The ESMF offline +regridding tool also only generates the interpolation matrix, the user is responsible for reading in this matrix and doing the actual interpolation + (multiplication by the sparse matrix) in their code. The rest of this section further describes ESMF offline regridding. + +
+For a discussion of installing and accessing ESMF command line tools such as this one please see the beginning of this part of the reference manual (Section II) or for the quickest approach to just building and accessing the command line tools please refer to the "Building and using bundled ESMF Command Line Tools" Section in the ESMF User's Guide. + +
+This application requires the NetCDF library to read the grid files and to write out the weight files in NetCDF format. To compile ESMF with the NetCDF library, please refer to the "Third Party Libraries" Section in the ESMF User's Guide for more information. + +
+As described above, this tool reads in +two grid files and outputs weights for interpolation + between the two grids. The input and output files are all in NetCDF format. The grid files can be defined in five +different formats: the SCRIP format 12.8.1 as is used as an input to SCRIP [13], the CF convension single-tile grid file 12.8.3 following the +CF metadata conventions, the GRIDSPEC Mosaic file 12.8.5 following the proposed GRIDSPEC standard, +the ESMF unstructured grid format 12.8.2 or the proposed CF unstructured grid data model (UGRID) 12.8.4. GRIDSPEC is a proposed CF extension for the annotation of complex Earth system grids. In the latest ESMF library, we added support for multi-tile GRIDSPEC Mosaic file with non-overlapping tiles. For UGRID, we support the 2D flexible mesh topology with mixed triangles and quadrilaterals and fully 3D unstructured mesh topology with hexahedrons and tetrahedrons. + +
+The ESMF_RegridWeightGen command line tool can detect the type of the input grid files automatically, so the specification of source and destination grid file type arguments is optional. However, these arguments (-t, --
src_type or --
dst_type) can be provided to override the auto-detection. If not explicitly specified, the rule to determine the file format is the following:
+
+
+ +
+This command line tool can do regrid weight generation from a global or regional source grid to a global or regional destination grid. +As is true with many global models, this application currently assumes the latitude and longitude values refer to positions on a perfect sphere, as opposed to a more complex and accurate representation of the Earth's true shape such as would be used in a GIS system. (ESMF's current user base doesn't require this level of detail in representing the Earth's shape, but it could be added in the future if necessary.) + +
+The interpolation weights generated by this application are output to a NetCDF file (specified by the "-w" or "--
weight"
+keywords). Two type of weight files are supported: the SCRIP format is the same as that generated by SCRIP, see Section 12.9 for a description of the format; and a simple weight file containing only the weights and the source and destination grid indices (In ESMF
+term, these are the factorList and factorIndexList generated by the ESMF weight calculation function ESMF_FieldRegridStore().
+Note that the sequence of the weights in the file can
+vary with the number of processors used to run the application. This means that two weight files generated by using different
+numbers of processors can contain exactly the same interpolation matrix, but can appear different in a direct line by line
+comparison (such as would be done by ncdiff). The interpolation weights can be generated with
+the bilinear, patch, nearest neighbor, first-order conservative, or second-order conservative methods described in Section 12.3.
+
+
+Internally this application uses the ESMF public API to generate the interpolation weights. +If a source or destination grid is a single tile logically rectangular grid, then ESMF_GridCreate() + 31.3.8 +is used to create an ESMF_Grid object. The cell center +coordinates of the input grid are put into the center stagger location (ESMF_STAGGERLOC_CENTER). +In addition, the corner coordinates are also put into the corner stagger location +(ESMF_STAGGERLOC_CORNER) for conservative regridding. If a grid contains multiple logically rectangular tiles +connected with each other by edges, such as a Cubed Sphere grid, the grid can be represented as a multi-tile ESMF_Grid object created +using ESMF_GridCreateMosaic() 31.3.12. Such a grid is stored in the GRIDSPEC Mosaic and tile file format. 12.8.5 +The method ESMF_MeshCreate() 33.3.8 +is used to create an ESMF_Mesh object, if the +source or destination grid is an unstructured grid. When making this call, +the flag convert3D is set to TRUE to convert the 2D coordinates into 3D Cartesian coordinates. +Internally ESMF_FieldRegridStore() is used to generate the weight table and indices table representing the interpolation matrix. + +
+ +
+The offline regrid weight generation application supports most of the options available in the rest of the ESMF regrid system. The following is a description of these options as relevant to the application. For a more in-depth description see Section 24.2. + +
+ +
+ +
--
src_missingvalue" or
+"--
dst_missingvalue" for users to specify the variable name from where the mask can be
+constructed.
+
++ +
--
extrap_method" flag. For the inverse distance weighted average method (nearestidavg),
+the number of source locations is specified using the "--
extrap_num_src_pnts" flag, and the distance exponent is specified using
+the "--
extrap_dist_exponent" flag. For the creep fill method (creep), the number of creep levels is specified using the "--
extrap_num_levels" flag.
+
++ +
--
ignore_unmapped " the user can cause the application to ignore unmapped destination points. In this case, the output matrix won't contain entries for the unmapped destination points. Note that the unmapped point detection doesn't
+currently work for nearest destination to source method ("-m nearestdtos"), so when using that method it is as if “-i” is always on.
+
++ +
--
line_type" or “-l” flag. This switch allows the user to select the path of the line which connects
+two points on a sphere surface. This in turn controls the path along which distances are calculated and the shape of
+the edges that make up a cell. Both of these quantities can influence how interpolation weights are calculated, for example in
+bilinear interpolation the distances are used to calculate the weights and the cell edges are used to determine to which source
+cell a destination point should be mapped.
+
++ESMF currently supports two line types: “cartesian” and “greatcircle”. The “cartesian” option +specifies that the line between two points follows a straight path through the 3D Cartesian space in which the sphere is embedded. +Distances are measured along this 3D Cartesian line. Under this option cells are approximated by planes in 3D space, and their boundaries are +3D Cartesian lines between their corner points. The “greatcircle” option specifies that the line between two points follows +a great circle path along the sphere surface. (A great circle is the shortest path between two points on a sphere.) +Distances are measured along the great circle path. Under this option cells are on the sphere surface, and their boundaries +are great circle paths between their corner points. + +
+ +
+ +
+ +
+The patch interpolation process works as follows. +For each source element containing a destination point +we construct a patch for each corner node that makes up the element (e.g. 4 patches for +quadrilateral elements, 3 for triangular elements). To construct a polynomial patch for +a corner node we gather all the elements around that node. +(Note that this means that the patch interpolation weights depends on the source +element's nodes, and the nodes of all elements neighboring the source element.) +We then use a least squares fitting algorithm to choose the set of coefficients +for the polynomial that produces the best fit for the data in the elements. +This polynomial will give a value at the destination point that fits the source data +in the elements surrounding the corner node. We then repeat this process for each +corner node of the source element generating a new polynomial for each set of elements. +To calculate the value at the destination point we do a weighted average of the values +of each of the corner polynomials evaluated at that point. The weight for a corner's +polynomial is the bilinear weight of the destination point with regard to that corner. + +
+The patch method has a larger stencil than the bilinear, for this reason the patch weight matrix can be correspondingly larger +than the bilinear matrix (e.g. for a quadrilateral grid the patch matrix is around 4x the size of + the bilinear matrix). This can be an issue when performing a regrid weight generation operation close to the memory +limit on a machine. + +
+The patch method does not guarantee that after regridding the range of values in the destination field is within the range of +values in the source field. For example, if the mininum value in the source field is 0.0, then it's possible that after regridding with the +patch method, the destination field will contain values less than 0.0. + +
+This method currently doesn't support self-intersecting cells (e.g. a cell twisted into a bow tie) in the source grid. + +
+ +
+ +
+By default (or if "--
norm_type dstarea"), the weight for a particular source cell and destination cell are calculated as
+.
+In this equation is the fraction of the source cell contributing to destination cell , and and are the areas of the source and
+destination cells. If "--
norm_type fracarea", then the weights are further divided by the destination fraction. In other words, in that case
+ where is fraction of the destination cell that intersects the unmasked source grid.
+
+
+To see a description of how the different normalization options affect the values and integrals produced by the conservative methods see section 12.5. For a grid on a sphere this method uses great circle cells, for a description of potential problems with these see 24.2.9. + +
+ +
+The weights for second-order are calculated in a similar manner to first-order 12.3.4 with additional weights that take into account the gradient across the source cell. + +
+To see a description of how the different normalization options affect the values and integrals produced by the conservative methods see section 12.5. For a grid on a sphere this method uses great circle cells, for a description of potential problems with these see 24.2.9. + +
+ +
+There are a couple of options for how the areas (A) in the proceding equation can be calculated. By default, ESMF calculates the areas. For a grid on a sphere,
+areas are calculated by connecting the corner coordinates of each grid cell (obtained from the grid file) with great circles. For a Cartesian grid, areas are calculated
+in the typcial manner for 2D polygons. If the user specifies the user area's option ("--
user_areas"), then weights will be adjusted so that the equation above
+will hold for the areas provided in the grid files. In either case, the areas output to the weight file are the ones for which the weights have been adjusted to conserve.
+
+
+ +
--
norm_type fracarea” on the command line.
+
+
+For weights generated using destination area normalization (either by not specifying any normalization type or by specifying "--
norm_type dstarea"),
+the following pseudo-code shows how to adjust a destination field (dst_field) by the destination fraction (dst_frac) called frac_b in the weight file:
+
+
+
+ for each destination element i + if (dst_frac(i) not equal to 0.0) then + dst_field(i)=dst_field(i)/dst_frac(i) + end if + end for ++ +
+For weights generated using destination area normalization (either by not specifying any normalization type or by specifying "--
norm_type dstarea"),
+the following pseudo-code shows how to compute the total destination integral (dst_total) given the destination field values (dst_field) resulting
+from the sparse matrix multiplication of the weights in the weight file by the source field, the destination area (dst_area) called area_b in the
+weight file, and the destination fraction (dst_frac) called frac_b in the weight file. As in the previous paragraph, it also
+shows how to adjust the destination field (dst_field) resulting from the sparse matrix multiplication by the fraction
+(dst_frac) called frac_b in the weight file:
+
+
+
+ dst_total=0.0 + for each destination element i + if (dst_frac(i) not equal to 0.0) then + dst_total=dst_total+dst_field(i)*dst_area(i) + dst_field(i)=dst_field(i)/dst_frac(i) + ! If mass computed here after dst_field adjust, would need to be: + ! dst_total=dst_total+dst_field(i)*dst_area(i)*dst_frac(i) + end if + end for ++ +
+For weights generated using fraction area normalization (set by specifying "--
norm_type fracarea"), no adjustment of the destination field (dst_field) by the destination fraction is necessary. The following pseudo-code shows how to compute the total destination integral (dst_total) given the destination field values (dst_field) resulting
+ from the sparse matrix multiplication of the weights in the weight file by the source field, the destination area (dst_area) called area_b in the
+weight file, and the destination fraction (dst_frac) called frac_b in the weight file:
+
+
+
+ dst_total=0.0 + for each destination element i + dst_total=dst_total+dst_field(i)*dst_area(i)*dst_frac(i) + end for ++ +
+For either normalization type, the following pseudo-code shows how to compute the total source integral (src_total) given the source field values (src_field), the source area (src_area) called area_a in the weight file, and the source fraction (src_frac) called frac_a in the weight file: + +
+
+ src_total=0.0 + for each source element i + src_total=src_total+src_field(i)*src_area(i)*src_frac(i) + end for ++ +
+ +
+The command line arguments are all keyword based. Both the long keyword prefixed with '--'
or the
+one character short keyword prefixed with '-' are supported. The format to run the application is
+as follows:
+
+
+
+ESMF_RegridWeightGen + --source|-s src_grid_filename + --destination|-d dst_grid_filename + --weight|-w out_weight_file + [--method|-m bilinear|patch|nearestdtos|neareststod|conserve|conserve2nd] + [--pole|-p none|all|teeth|1|2|..] + [--line_type|-l cartesian|greatcircle] + [--norm_type dstarea|fracarea] + [--extrap_method none|neareststod|nearestidavg|nearestd|creep|creepnrstd] + [--extrap_num_src_pnts <N>] + [--extrap_dist_exponent <P>] + [--extrap_num_levels <L>] + [--ignore_unmapped|-i] + [--ignore_degenerate] + [--src_type SCRIP|ESMFMESH|UGRID|CFGRID|GRIDSPEC|MOSAIC|TILE] + [--dst_type SCRIP|ESMFMESH|UGRID|CFGRID|GRIDSPEC|MOSAIC|TILE] + [-t SCRIP|ESMFMESH|UGRID|CFGRID|GRIDSPEC|MOSAIC|TILE] + [-r] + [--src_regional] + [--dst_regional] + [--64bit_offset] + [--netcdf4] + [--src_missingvalue var_name] + [--dst_missingvalue var_name] + [--src_coordinates lon_name,lat_name] + [--dst_coordinates lon_name,var_name] + [--tilefile_path filepath] + [--src_loc center|corner] + [--dst_loc center|corner] + [--user_areas] + [--weight_only] + [--check] + [--checkFlag] + [--no_log] + [--help] + [--version] + [-V] + +where: + --source or -s - a required argument specifying the source grid + file name + + --destination or -d - a required argument specifying the destination + grid file name + + --weight or -w - a required argument specifying the output regridding + weight file name + + --method or -m - an optional argument specifying which interpolation + method is used. The value can be one of the following: + + bilinear - for bilinear interpolation, also the + default method if not specified. + patch - for patch recovery interpolation + neareststod - for nearest source to destination interpolation + nearestdtos - for nearest destination to source interpolation + conserve - for first-order conservative interpolation + conserve2nd - for second-order conservative interpolation + + --pole or -p - an optional argument indicating how to extrapolate + in the pole region. + The value can be one of the following: + + none - No pole, the source grid ends at the top + (and bottom) row of nodes specified in + <source grid>. + all - Construct an artificial pole placed in the + center of the top (or bottom) row of nodes, + but projected onto the sphere formed by the + rest of the grid. The value at this pole is + the average of all the pole values. This + is the default option. + + teeth - No new pole point is constructed, instead + the holes at the poles are filled by + constructing triangles across the top and + bottom row of the source Grid. This can be + useful because no averaging occurs, however, + because the top and bottom of the sphere are + now flat, for a big enough mismatch between + the size of the destination and source pole + regions, some destination points may still + not be able to be mapped to the source Grid. + + <N> - Construct an artificial pole placed in the + center of the top (or bottom) row of nodes, + but projected onto the sphere formed by the + rest of the grid. The value at this pole is + the average of the N source nodes next to + the pole and surrounding the destination + point (i.e. the value may differ for each + destination point. Here N ranges from 1 to + the number of nodes around the pole. + + --line_type + or + -l - an optional argument indicating the type of path + lines (e.g. cell edges) follow on a spherical + surface. The default value depends on the regrid + method. For non-conservative methods the default is + cartesian. For conservative methods the default is + greatcircle. + + --norm_type - an optional argument indicating the type of normal- + ization to do when generating conservative weights. + The default value is dstarea. + + --extrap_method - an optional argument specifying which extrapolation + method is used to handle unmapped destination locations. + The value can be one of the following: + + none - no extrapolation method should be used. + This is the default. + + neareststod - nearest source to destination. Each + unmapped destination location is mapped + to the closest source location. This + extrapolation method is not supported with + conservative regrid methods (e.g. conserve). + + nearestidavg - inverse distance weighted average. + The value of each unmapped destination location + is the weighted average of the closest N + source locations. The weight is the reciprocal + of the distance of the source from the destination + raised to a power P. All the weights contributing + to one destination point are normalized so that + they sum to 1.0. The user can choose N and P by + using --extrap_num_src_pnts and + --extrap_dist_exponent, but defaults are + also provided. This extrapolation method is not + supported with conservative regrid methods + (e.g. conserve). + + nearestd - nearest mapped destination to + unmapped destination. Each + unmapped destination location is mapped + to the closest mapped destination location. This + extrapolation method is not supported with + conservative regrid methods (e.g. conserve). + + creep - creep fill. + Here unmapped destination points are filled by + moving values from mapped locations to neighboring + unmapped locations. The value filled into a + new location is the average of its already filled + neighbors' values. This process is repeated for + the number of levels indicated by the + --extrap_num_levels flag. This extrapolation + method is not supported with conservative + regrid methods (e.g. conserve). + + creepnrstd - creep fill with nearest destination. + Here unmapped destination points are filled by + first doing a creep fill, and then filling the + remaining unmapped points by using + the nearest destination method (both of these + methods are described in the entries above). + This extrapolation method is not supported + with conservative regrid methods (e.g. conserve). + + + --extrap_num_src_pnts - an optional argument specifying how many source points + should be used when the extrapolation method is + nearestidavg. If not specified, the default is 8. + + --extrap_dist_exponent - an optional argument specifying the exponent that + the distance should be raised to when the + extrapolation method is nearestidavg. If not specified, + the default is 2.0. + + --extrap_num_levels - an optional argument specifying how many levels should + be filled for level based extrapolation methods (e.g. creep). + + --ignore_unmapped + or + -i - ignore unmapped destination points. If not specified + the default is to stop with an error if an unmapped + point is found. + + --ignore_degenerate - ignore degenerate cells in the input grids. If not specified + the default is to stop with an error if an degenerate + cell is found. + + --src_type - an optional argument specifying the source grid file type. + The value can be one of SCRIP, ESMFMESH, UGRID, CFGRID, GRIDSPEC, MOSAIC or TILE. + If neither --src_type nor -t is given, the source grid file type will be + determined automatically. (Usually it is unnecessary to provide --src_type, + but it can be specified when the automatic file type determination fails.) + + --dst_type - an optional argument specifying the destination grid file type. + The value can be one of SCRIP, ESMFMESH, UGRID, CFGRID, GRIDSPEC, MOSAIC or TILE. + If neither --dst_type nor -t is given, the destination grid file type will be + determined automatically. (Usually it is unnecessary to provide --dst_type, + but it can be specified when the automatic file type determination fails.) + + -t - an optional argument specifying the file types for both the source + and the destination grid files. + The value can be one of SCRIP, ESMFMESH, UGRID, CFGRID, GRIDSPEC, MOSAIC or TILE. + If -t is given, then neither --src_type nor --dst_type can be given. + + -r - an optional argument specifying that the source and + destination grids are regional grids. If the argument + is not given, the grids are assumed to be global. + + --src_regional - an optional argument specifying that the source is + a regional grid and the destination is a global grid. + + --dst_regional - an optional argument specifying that the destination + is a regional grid and the source is a global grid. + + --64bit_offset - an optional argument specifying that the weight file + will be created in the NetCDF 64-bit offset format + to allow variables larger than 2GB. Note the 64-bit + offset format is not supported in the NetCDF version + earlier than 3.6.0. An error message will be generated + if this flag is specified while the application is + linked with a NetCDF library earlier than 3.6.0. + + --netcdf4 - an optional argument specifying that the output weight + will be created in the NetCDF4 format. This option + only works with NetCDF library version 4.1 and above + that was compiled with the NetCDF4 file format enabled + (with HDF5 compression). An error message will be + generated if these conditions are not met. + + --src_missingvalue - an optional argument that defines the variable name + in the source grid file if the file type is either CF Convension + single-tile or UGRID. The regridder will generate a mask using + the missing values of the data variable. The missing + value is defined using an attribute called "_FillValue" + or "missing_value". + --dst_missingvalue - an optional argument that defines the variable name + in the destination grid file if the file type is + CF Convension single-tile or UGRID. The regridder will generate a mask using + the missing values of the data variable. The missing + value is defined using an attribute called "_FillValue" + or "missing_value" + + --src_coordinates - an optional argument that defines the longitude and + latitude variable names in the source grid file if + the file type is CF Convension single-tile. The variable names are + separated by comma. This argument is required in case + there are multiple sets of coordinate variables defined + in the file. Without this argument, the offline regrid + application will terminate with an error message when + multiple coordinate variables are found in the file. + + --dst_coordinates - an optional argument that defines the longitude and + latitude variable names in the destination grid file + if the file type is CF Convension single-tile. The variable names are + separated by comma. This argument is required in case + there are multiple sets of coordinate variables defined + in the file. Without this argument, the offline regrid + application will terminate with an error message when + multiple coordinate variables are found in the file. + + --tilefile_path - the alternative file path for the tile files when either the source + or the destination grid is a GRIDSPEC Mosaic grid. The path can + be either relative or absolute. If it is relative, it is relative + to the working directory. When specified, the gridlocation variable + defined in the Mosaic file will be ignored. + + --src_loc - an optional argument indicating which part of a source + grid cell to use for regridding. Currently, this flag is + only required for non-conservative regridding when the + source grid is an unstructured grid in ESMF or UGRID format. + For all other cases, only the center location is supported. + The value can be one of the following: + + center - Regrid using the center location of each grid cell. + + corner - Regrid using the corner location of each grid cell. + + --dst_loc - an optional argument indicating which part of a destination + grid cell to use for regridding. Currently, this flag is + only required for non-conservative regridding when the + destination grid is an unstructured grid in ESMF or UGRID format. + For all other cases, only the center location is supported. + The value can be one of the following: + + center - Regrid using the center location of each grid cell. + + corner - Regrid using the corner location of each grid cell. + + + --user_areas - an optional argument specifying that the conservation + is adjusted to hold for the user areas provided in + the grid files. If not specified, then the + conservation will hold for the ESMF calculated + (great circle) areas. + Whichever areas the conservation holds for are output + to the weight file. + + --weight_only - an optional argument specifying that the output weight file only + contains the weights and the source and destination grid's indices. + + --check - Check that the generated weights produce reasonable + regridded fields. This is done by calling ESMF_Regrid() + on an analytic source field using the weights generated + by this application. The mean relative error between + the destination and analytic field is computed, as well + as the relative error between the mass of the source and + destination fields in the conservative case. + + --checkFlag - Turn on more expensive extra error checking during + weight generation. + + --no_log - Turn off the ESMF Log files. By default, ESMF creates + multiple log files, one per PET. + + --help - Print the usage message and exit. + + --version - Print ESMF version and license information and exit. + + -V - Print ESMF version number and exit. ++ +
+ +
+The example below shows the command to generate a set of conservative interpolation weights between a global +SCRIP format source grid file (src.nc) and a global SCRIP format destination grid file (dst.nc). The weights +are written into file w.nc. In this case the +ESMF library and applications have been compiled using an MPI parallel communication library +(e.g. setting ESMF_COMM to openmpi) to enable it to run in parallel. To demonstrate running in parallel +the mpirun script is used to run the application in parallel on 4 processors. + +
+
+ mpirun -np 4 ./ESMF_RegridWeightGen -s src.nc -d dst.nc -m conserve -w w.nc ++ +
+The next example below shows the command to do the same thing as the previous example except for three changes. The first
+change is this time the source grid is regional ("--
src_regional"). The second change is that
+for this example bilinear interpolation ("-m bilinear") is being used. Because bilinear is the default, we could also
+omit the "-m bilinear". The third change is that in this example some of the destination points are expected to
+not be found in the source grid, but the user is ok with that and just wants those points to not appear in the weight file instead of causing an error ("-i").
+
+
+
+ mpirun -np 4 ./ESMF_RegridWeightGen -i --src_regional -s src.nc -d dst.nc \ + -m bilinear -w w.nc ++ +
+The last example shows how to use the missing values of a data variable to generate the
+grid mask for a CF Convension single-tile file, how to specify the coordinate variable names
+using "--
src_coordinates"
+ and use user defined area for the conservative regridding.
+
+
+
+ mpirun -np 4 ./ESMF_RegridWeightGen -s src.nc -d dst.nc -m conserve \ + -w w.nc --src_missingvalue datavar \ + --src_coordinates lon,lat --user_areas ++ +
+In the above example, "datavar" is the variable name defined in the source grid that will + be used to construct the mask using its missing values. In addition, "lon" and "lat" are the +variable names for the longitude and latitude values, respectively. + +
+ +
+This section describes the grid file formats supported by ESMF. These are typically used either to describe grids to ESMF_RegridWeightGen or to create grids within ESMF. The following table summarizes the +features supported by each of the grid file formats. + +
+
Feature | +SCRIP | +ESMF Unstruct. | +CF Grid | +UGRID | +GRIDSPEC Mosaic | +
Create an unstructured Mesh | +YES | +YES | +NO | +YES | +NO | +
Create a logically-rectangular Grid | +YES | +NO | +YES | +NO | +YES | +
Create a multi-tile Grid | +NO | +NO | +NO | +NO | +YES | +
2D | +YES | +YES | +YES | +YES | +YES | +
3D | +NO | +YES | +NO | +YES | +NO | +
Spherical coordinates | +YES | +YES | +YES | +YES | +YES | +
Cartesian coordinates | +NO | +YES | +NO | +NO | +NO | +
Non-conserv regrid on corners | +NO | +YES | +NO | +YES | +YES | +
+The rest of this section contains a detailed descriptions of each grid file format along with a simple example of the format. + +
+ +
+A SCRIP format grid file is a NetCDF file for describing grids. This format is the same as is used by the SCRIP [13] +package, and so grid files which work with that package should also work here. +When using the ESMF API, the file format flag ESMF_FILEFORMAT_SCRIP can be used to indicate a file in this format. + +
+SCRIP format files are capable of storing either 2D logically rectangular +grids or 2D unstructured grids. The basic format for both of these grids is the same and they are distinguished by the +value of the grid_rank variable. Logically rectangular grids have grid_rank set to 2, +whereas unstructured grids have this variable set to 1. + +
+The following is a sample header of a logically rectangular grid file: + +
+
+netcdf remap_grid_T42 { +dimensions: + grid_size = 8192 ; + grid_corners = 4 ; + grid_rank = 2 ; + +variables: + int grid_dims(grid_rank) ; + double grid_center_lat(grid_size) ; + grid_center_lat:units = "radians"; + double grid_center_lon(grid_size) ; + grid_center_lon:units = "radians" ; + int grid_imask(grid_size) ; + grid_imask:units = "unitless" ; + double grid_corner_lat(grid_size, grid_corners) ; + grid_corner_lat:units = "radians" ; + double grid_corner_lon(grid_size, grid_corners) ; + grid_corner_lon:units ="radians" ; + +// global attributes: + :title = "T42 Gaussian Grid" ; +} ++ +
+The grid_size dimension is the total number of cells in the grid; grid_rank refers to the +number of dimensions. In this case grid_rank is 2 for a 2D logically rectangular grid. +The integer array grid_dims gives the number of grid cells along each dimension. +The number of corners (vertices) in each grid cell is given by grid_corners. +The grid corner coordinates need to be listed in an order such that the corners are in counterclockwise +order. Also, note that if your grid has a variable number of corners on grid cells, then +you should set grid_corners to be the highest value and use redundant points +on cells with fewer corners. + +
+The integer array grid_imask is used to mask out grid cells which should +not participate in the regridding. The array values should be zero for any points +that do not participate in the regridding and one for all other points. +Coordinate arrays provide the latitudes and longitudes of cell centers +and cell corners. The unit of the coordinates can be either "radians" or "degrees". + +
+Here is a sample header from a SCRIP unstructured grid file: + +
+
+netcdf ne4np4-pentagons { +dimensions: + grid_size = 866 ; + grid_corners = 5 ; + grid_rank = 1 ; +variables: + int grid_dims(grid_rank) ; + double grid_center_lat(grid_size) ; + grid_center_lat:units = "degrees" ; + double grid_center_lon(grid_size) ; + grid_center_lon:units = "degrees" ; + double grid_corner_lon(grid_size, grid_corners) ; + grid_corner_lon:units = "degrees"; + grid_corner_lon:_FillValue = -9999. ; + double grid_corner_lat(grid_size, grid_corners) ; + grid_corner_lat:units = "degrees" ; + grid_corner_lat:_FillValue = -9999. ; + int grid_imask(grid_size) ; + grid_imask:_FillValue = -9999. ; + double grid_area(grid_size) ; + grid_area:units = "radians^2" ; + grid_area:long_name = "area weights" ; +} ++ +
+The variables are the same as described above, however, here grid_rank = 1. In this format there +is no notion of which cells are next to which, so to construct the unstructured mesh the connection between +cells is defined by searching for cells with the same corner coordinates. (e.g. the same grid_corner_lat +and grid_corner_lon values). + +
+Both the SCRIP grid file format and the SCRIP weight file format work with the SCRIP 1.4 tools. + +
+ +
+ESMF supports a custom unstructured grid file format for describing meshes. This format is more compatible than the SCRIP format with the methods used to create an ESMF Mesh object, so less conversion needs to be done to create a Mesh. The ESMF format is thus more efficient than SCRIP when used with ESMF codes (e.g. the ESMF_RegridWeightGen application). When using the ESMF API, the file format flag ESMF_FILEFORMAT_ESMFMESH can be used to indicate a file in this format. + +
+The following is a sample header in the ESMF format followed by a description: + +
+
+netcdf mesh-esmf { +dimensions: + nodeCount = 9 ; + elementCount = 5 ; + maxNodePElement = 4 ; + coordDim = 2 ; +variables: + double nodeCoords(nodeCount, coordDim); + nodeCoords:units = "degrees" ; + int elementConn(elementCount, maxNodePElement) ; + elementConn:long_name = "Node Indices that define the element / + connectivity"; + elementConn:_FillValue = -1 ; + elementConn:start_index = 1 ; + byte numElementConn(elementCount) ; + numElementConn:long_name = "Number of nodes per element" ; + double centerCoords(elementCount, coordDim) ; + centerCoords:units = "degrees" ; + double elementArea(elementCount) ; + elementArea:units = "radians^2" ; + elementArea:long_name = "area weights" ; + int elementMask(elementCount) ; + elementMask:_FillValue = -9999. ; +// global attributes: + :gridType="unstructured"; + :version = "0.9" ; ++ +
+In the ESMF format the NetCDF dimensions have the following meanings. The nodeCount dimension is the number of nodes in the mesh. + The elementCount dimension is the number of elements in the mesh. The maxNodePElement dimension is the maximum number + of nodes in any element in the mesh. For example, in a mesh containing just triangles, then maxNodePElement would be 3. However, + if the mesh contained one quadrilateral then maxNodePElement would need to be 4. The coordDim dimension is the number of dimensions + of the points making up the mesh (i.e. the spatial dimension of the mesh). For example, a 2D planar mesh would have coordDim equal to 2. + +
+In the ESMF format the NetCDF variables have the following meanings. The nodeCoords variable contains the coordinates for each node. + nodeCoords is a two-dimensional array of dimension (nodeCount,coordDim). + For a 2D Grid, coordDim is 2 and the grid can be either spherical or Cartesian. If the units + attribute is either degrees or radians, it is spherical. nodeCoords(:,1) contains +the longitude coordinates and nodeCoords(:,2) contains the latitude coordinates. If the value of +the units attribute is km, kilometers or meters, the grid is in 2D Cartesian +coordinates. nodeCoords(:,1) contains the x coordinates and + nodeCoords(:,2) contains the y coordinates. + The same order applies to centerCoords. + For a 3D Grid, coordDim is 3 and the grid is assumed to be Cartesian. nodeCoords(:,1) contains the x coordinates, nodeCoords(:,2) contains the y coordinates, + and nodeCoords(:,3) contains the z coordinates. The same order applies to centerCoords. +A 2D grid in the Cartesian coordinate can only be regridded into another 2D grid in the Cartesian coordinate. + +
+The elementConn variable describes how the nodes are connected together to form each element. For each element, this variable contains a list of indices into the nodeCoords variable pointing to the nodes which make up that + element. By default, the index is 1-based. It can be changed to 0-based by adding an attribute +start_index of value 0 to the elementConn variable. The order of the indices describing the element is important. + The proper order for elements available in an ESMF mesh can be found in Section 33.2.1. The file format does support 2D polygons with more + corners than those in that section, but internally these are broken into triangles. For these polygons, the corners should + be listed such that they are in counterclockwise order around the element. +elementConn can be either a 2D array or a 1D array. If it is a 2D array, the second + dimension of the elementConn variable has to be the size of the largest number of nodes in any element (i.e. maxNodePElement), the actual number of + nodes in an element is given by the numElementConn variable. For a given dimension (i.e. coordDim) the number of nodes in the element + indicates the element shape. For example in 2D, if numElementConn is 4 then the element is a quadrilateral. In 3D, if numElementConn is 8 + then the element is a hexahedron. + +
+If the grid contains some elements with large number of edges, using a 2D array for elementConn could take a lot of space. +In that case, elementConn can be represented as a 1D array that stores the edges of all the elements continuously. When elementConn is a 1D array, the dimension maxNodePElement is no longer needed, instead, a new dimension variable connectionCount +is required to define the size of elementConn. The value of connectionCount is the sum of all the values in numElementConn. + +
+The following is an example grid file using 1D array for elementConn: + +
+
+netcdf catchments_esmf1 { +dimensions: + nodeCount = 1824345 ; + elementCount = 68127 ; + connectionCount = 18567179 ; + coordDim = 2 ; +variables: + double nodeCoords(nodeCount, coordDim) ; + nodeCoords:units = “degrees” ; + double centerCoords(elementCount, coordDim) ; + centerCoords:units = “degrees” ; + int elementConn(connectionCount) ; + elementConn:polygon_break_value = -8 ; + elementConn:start_index = 0. ; + int numElementConn(elementCount) ; +} ++ +
+In some cases, one mesh element may contain multiple polygons and these polygons are separated by a special value defined in the attribute + polygon_break_value. + +
+The rest of the variables in the format are optional. The centerCoords variable gives the coordinates of the center of the corresponding element. + This variable is used by ESMF for non-conservative interpolation on the data field residing at the center of the elements. The elementArea variable gives the area (or volume in 3D) of the corresponding element. This + area is used by ESMF during conservative interpolation. If not specified, ESMF calculates the area (or volume) based on the coordinates of the nodes + making up the element. The final variable is the elementMask variable. This variable allows the user to specify a mask value for + the corresponding element. If the value is 1, then the element is unmasked and if the value is 0 the element is masked. + If not specified, ESMF assumes that no elements are masked. + +
+The following is a picture of a small example mesh and a sample ESMF format header using non-optional variables describing that mesh: + +
+
+ 2.0 7 ------- 8 ------- 9 + | | | + | 4 | 5 | + | | | + 1.0 4 ------- 5 ------- 6 + | | \ 3 | + | 1 | \ | + | | 2 \ | + 0.0 1 ------- 2 ------- 3 + + 0.0 1.0 2.0 + + Node indices at corners + Element indices in centers + +netcdf mesh-esmf { +dimensions: + nodeCount = 9 ; + elementCount = 5 ; + maxNodePElement = 4 ; + coordDim = 2 ; +variables: + double nodeCoords(nodeCount, coordDim); + nodeCoords:units = "degrees" ; + int elementConn(elementCount, maxNodePElement) ; + elementConn:long_name = "Node Indices that define the element / + connectivity"; + elementConn:_FillValue = -1 ; + byte numElementConn(elementCount) ; + numElementConn:long_name = "Number of nodes per element" ; +// global attributes: + :gridType="unstructured"; + :version = "0.9" ; +data: + nodeCoords= + 0.0, 0.0, + 1.0, 0.0, + 2.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, + 2.0, 1.0, + 0.0, 2.0, + 1.0, 2.0, + 2.0, 2.0 ; + + elementConn= + 1, 2, 5, 4, + 2, 3, 5, -1, + 3, 6, 5, -1, + 4, 5, 8, 7, + 5, 6, 9, 8 ; + + numElementConn= 4, 3, 3, 4, 4 ; +} ++ +
+ +
+ESMF_RegridWeightGen supports single tile logically rectangular lat/lon grid files that follow the NETCDF CF convention based on +CF Metadata Conventions V1.6. When using the ESMF API, the file format flag ESMF_FILEFORMAT_CFGRID (or its equivalent deprecated name, ESMF_FILEFORMAT_GRIDSPEC) can be used to indicate a file in this format. + +
+An example grid file is shown below.
+The cell center coordinate variables are determined by the value of its attribute units. The longitude
+variable has the attribute value set to either degrees_east, degree_east, degrees_E, degree_E,
+degreesE or degreeE. The latitude variable has the attribute value set to degrees_north, degree_north, degrees_N,
+degree_N, degreesN or degreeN. The latitude and the longitude variables are one-dimensional arrays if the grid is a regular lat/lon grid, two-dimensional arrays if the grid is curvilinear. The bound coordinate
+variables define the bound or the corner coordinates of a cell. The bound variable name is specified in the
+bounds attribute of the latitude and longitude variables. In the following example, the latitude bound
+variable is lat_bnds and the longitude bound variable is lon_bnds. The bound variables are 2D
+arrays for a regular lat/lon grid and a 3D array for a curvilinear grid. The first dimension of the bound
+array is 2 for a regular lat/lon grid and 4 for a curvilinear grid. The bound coordinates for a curvilinear
+grid are defined in counterclockwise order. Since the grid is a regular lat/lon grid,
+the coordinate variables are 1D and the bound variables are 2D with the first dimension equal to 2.
+The bound coordinates will be read in and stored in a ESMF Grid object as the corner stagger coordinates when doing a conservative regrid. In case there are multiple sets of coordinate variables defined in a grid file,
+the offline regrid application will return an error for duplicate latitude or longitude variables unless
+"--
src_coordinates"
+or "--
src_coordinates" options are used to specify the coordinate variable names
+to be used in the regrid.
+
+
+
+netcdf single_tile_grid { +dimensions: + time = 1 ; + bound = 2 ; + lat = 181 ; + lon = 360 ; +variables: + double lat(lat) ; + lat:bounds = "lat_bnds" ; + lat:units = "degrees_north" ; + lat:long_name = "latitude" ; + lat:standard_name = "latitude" ; + double lat_bnds(lat, bound) ; + double lon(lon) ; + lon:bounds = "lon_bnds" ; + lon:long_name = "longitude" ; + lon:standard_name = "longitude" ; + lon:units = "degrees_east" ; + double lon_bnds(lon, bound) ; + float so(time, lat, lon) ; + so:standard_name = "sea_water_salinity" ; + so:units = "psu" ; + so:missing_value = 1.e+20f ; +} ++ +
+2D Cartesian coordinates can be supplied in additional to the required
+longitude/latitude coordinates. They can be used in ESMF to create a grid and
+used in ESMF_RegridWeightGen. The Cartesian coordinate variables have to
+include an "axis" attribute with value "X" or "Y". The "units"
+attribute can be either "m" or "meters" for meters or "km" or "kilometers"
+for kilometers. When a grid with 2D Cartesian coordinates are used in
+ESMF_RegridWeightGen, the optional arguments "--
src_coordinates"
+or "--
src_coordinates" have to be used to specify the coordinate
+variable names. A grid with 2D Cartesian coordinates can only be regridded
+with another grid in 2D Cartesian coordinates. Internally in ESMF, the
+Cartesian coordinates are all converted into kilometers. Here is an example
+of the 2D Cartesian coordinates:
+
+
+
+ double xc(xc) ; + xc:long_name = "x-coordinate in Cartesian system" ; + xc:standard_name = "projection_x_coordinate" ; + xc:axis = "X" ; + xc:units = "m" ; + double yc(yc) ; + yc:long_name = "y-coordinate in Cartesian system" ; + yc:standard_name = "projection_y_coordinate" ; + yc:axis = "Y" ; + yc:units = "m" ; ++ +
+Since a CF convension tile file does not have a way to specify the grid mask, the mask is usually derived by the missing values stored in a data variable. ESMF_RegridWeightGen provides an option for users to +derive the grid mask from a data variable's missing values. The value of the missing value is defined by the +variable attribute missing_value or _FillValue. If the value of the data point is equal to the +missing value, the grid mask for that grid point is set to 0, otherwise, it is set to 1. In the following +grid, the variable so can be used to derive the grid mask. A data variable could be a 2D, 3D or 4D. +For example, it may have additional depth and time dimensions. +It is assumed that the first and the second dimensions of the data variable should be the longitude and the +latitude dimension. ESMF_RegridWeightGen will use the first 2D data values to derive the grid mask. + +
+ +
+ESMF_RegridWeightGen supports NetCDF files that follow the UGRID conventions for unstructured grids. + +
+The UGRID file format is a proposed extension to the CF metadata conventions for the unstructured grid data model. The latest proposal can be found at https://github.com/ugrid-conventions/ugrid-conventions. The proposal is still evolving, the Mesh creation API and ESMF_RegridWeightGen in the current ESMF release is based on UGRID Version 0.9.0 published on October 29, 2013. When using the ESMF API, the file format flag ESMF_FILEFORMAT_UGRID can be used to indicate a file in this format. + +
+In the UGRID proposal, a 1D, 2D, or 3D mesh topology can be defined for an unstructured grid. Currently, ESMF +supports two types of meshes: (1) the 2D flexible mesh topology where each cell (a.k.a. "face" as defined in the UGRID document) in the mesh is either a triangle or a quadrilateral, and (2) the fully 3D unstructured mesh topology where each cell (a.k.a. "volume" as defined in the UGRID document) in the mesh +is either a tetrahedron or a hexahedron. Pyramids and wedges are not currently supported in ESMF, but they +can be defined as degenerate hexahedrons. ESMF_RegridWeightGen also +supports UGRID 1D network mesh topology in a limited way: A 1D mesh in UGRID +can be used as the source grid for nearest neighbor regridding, and as the +destination grid for non-conservative regridding. + +
+The main addition of the UGRID extension is a dummy variable that defines the mesh +topology. This additional variable has a required attribute cf_role +with value "mesh_topology". In addition, it has two more required attributes: topology_dimension +and node_coordinates. If it is a 1D mesh, topology_dimension is +set to 1. +If it is a 2D mesh (i.e., topology_dimension equals to 2), an additional attribute +face_node_connectivity is required. If it is a 3D mesh (i.e., topology_dimension equals to 3), two additional attributes volume_node_connectivity and volume_shape_type are required. +The value of attribute node_coordinates is a list of the names of the node longitude and latitude variables, +plus the elevation variable if it is a 3D mesh. +The value of attribute face_node_connectivity or volume_node_connectivity is the variable name that defines the corner node indices for each mesh cell. The additional attribute volume_shape_type for the +3D mesh points to a flag variable that specifies the shape type of each cell in the mesh. + +
+Below is a sample 2D mesh called FVCOM_grid2d. The dummy mesh topology variable is fvcom_mesh. As described above, its cf_role attribute has to be mesh_topology +and the topology_dimension attribute has to be 2 for a 2D mesh. It defines +the node coordinate variable names to be lon and lat. It also specifies the face/node connectivity variable name as nv. + +
+The variable nv is a two-dimensional array that defines the node indices of each face. The first dimension +defines the maximal number of nodes for each face. In this example, it is a +triangle mesh so the number of nodes per face is 3. Since each face may have a different number of corner nodes, +some of the cells may have fewer nodes than the specified dimension. In that case, it is filled with the +missing values defined by the attribute _FillValue. If _FillValue is not defined, the default value +is -1. The nodes are in counterclockwise order. An optional attribute +start_index defines whether the node index is 1-based or 0-based. If start_index is not defined, +the default node index is 0-based. + +
+The coordinate variables follows the CF metadata convention for coordinates. They are 1D array with attribute +standard_name being either latitude or longitude. The units of the coordinates can be either degrees or radians. + +
+The UGRID files may also contain data variables. The data may be located at the nodes or at the faces. Two additional attributes are introduced in the UGRID extension for the data variables: location and mesh. The location +attribute defines where the data is located, it can be either face or node. The mesh attribute defines which mesh topology this variable belongs to since multiple mesh topologies may be defined in one +file. The coordinates attribute defined in the CF conventions can also be used to associate the variables to their locations. ESMF checks both location and coordinates attributes to determine where the data variable is defined upon. If both attributes are present, the location attribute takes the precedence. ESMF_RegridWeightGen uses the data variable on the face to derive the element masks for the mesh cell and variable on the node to derive the node masks for the mesh. + +
+When creating a ESMF Mesh from a UGRID file, the user has to provide the mesh topology variable name to ESMF_MeshCreate(). + +
+
+netcdf FVCOM_grid2d { +dimensions: + node = 417642 ; + nele = 826866 ; + three = 3 ; + time = 1 ; + +variables: +// Mesh topology + int fvcom_mesh; + fvcom_mesh:cf_role = "mesh_topology" ; + fvcom_mesh:topology_dimension = 2. ; + fvcom_mesh:node_coordinates = "lon lat" ; + fvcom_mesh:face_node_connectivity = "nv" ; + int nv(nele, three) ; + nv:standard_name = "face_node_connectivity" ; + nv:start_index = 1. ; + +// Mesh node coordinates + float lon(node) ; + lon:standard_name = "longitude" ; + lon:units = "degrees_east" ; + float lat(node) ; + lat:standard_name = "latitude" ; + lat:units = "degrees_north" ; + +// Data variable + float ua(time, nele) ; + ua:standard_name = "barotropic_eastward_sea_water_velocity" ; + ua:missing_value = -999. ; + ua:location = "face" ; + ua:mesh = "fvcom_mesh" ; + float va(time, nele) ; + va:standard_name = "barotropic_northward_sea_water_velocity" ; + va:missing_value = -999. ; + va:location = "face" ; + va:mesh = "fvcom_mesh" ; +} ++ +
+Following is a sample 3D UGRID file containing hexahedron cells. The dummy mesh topology variable is fvcom_mesh. Its cf_role attribute has to be mesh_topology +and topology_dimension attribute has to be 3 for a 3D mesh. There are two additional required attributes: +volume_node_connectivity specifies a variable name that defines the corner indices of the mesh cells and +volume_shape_type specifies a variable name that defines the type of the mesh cells. + +
+The node coordinates are defined by variables nodelon, nodelat and height. Currently, the units +attribute for the height variable is either kilometers, km or meters. +The variable vertids is a two-dimensional array that defines the corner node indices of each mesh cell. The first dimension +defines the maximal number of nodes for each cell. There is only one type of cells in the sample grid, i.e. hexahedrons, so the maximal number +of nodes is 8. The node order is defined in 33.2.1. The index can be either 1-based or 0-based and +the default is 0-based. + Setting an optional attribute start_index to 1 changed it to 1-based index scheme. +The variable meshtype is a one-dimensional integer array that defines the shape type of each cell. Currently, ESMF only +supports tetrahedron and hexahedron shapes. There are three attributes in meshtype: flag_range, flag_values, and flag_meanings representing the range of the flag values, all the possible flag values, and the meaning of each flag value, respectively. flag_range and flag_values are either a scalar or an array of integers. flag_meanings is a text string containing a list of shape types separated by space. In this example, there +is only one shape type, thus, the values of meshtype are all 1. + +
+
+netcdf wam_ugrid100_110 { +dimensions: + nnodes = 78432 ; + ncells = 66030 ; + eight = 8 ; +variables: + int mesh ; + mesh:cf_role = "mesh_topology" ; + mesh:topology_dimension = 3. ; + mesh:node_coordinates = "nodelon nodelat height" ; + mesh:volume_node_connectivity = "vertids" ; + mesh:volume_shape_type = "meshtype" ; + double nodelon(nnodes) ; + nodelon:standard_name = "longitude" ; + nodelon:units = "degrees_east" ; + double nodelat(nnodes) ; + nodelat:standard_name = "latitude" ; + nodelat:units = "degrees_north" ; + double height(nnodes) ; + height:standard_name = "elevation" ; + height:units = "kilometers" ; + int vertids(ncells, eight) ; + vertids:cf_role = "volume_node_connectivity" ; + vertids:start_index = 1. ; + int meshtype(ncells) ; + meshtype:cf_role = "volume_shape_type" ; + meshtype:flag_range = 1. ; + meshtype:flag_values = 1. ; + meshtype:flag_meanings = "hexahedron" ; +} ++ +
+ +
+GRIDSPEC is a draft proposal to extend the Climate and Forecast (CF) metadata conventions for the representation of gridded data for Earth System Models. The original GRIDSPEC standard was proposed by V. Balaji and Z. Liang of GFDL (see ref). GRIDSPEC extends the current CF convention to support grid mosaics, i.e., a grid consisting of multiple logically +rectangular grid tiles. It also provides a mechanism for storing a grid dataset in multiple files. Therefore, +it introduces different types of files, such as a mosaic file that defines the multiple tiles and their +connectivity, and a tile file for a single tile grid definition on a so-called "Supergrid" format. When using the ESMF API, the file format flag ESMF_FILEFORMAT_MOSAIC can be used to indicate a file in this format. + +
+Following is an example of a mosaic file that defines a 6 tile Cubed Sphere grid: + +
+
+netcdf C48_mosaic { +dimensions: + ntiles = 6 ; + ncontact = 12 ; + string = 255 ; +variables: + char mosaic(string) ; + mosaic:standard_name = "grid_mosaic_spec" ; + mosaic:children = "gridtiles" ; + mosaic:contact_regions = "contacts" ; + mosaic:grid_descriptor = "" ; + char gridlocation(string) ; + char gridfiles(ntiles, string) ; + char gridtiles(ntiles, string) ; + char contacts(ncontact, string) ; + contacts:standard_name = "grid_contact_spec" ; + contacts:contact_type = "boundary" ; + contacts:alignment = "true" ; + contacts:contact_index = "contact_index" ; + contacts:orientation = "orient" ; + char contact_index(ncontact, string) ; + contact_index:standard_name = "starting_ending_point_index_of_contact" ; + +data: + +mosaic = "C48_mosaic" ; + +gridlocation = "./data/" ; + +gridfiles = + "horizontal_grid.tile1.nc", + "horizontal_grid.tile2.nc", + "horizontal_grid.tile3.nc", + "horizontal_grid.tile4.nc", + "horizontal_grid.tile5.nc", + "horizontal_grid.tile6.nc" ; + +gridtiles = + "tile1", + "tile2", + "tile3", + "tile4", + "tile5", + "tile6" ; + +contacts = + "C48_mosaic:tile1::C48_mosaic:tile2", + "C48_mosaic:tile1::C48_mosaic:tile3", + "C48_mosaic:tile1::C48_mosaic:tile5", + "C48_mosaic:tile1::C48_mosaic:tile6", + "C48_mosaic:tile2::C48_mosaic:tile3", + "C48_mosaic:tile2::C48_mosaic:tile4", + "C48_mosaic:tile2::C48_mosaic:tile6", + "C48_mosaic:tile3::C48_mosaic:tile4", + "C48_mosaic:tile3::C48_mosaic:tile5", + "C48_mosaic:tile4::C48_mosaic:tile5", + "C48_mosaic:tile4::C48_mosaic:tile6", + "C48_mosaic:tile5::C48_mosaic:tile6" ; + + contact_index = + "96:96,1:96::1:1,1:96", + "1:96,96:96::1:1,96:1", + "1:1,1:96::96:1,96:96", + "1:96,1:1::1:96,96:96", + "1:96,96:96::1:96,1:1", + "96:96,1:96::96:1,1:1", + "1:96,1:1::96:96,96:1", + "96:96,1:96::1:1,1:96", + "1:96,96:96::1:1,96:1", + "1:96,96:96::1:96,1:1", + "96:96,1:96::96:1,1:1", + "96:96,1:96::1:1,1:96" ; +} ++ +
+A GRIDSPEC Mosaic file is identified by a dummy variable with its standard_name attribute set to grid_mosaic_spec. +The children attribute of this dummy variable provides the variable name that contains the tile names and the +contact_region attribute points to the variable name that defines a list of tile pairs that are connected +to each other. For a Cubed Sphere grid, there are six tiles and 12 connections. The contacts variable, the +variable that defines the contact_region +has three required attributes: standard_name, contact_type, and contact_index. startand_name +has to be set to grid_contact_spec. contact_type can be either boundary or overlap. Currently, ESMF +only supports non-overlapping tiles connected by boundary. contact_index defines the variable name that contains the information defining how the +two adjacent tiles are connected to each other. In the above example, the contact_index variable contains 12 entries. Each entry +contains the index of four points that defines the two edges that contact to + each other from the two neighboring tiles. Assuming the four points are A, B, C, and D. + A and B defines the edge of tile 1 and C and D defines the edge of tile 2. A is the same point + as C and B is the same as D. (Ai, Aj) is the index for point A. The entry looks like this: +
+ Ai:Bi,Aj:Bj::Ci:Di,Cj:Dj ++ +
+There are two fixed-name variables required in the mosaic file: variable gridfiles defines the associated tile file names and +variable gridlocation defines the directory path of the tile files. +The gridlocation can be overwritten with an command line argument -tilefile_path in ESMF_RegridWeightGen application. + +
+It is possible to define a single-tile Mosaic file. If there is only one tile in the Mosaic, the contact_region attribute in the +grid_mosaic_spec varilable will be ignored. + +
+Each tile in the Mosaic is a logically rectangular lat/lon grid and is defined in a separate file. The tile file used in the GRIDSPEC Mosaic file defines the coordinates of a so-called +supergrid. A supergrid contains all the +stagger locations in one grid. It contains the corner, edge and center coordinates all in one 2D array. +In this example, there are 48 elements in each side of a tile, therefore, the size of the supergrid is +48*2+1=97, i.e. 97x97. + +
+Here is the header of one of the tile files: + +
+
+netcdf horizontal_grid.tile1 { +dimensions: + string = 255 ; + nx = 96 ; + ny = 96 ; + nxp = 97 ; + nyp = 97 ; +variables: + char tile(string) ; + tile:standard_name = "grid_tile_spec" ; + tile:geometry = "spherical" ; + tile:north_pole = "0.0 90.0" ; + tile:projection = "cube_gnomonic" ; + tile:discretization = "logically_rectangular" ; + tile:conformal = "FALSE" ; + double x(nyp, nxp) ; + x:standard_name = "geographic_longitude" ; + x:units = "degree_east" ; + double y(nyp, nxp) ; + y:standard_name = "geographic_latitude" ; + y:units = "degree_north" ; + double dx(nyp, nx) ; + dx:standard_name = "grid_edge_x_distance" ; + dx:units = "meters" ; + double dy(ny, nxp) ; + dy:standard_name = "grid_edge_y_distance" ; + dy:units = "meters" ; + double area(ny, nx) ; + area:standard_name = "grid_cell_area" ; + area:units = "m2" ; + double angle_dx(nyp, nxp) ; + angle_dx:standard_name = "grid_vertex_x_angle_WRT_geographic_east" ; + angle_dx:units = "degrees_east" ; + double angle_dy(nyp, nxp) ; + angle_dy:standard_name = "grid_vertex_y_angle_WRT_geographic_north" ; + angle_dy:units = "degrees_north" ; + char arcx(string) ; + arcx:standard_name = "grid_edge_x_arc_type" ; + arcx:north_pole = "0.0 90.0" ; + +// global attributes: + :grid_version = "0.2" ; + :history = "/home/z1l/bin/tools_20091028/make_hgrid --grid_type gnomonic_ed --nlon 96" ; +} ++ +
+The tile file not only defines the coordinates at all staggers, it also has a complete specification of +distances, angles, and areas. In ESMF, we only use the geographic_longitude and geographic_latitude +variables and its subsets on the center and corner staggers. ESMF currently supports the Mosaic containing tiles of the same size. +A tile can be square or rectangular. For a cubed sphere grid, each tile is a square, i.e. the x and y +dimensions are the same. + +
+ +
+A regrid weight file is a NetCDF format file containing the information necessary to perform +a regridding between two grids. It also optionally contains information about the grids used to compute +the regridding. This information is provided to allow applications (e.g. ESMF_RegridWeightGenCheck) to +independently compute the accuracy of the regridding weights. In some cases, ESMF_RegridWeightGen doesn't +output the full grid information (e.g. when it's costly to compute, or when the current grid format doesn't +support the type of grids used to generate the weights). In that case, the weight file can still be used +for regridding, but applications which depend on the grid information may not work. + +
+The following is the header of a sample regridding weight file that describes a bilinear regridding +from a logically rectangular 2D grid to a triangular unstructured grid: + +
+
+netcdf t42mpas-bilinear { +dimensions: + n_a = 8192 ; + n_b = 20480 ; + n_s = 42456 ; + nv_a = 4 ; + nv_b = 3 ; + num_wgts = 1 ; + src_grid_rank = 2 ; + dst_grid_rank = 1 ; +variables: + int src_grid_dims(src_grid_rank) ; + int dst_grid_dims(dst_grid_rank) ; + double yc_a(n_a) ; + yc_a:units = "degrees" ; + double yc_b(n_b) ; + yc_b:units = "radians" ; + double xc_a(n_a) ; + xc_a:units = "degrees" ; + double xc_b(n_b) ; + xc_b:units = "radians" ; + double yv_a(n_a, nv_a) ; + yv_a:units = "degrees" ; + double xv_a(n_a, nv_a) ; + xv_a:units = "degrees" ; + double yv_b(n_b, nv_b) ; + yv_b:units = "radians" ; + double xv_b(n_b, nv_b) ; + xv_b:units = "radians" ; + int mask_a(n_a) ; + mask_a:units = "unitless" ; + int mask_b(n_b) ; + mask_b:units = "unitless" ; + double area_a(n_a) ; + area_a:units = "square radians" ; + double area_b(n_b) ; + area_b:units = "square radians" ; + double frac_a(n_a) ; + frac_a:units = "unitless" ; + double frac_b(n_b) ; + frac_b:units = "unitless" ; + int col(n_s) ; + int row(n_s) ; + double S(n_s) ; + +// global attributes: + :title = "ESMF Offline Regridding Weight Generator" ; + :normalization = "destarea" ; + :map_method = "Bilinear remapping" ; + :ESMF_regrid_method = "Bilinear" ; + :conventions = "NCAR-CSM" ; + :domain_a = "T42_grid.nc" ; + :domain_b = "grid-dual.nc" ; + :grid_file_src = "T42_grid.nc" ; + :grid_file_dst = "grid-dual.nc" ; + :ESMF_version = "ESMF_8_2_0_beta_snapshot_05-3-g2193fa3f8a" ; +} ++ +
+The weight file contains four types of information: a description of the source grid, a description of the destination grid, the output of the regrid weight calculation, and global attributes describing the weight file. + +
+ +
+The variables describing the source grid in the weight file end with the suffix "_a". To be consistent with the original use of this weight file format +the grid information is written to the file such that the location being regridded is always the cell center. This means that the grid structure described here may not be identical to that in the source grid file. The full set of these variables may not always be present in the weight file. The following is an +explanation of each variable: +
+ +
+The variables describing the destination grid in the weight file end with the suffix "_b". To be consistent with the original use of this weight file format +the grid information is written to the file such that the location being regridded is always the cell center. This means that the grid structure described here may not be identical to that in the destination grid file. The full set of these variables may not always be present in the weight file. The following is an +explanation of each variable: +
+ +
+The following is an explanation of the variables containing the output of the regridding calculation: +
+The following code shows how to apply the weights in the weight file to interpolate a source field (src_field) defined +over the source grid to a destination field (dst_field) defined over the destination grid. The variables n_s, n_b, +row, col, and S are from the weight file. + +
+
+ ! Initialize destination field to 0.0 + do i=1, n_b + dst_field(i)=0.0 + enddo + + ! Apply weights + do i=1, n_s + dst_field(row(i))=dst_field(row(i))+S(i)*src_field(col(i)) + enddo ++ +
+If the first-order conservative interpolation method is specified ("-m conserve") then the destination field may need to be adjusted by the destination fraction (frac_b). +This should be done if the normalization type is "dstarea" and if the destination grid extends outside the unmasked source grid. If it isn't known if the destination extends outside the source, then it doesn't hurt to apply the destination fraction. (If it doesn't extend outside, then the fraction will be 1.0 everywhere anyway.) +The following code shows how to adjust an already interpolated destination field (dst_field) by the destination fraction. The variables n_b, and frac_b are from the weight file: + +
+
+ ! Adjust destination field by fraction + do i=1, n_b + if (frac_b(i) .ne. 0.0) then + dst_field(i)=dst_field(i)/frac_b(i) + endif + enddo ++ +
+ +
+The following is an explanation of the global attributes describing the weight file: +
+ +
+In the current ESMF distribution, a new simplified weight file option -weight_only is added to ESMF_RegridWeightGen. +The simple weight file contains only a subset of the Regrid Calculation Output defined in 12.9.3, i.e. +the weights S, the source grid indices col and destination grid indices row. The dimension of these three variables is n_s. + +
+ +
+The ESMF_RegridWeightGen application is used in the +ESMF_RegridWeightGenCheck external demo +to generate interpolation weights. These weights are then tested by using them for a regridding operation and then comparing them against an analytic function on the destination grid. This external demo is also used to regression test ESMF regridding, and it is run nightly on over 150 combinations of structured and unstructured, regional and global grids, and regridding methods. + +
+ +
+ +
+This section describes the file-based regridding command line tool provided by ESMF (for a description of ESMF regridding in general see Section 24.2). Regridding, also called remapping or interpolation, is the process of changing the grid that underlies data values while preserving qualities of the original data. Different kinds of transformations are appropriate for different problems. Regridding may be needed when communicating data between Earth system model components such as land and atmosphere, or between different data sets to support operations such as visualization. + +
+Regridding can be broken into two stages. The first stage is generation of an interpolation weight matrix that describes how points in +the source grid contribute to points in the destination grid. The second stage is the multiplication of values on the source grid by the +interpolation weight matrix to produce values on the destination grid. This is implemented as a parallel sparse matrix multiplication. + +
+The ESMF_RegridWeightGen command line tool described in Section 12 +performs the first stage of the regridding process - generate the interpolation weight matrix. +This tool not only calculates the interpolation weights, it also applies the +weights to a list of variables +stored in the source grid file and produces the interpolated values on the destination grid. +The interpolated output variable is written out to the destination grid file. This tool +supports three CF compliant file formats: the CF Single Tile grid file format( 12.8.3) for +a logically rectangular grid, the UGRID file +format( 12.8.4) for unstructured grid and the GRIDSPEC +Mosaic file format( 12.8.5) for cubed-sphere grid. For +the GRIDSPEC Mosaic file format, the data are stored in seperate data files, +one file per tile. +The SCRIP format( 12.8.1) and the ESMF unstructured grid format( 12.8.2) are not supported because there is no way to define a variable field using these two formats. Currently, the tool only works with 2D grids, the support for the 3D grid will be +made available in the future release. The variable array can be up to four dimensions. The +variable type is currently limited to single or double precision real numbers. The support for +other data types, such as integer or short will be added in the future release. + +
+The user interface of this tool is greatly simplified from ESMF_RegridWeightGen. User only +needs to provide two input file names, the source and the destination variable names and the regrid method. The tool will figure out the type of the grid file automatically based on the attributes of the variable. +If the variable has a coordinates attribute, the grid file is a GRIDSPEC file and the value of the +coordinates defines the longitude and latitude variable's names. For example, following is a simple +GRIDSPEC file with a variable named PSL and coordinate variables named lon and lat. + +
+netcdf simple_gridspec { +dimensions: + lat = 192 ; + lon = 288 ; +variables: + float PSL(lat, lon) ; + PSL:time = 50. ; + PSL:units = "Pa" ; + PSL:long_name = "Sea level pressure" ; + PSL:cell_method = "time: mean" ; + PSL:coordinates = "lon lat" ; + double lat(lat) ; + lat:long_name = "latitude" ; + lat:units = "degrees_north" ; + double lon(lon) ; + lon:long_name = "longitude" ; + lon:units = "degrees_east" ; +} ++ +
+If the variable has a mesh attribute and a location attribute, the grid file is in UGRID +format( 12.8.4). The value of mesh attribute is the name of a dummy variable that defines the mesh topology. If the application performs a conservative regridding, the value of the location attribute has to be face, otherwise, it has to be node. +This is because ESMF only supports non-conservative regridding on the data stored at the nodes of a ESMF_Mesh object, and conservative regridding on the data stored at the cells of +a ESMF_Mesh object. + +
+Here is an example 2D UGRID file: + +
+netcdf simple_ugrid { +dimensions: + node = 4176 ; + nele = 8268 ; + three = 3 ; + time = 2 ; +variables: + float lon(node) ; + lon:units = "degrees_east" ; + float lat(node) ; + lat:units = "degrees_north" ; + float lonc(nele) ; + lonc:units = "degrees_east" ; + float latc(nele) ; + latc:units = "degrees_north" ; + int nv(nele, three) ; + nv:standard_name = "face_node_connectivity" ; + nv:start_index = 1. ; + float zeta(time, node) ; + zeta:standard_name = "sea_surface_height_above_geoid" ; + zeta:_FillValue = -999. ; + zeta:location = "node" ; + zeta:mesh = "fvcom_mesh" ; + float ua(time, nele) ; + ua:standard_name = "barotropic_eastward_sea_water_velocity" ; + ua:_FillValue = -999. ; + ua:location = "face" ; + ua:mesh = "fvcom_mesh" ; + float va(time, nele) ; + va:standard_name = "barotropic_northward_sea_water_velocity" ; + va:_FillValue = -999. ; + va:location = "face" ; + va:mesh = "fvcom_mesh" ; + int fvcom_mesh(node) ; + fvcom_mesh:cf_role = "mesh_topology" ; + fvcom_mesh:dimension = 2. ; + fvcom_mesh:locations = "face node" ; + fvcom_mesh:node_coordinates = "lon lat" ; + fvcom_mesh:face_coordinates = "lonc latc" ; + fvcom_mesh:face_node_connectivity = "nv" ; +} ++ +
+There are three variables defined in the above UGRID file - zeta on the node of the mesh, ua and +va on the face of the mesh. All three variables have one extra time dimension. + +
+The GRIDSPEC MOSAIC file( 12.8.5) can be identified by a dummy variable with standard_name attribute set to grid_mosaic_spec. The data for a +GRIDSPEC Mosaic file are stored in seperate files, one tile per file. The +name of the data file is not specified in the mosaic file. Therefore, +additional optional argument -srcdatafile or -dstdatafile is +required to provide the prefix of the datafile. The datafile is also a CF +compliant NetCDF file. The complete name of the datafile is +constructed by appending the tilename (defined in the Mosaic file in a +variable specified by the children attribute of the dummy variable). +For instance, if the prefix of the datafile is mosaicdata, then the +datafile names are mosaicdata.tile1.nc, mosaicdata.tile2.nc, +etc... using the mosaic file example in 12.8.5. The +path of the datafile is defined by gridlocation variable, similar to the +tile files. To overwrite it, an optional argument tilefile_path can be +specified. + +
+Following is an example GRIDSPEC MOSAIC datafile: + +
+
+netcdf mosaictest.tile1 { +dimensions: + grid_yt = 48 ; + grid_xt = 48 ; + time = UNLIMITED ; // (12 currently) +variables: + float area_land(grid_yt, grid_xt) ; + area_land:long_name = "area in the grid cell" ; + area_land:units = "m2" ; + float evap_land(time, grid_yt, grid_xt) ; + evap_land:long_name = "vapor flux up from land" ; + evap_land:units = "kg/(m2 s)" ; + evap_land:coordinates = "geolon_t geolat_t" ; + double geolat_t(grid_yt, grid_xt) ; + geolat_t:long_name = "latitude of grid cell centers" ; + geolat_t:units = "degrees_N" ; + double geolon_t(grid_yt, grid_xt) ; + geolon_t:long_name = "longitude of grid cell centers" ; + geolon_t:units = "degrees_E" ; + double time(time) ; + time:long_name = "time" ; + time:units = "days since 1900-01-01 00:00:00" ; +} ++ +
+This is a database for the C48 Cubed Sphere grid defined in +12.8.5. Note currently we assume that the data are +located at the center stagger of the grid. The coordinate variables geolon_t and geolat_t should be identical to the center coordinates +defined in the corresponding tile files. They are not used to create the +multi-tile grid. For this application, they are only used to construct the +analytic field to check the correctness of the regridding results if -check argument is given. + +
+If the variable specified for the destination file does not already exist in the file, the file type is determined as follows: +First search for a variable that has a cf_role attribute of value mesh_topology. If successful, +the file is a UGRID file. The destination variable will be created on the nodes if the regrid method is +non-conservative and an optional argument dst_loc is set to corner. Otherwise, the destination variable will be created +on the face. If the destination file is not a UGRID file, check if there is a variable with its units attribute set to degrees_east and another variable with it's units attribute set to degrees_west. If such a pair is found, +the file is a GRIDSPEC file and the above two variables will be used as the coordinate variables for the +variable to be created. If more than one pair of coordinate variables are found in the file, the application +will fail with an error message. + +
+If the destination +variable exists in the destination grid file, it has to have the same number of dimensions and the same type as the source variable. Except for the latitude and longitude dimensions, the size of +the destination variable's extra dimensions (e.g., time and vertical layers) has to match with the +source variable. If the destination varialbe does not exist in the destination grid file, a +new variable will be created with the same type and matching dimensions as the source variable. +All the attributes of the source variable will be copied to the destination variable except those +related to the grid definition (i.e. coordinates attribute if the destination file is in +GRIDSPEC or MOSAIC format or mesh and location attributes if the destination file is in UGRID format. + +
+Additional rules beyond the CF convention are adopted to determine whether there is a time dimension defined +in the source and destination files. In this application, only a dimension with a name time is +considered as a time dimension. +If the source variable has a time dimension and the destination variable is not already defined, +the application first checks if there is a time dimension defined in the destination file. If so, +the values of the time dimension in both files have to be identical. If the time dimension values don't match, the application +terminates with an error message. The application does not check the existence of a time variable +or if the units attribute of the time variable match in two input files. If the destination +file does not have a time dimension, it will be created. UNLIMITED time dimension is allowed in the +source file, but the time dimension created in the destination file is not UNLIMITED. + +
+This application requires the NetCDF library to read the grid files and write out the interpolated variables. To compile ESMF with +the NetCDF library, please refer to the "Third Party Libraries" Section in the ESMF User's Guide for more information. + +
+Internally this application uses the ESMF public API to perform regridding. +If a source or destination grid is logically rectangular, then ESMF_GridCreate()( 31.6.13) is used to create an ESMF_Grid object from the file. The coordinate variables are stored +at the center stagger location (ESMF_STAGGERLOC_CENTER). If the application performs a +conservative regridding, the addCornerStager argument is set to TRUE and the bound variables in the grid file will +be read in and stored at the corner stagger location (ESMF_STAGGERLOC_CORNER). If the variable has an _FillValue attribute defined, a mask will be generated using the missing values of the variable. +The data variable is defined as a ESMF_Field object at the center stagger location (ESMF_STAGGERLOC_CENTER) of the grid. + +
+If the source grid is an unstructured grid and the the regrid method is nearest neighbor, or if the destination grid +is unstructured and the regrid method is non-conservative, ESMF_LocStreamCreate()( 32.4.14 is used to create an ESMF_LocStream object. Otherwise, +ESMF_MeshCreate()( 33.4.8) is used to create an ESMF_Mesh object for the unstructured +input grids. Currently, only the 2D unstructured grid is supported. +If the application performs a conservative regridding, the variable has to be defined on the face of the mesh cells, i.e., its location attribute has to be set to face. Otherwise, the variable has to be +defined on the node and its (location attribute is set to node). + +
+If a source or a destination grid is a Cubed Sphere grid defined in GRIDSPEC +MOSAIC file format, ESMF_GridCreateMosaic()( 31.6.28) will be used to create a multi-tile ESMF_Grid +object from the file. The coordinates at the center and the corner stagger in +the tile files will be stored in the grid. The data has to be located at the +center stagger of the grid. + +
+Similar to the ESMF_RegridWeightGen command line tool (Section 12), this application supports +bilinear, patch, nearest neighbor, first-order and second-order conservative interpolation. The descriptions of different +interpolation methods can be found at Section 24.2 and Section 12. +It also supports different pole methods for non-conservative interpolation and allows user to choose to +ignore the errors when some of the destination points cannot be mapped by any source points. + +
+If the optional argument -check is given, the interpolated fields will +be checked agaist a synthetic field defined as follows: + +
+
++ +
+ +
+The command line arguments are all keyword based. Both the long keyword prefixed with '--'
or the
+one character short keyword prefixed with '-' are supported. The format to run the command line tool is as follows:
+
+
+
+ESMF_Regrid + --source|-s src_grid_filename + --destination|-d dst_grid_filename + --src_var var_name[,var_name,..] + --dst_var var_name[,var_name,..] + [--srcdatafile] + [--dstdatafile] + [--tilefile_path filepath] + [--dst_loc center|corner] + [--method|-m bilinear|patch|nearestdtos|neareststod|conserve|conserve2nd] + [--pole|-p none|all|teeth|1|2|..] + [--ignore_unmapped|-i] + [--ignore_degenerate] + [-r] + [--src_regional] + [--dst_regional] + [--check] + [--no_log] + [--help] + [--version] + [-V] +where + --source or -s - a required argument specifying the source grid + file name + + --destination or -d - a required argument specifying the destination + grid file name + + --src_var - a required argument specifying the variable names + in the src grid file to be interpolated from. If more + than one, separated them with comma. + + --dst_var - a required argument specifying the variable names + to be interpolated to. If more than one, separated + them with comma. The variable may or may not + exist in the destination grid file. + + --srcdatafile - If the source grid is a GRIDSPEC MOSAIC grid, the data + is stored in separate files, one per tile. srcdatafile + is the prefix of the source data file. The filename + is srcdatafile.tilename.nc, where tilename is the tile + name defined in the MOSAIC file. + + --srcdatafile - If the destination grid is a GRIDSPEC MOSAIC grid, the data + is stored in separate files, one per tile. dstdatafile + is the prefix of the destination data file. The filename + is dstdatafile.tilename.nc, where tilename is the tile + name defined in the MOSAIC file. + + --tilefile_path - the alternative file path for the tile files and the + data files when either the source or the destination grid + is a GRIDSPEC MOSAIC grid. The path can be either relative + or absolute. If it is relative, it is relative to the + working directory. When specified, the gridlocation variable + defined in the Mosaic file will be ignored. + + --dst_loc - an optional argument that specifies whether the destination + variable is located at the center or the corner of the grid + if the destination variable does not exist in the destination + grid file. This flag is only required for non-conservative + regridding when the destination grid is in UGRID format. + For all other cases, only the center location is supported + that is also the default value if this argument is not specified. + + --method or -m - an optional argument specifying which interpolation + method is used. The value can be one of the following: + + bilinear - for bilinear interpolation, also the + default method if not specified. + patch - for patch recovery interpolation + nearstdtos - for nearest destination to source interpolation + nearststod - for nearest source to destination interpolation + conserve - for first-order conservative interpolation + + --pole or -p - an optional argument indicating what to do with + the pole. + The value can be one of the following: + + none - No pole, the source grid ends at the top + (and bottom) row of nodes specified in + <source grid>. + all - Construct an artificial pole placed in the + center of the top (or bottom) row of nodes, + but projected onto the sphere formed by the + rest of the grid. The value at this pole is + the average of all the pole values. This + is the default option. + + teeth - No new pole point is constructed, instead + the holes at the poles are filled by + constructing triangles across the top and + bottom row of the source Grid. This can be + useful because no averaging occurs, however, + because the top and bottom of the sphere are + now flat, for a big enough mismatch between + the size of the destination and source pole + regions, some destination points may still + not be able to be mapped to the source Grid. + + <N> - Construct an artificial pole placed in the + center of the top (or bottom) row of nodes, + but projected onto the sphere formed by the + rest of the grid. The value at this pole is + the average of the N source nodes next to + the pole and surrounding the destination + point (i.e. the value may differ for each + destination point. Here N ranges from 1 to + the number of nodes around the pole. + + --ignore_unmapped + or + -i - ignore unmapped destination points. If not specified + the default is to stop with an error if an unmapped + point is found. + + --ignore_degenerate - ignore degenerate cells in the input grids. If not specified + the default is to stop with an error if an degenerate + cell is found. + + -r - an optional argument specifying that the source and + destination grids are regional grids. If the argument + is not given, the grids are assumed to be global. + + --src_regional - an optional argument specifying that the source is + a regional grid and the destination is a global grid. + + --dst_regional - an optional argument specifying that the destination + is a regional grid and the source is a global grid. + + --check - Check the correctness of the interpolated destination + variables against an analytic field. The source variable + has to be synthetically constructed using the same analytic + method in order to perform meaningful comparison. + The analytic field is calculated based on the coordinate + of the data point. The formular is as follows: + data(i,j,k,l)=2.0+cos(lat(i,j))**2*cos(2.0*lon(i,j))+(k-1)+2*(l-1) + The data field can be up to four dimensional with the + first two dimension been longitude and latitude. + The mean relative error between the destination and + analytic field is computed. + + --no_log - Turn off the ESMF error log. + + --help - Print the usage message and exit. + + --version - Print ESMF version and license information and exit. + + -V - Print ESMF version number and exit. ++ +
+ +
+The example below regrids the node variable zeta defined in the sample UGRID file(13.1) to +the destination grid defined in the sample GRIDSPEC file(13.1) using bilinear regridding +method and write the interpolated data into a variable named zeta. + +
+
+ mpirun -np 4 ESMF_Regrid -s simple_ugrid.nc -d simple_gridspec.nc \ + --src_var zeta --dst_var zeta ++ +
+In this case, the destination variable does not exist in simple_ugrid.nc and the time +dimension is not defined in the destination file. The resulting output file has a new time dimension and a new variable zeta. +The attributes from the source variable zeta are copied to the destination variable except for +mesh and location. A new attribute coordinates is created for the destination variable to +specify the names of the coordinate variables. The header of the output file looks like: + +
+
+netcdf simple_gridspec { +dimensions: + lat = 192 ; + lon = 288 ; + time = 2 ; +variables: + float PSL(lat, lon) ; + PSL:time = 50. ; + PSL:units = "Pa" ; + PSL:long_name = "Sea level pressure" ; + PSL:cell_method = "time: mean" ; + PSL:coordinates = "lon lat" ; + double lat(lat) ; + lat:long_name = "latitude" ; + lat:units = "degrees_north" ; + double lon(lon) ; + lon:long_name = "longitude" ; + lon:units = "degrees_east" ; + float zeta(time, lat, lon) ; + zeta:standard_name = "sea_surface_height_above_geoid" ; + zeta:_FillValue = -999. ; + zeta:coordinates = "lon lat" ; +} ++ +
+The next example shows the command to do the same thing as the previous example but for a +different variable ua. Since ua is defined on the face, we can only do a conservative +regridding. + +
+
+ mpirun -np 4 ESMF_Regrid -s simple_ugrid.nc -d simple_gridspec.nc \ + --src_var ua --dst_var ua -m conserve ++ +
+ +
+ +
+ +
+The ESMF_Scrip2Unstruct application is a parallel program that converts a SCRIP format grid file 12.8.1 into an unstructured grid file in the ESMF unstructured file format 12.8.2 or in the UGRID file format 12.8.4. This application program can be used together with ESMF_RegridWeightGen 12 application for the unstructured SCRIP format grid files. An unstructured SCRIP grid file will be converted into the ESMF unstructured file format internally in ESMF_RegridWeightGen. The conversion subroutine used in ESMF_RegridWeightGen is sequential and could be slow if the grid file is very big. It will be more efficient to run the ESMF_Scrip2Unstruct first and then regrid the output ESMF or UGRID file using ESMF_RegridWeightGen. Note that a logically rectangular grid file in the SCRIP format (i.e. the dimension grid_rank is equal to 2) can also be converted into an unstructured grid file with this application. + +
+The application usage is as follows: + +
+
+ESMF_Scrip2Unstruct inputfile outputfile dualflag [fileformat] + +where + inputfile - a SCRIP format grid file + + outputfile - the output file name + + dualflag - 0 for straight conversion and 1 for dual + mesh. A dual mesh is a mesh constructed + by putting the corner coordinates in the + center of the elements and using the + center coordinates to form the mesh + corner vertices. + + fileformat - an optional argument for the output file + format. It could be either ESMF or UGRID. + If not specified, the output file is in + the ESMF format. ++ + + + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_refdoc/node4.html b/docs/nightly/fix/reconcile-info/ESMF_refdoc/node4.html new file mode 100644 index 000000000..61c9f22cb --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_refdoc/node4.html @@ -0,0 +1,15089 @@ + + + + + +
+ +
+ESMF superstructure classes define an architecture for assembling +Earth system applications from modeling components. A component +may be defined in terms of the physical domain that it represents, +such as an atmosphere or sea ice model. It may also be defined in terms +of a computational function, such as a data assimilation system. +Earth system research often requires that such components be coupled +together to create an application. By coupling we mean the data +transformations and, on parallel computing systems, data transfers, +that are necessary to allow data from one component to be utilized by +another. ESMF offers regridding methods and other tools to simplify +the organization and execution of inter-component data exchanges. + +
+In addition to components defined at the level of major physical +domains and computational functions, components may be defined that +represent smaller computational functions within larger components, +such as the transformation of data between the physics and dynamics +in a spectral atmosphere model, +or the creation of nested higher resolution regions +within a coarser grid. The objective is to couple components at varying +scales both flexibly and efficiently. ESMF encourages a hierarchical +application structure, in which large components branch into +smaller sub-components (see Figure 2). ESMF also makes +it easier for the same component to be used in multiple contexts +without changes to its source code. + +
+
+ +Key Features |
+
Modular, component-based architecture. | +
Hierarchical assembly of components into applications. | +
Use of components in multiple contexts without modification. | +
Sequential or concurrent component execution. | +
Single program, multiple datastream (SPMD) applications for +maximum portability and reconfigurability. | +
Multiple program, multiple datastream (MPMD) option for +flexibility. | +
+ +
+There are a small number of classes in the ESMF superstructure: + +
+ +
+The second part of an ESMF Component is user code, such as a +model or data assimilation system. Users set entry points +within their code so that it is callable by the framework. +In practice, setting entry points means that within user code +there are calls to ESMF methods that associate the name of a +Fortran subroutine with a corresponding standard ESMF operation. +For example, a user-written initialization routine called +myOceanInit might be associated with the standard +initialize routine of an ESMF Gridded Component named “myOcean” +that represents an ocean model. + +
+
+
+An ESMF coupled application typically involves a parent Gridded Component, +two or more child Gridded Components and one or more Coupler +Components. + +
+The parent Gridded Component is responsible for creating the child +Gridded Components that are exchanging data, for creating the Coupler, +for creating the necessary Import and Export States, and for +setting up the desired sequencing. The application's “main” routine +calls the parent Gridded Component's initialize, run, and finalize +methods in order to execute the application. For each of these +standard methods, the parent Gridded Component in turn calls the +corresponding methods in the child Gridded Components and the +Coupler Component. For example, consider a simple coupled +ocean/atmosphere simulation. When the initialize method of the +parent Gridded Component is called by the application, it in turn +calls the initialize methods of its child atmosphere and ocean +Gridded Components, and the initialize method of an +ocean-to-atmosphere Coupler Component. Figure 3 +shows this schematically. + +
+
+ |
+ +
+Components are allocated computational resources in the form of +Persistent Execution Threads, or PETs. A list of a Component's +PETs is contained in a structure called a Virtual Machine, +or VM. The VM also contains information about the topology and +characteristics of the underlying computer. +Components are created hierarchically, with parent Components creating +child Components and allocating some or all of their PETs to each one. +By default ESMF creates a new VM for each child Component, which +allows Components to tailor their VM resources to match their needs. +In some cases, a child may want to share its parent's VM - ESMF +supports this, too. + +
+A Gridded Component may exist across all the PETs in an application. +A Gridded Component may also reside on a subset of PETs in an +application. These PETs may wholly coincide with, be wholly contained +within, or wholly contain another Component. + +
+
+ |
+ +
+When a set of Gridded Components and a Coupler runs in sequence +on the same set of PETs the application is executing in a sequential +mode. When Gridded Components are created and run on mutually exclusive +sets of PETs, and are coupled by a Coupler Component that extends over +the union of these sets, the mode of execution is concurrent. + +
+Figure 4 illustrates a typical configuration for +a simple coupled sequential +application, and Figure 5 shows a possible +configuration for the same application running in a concurrent mode. + +
+Parent Components can select if and when to wait for concurrently +executing child Components, synchronizing only when required. + +
+It is possible for ESMF applications to contain some Component sets +that are executing sequentially and others that are executing concurrently. +We might have, for example, atmosphere and land Components created +on the same subset of PETs, ocean and sea ice Components created on +the remainder of PETs, and a Coupler created across all the PETs in +the application. + +
+
+ |
+
+ |
+ +
+All data transfers within an ESMF application occur within a +component. For example, a Gridded Component may contain halo updates. +Another example is that a Coupler Component may redistribute +data between two Gridded Components. As a result, +the architecture of ESMF does not depend on any particular data +communication mechanism, and new communication schemes can be +introduced without affecting the overall structure of the application. + +
+Since all data communication happens within a component, a Coupler +Component must be created on the union of the PETs of all +the Gridded Components that it couples. + +
+ +
+The scope of distributed objects is the VM of the currently +executing Component. For this reason, all +PETs in the current VM must make the same distributed object +creation calls. When a Coupler Component running on a superset +of a Gridded Component's PETs needs to make communication calls +involving objects created by the Gridded Component, +an ESMF-supplied function called ESMF_StateReconcile() creates proxy +objects for those PETs that had no previous information about the +distributed objects. Proxy objects contain no local data but +can be used in communication calls (such as regrid or redistribute) +to describe the remote source for data being moved to the current PET, +or to describe the remote destination for data being moved from the local PET. +Figure 6 is a simple schematic that shows the +sequence of events in a reconcile call. + +
+
+ |
+ +
+The ESMF design enables the user to configure ESMF +applications so that data is transferred directly from one component +to another, without requiring that it be copied or sent to a different data +buffer as an interim step. This is likely to be the most efficient way +of performing inter-component coupling. However, if desired, an +application can also be configured so that data from a source component +is sent to a distinct set of Coupler Component PETs for processing +before being sent to its destination. + +
+The ability to overlap computation with communication is essential for +performance. When running with ESMF the user can initiate data +sends during Gridded Component execution, as soon as the data is ready. +Computations can then proceed simultaneously with the data transfer. + +
+ +
+The following is a simplified Unified Modeling Language (UML) diagram showing the relationships among +ESMF superstructure classes. See Appendix A, A Brief Introduction +to UML, for a translation table that lists the symbols in the diagram +and their meaning. + +
+
+ +
+Every ESMF application needs a driver code. Typically the driver layer is +implemented as the "main" of the application, although this is not strictly an +ESMF requirement. For most ESMF applications the task of the application driver +will be very generic: Initialize ESMF, create a top-level Component and call its +Initialize, Run and Finalize methods, before destroying the top-level Component +again and calling ESMF Finalize. + +
+ESMF provides a number of different application driver templates in the +$ESMF_DIR/src/Superstructure/AppDriver directory. An appropriate one +can be chosen depending on how the application is to be structured: + +
+
+In a sequential execution model, every Component executes +on all PETs, with each Component completing execution before +the next Component begins. This has the appeal of +simplicity of data consumption and production: when a Gridded +Component starts, all required data is available for use, and when +a Gridded Component finishes, all data produced is ready for consumption +by the next Gridded Component. This approach also has +the possibility of less data movement if the grid and +data decomposition is done such that each processor's memory contains +the data needed by the next Component. + +
+In a concurrent execution model, subgroups of PETs run +Gridded Components and multiple Gridded Components are active at the +same time. Data exchange must be coordinated between Gridded +Components so that data deadlock does not occur. This strategy +has the advantage of allowing coupling to other Gridded Components +at any time during the computational process, including not +having to return to the calling level of code before making +data available. + +
+
+Coupler Components are responsible for taking data from one +Gridded Component and putting it into the form expected by another +Gridded Component. This might include regridding, change of units, +averaging, or binning. + +
+Coupler Components can be written for pairwise data exchange: +the Coupler Component takes data from a single Component and transforms +it for use by another single Gridded Component. This simplifies the +structure of the Coupler Component code. + +
+Couplers can also be written using a hub and spoke model where a +single Coupler accepts data from all other Components, can do data +merging or splitting, and formats data for all other Components. + +
+Multiple Couplers, using either of the above two models or some mixture of +these approaches, are also possible. + +
+
+The ESMF framework currently has Fortran interfaces for all public functions. +Some functions also have C interfaces, and the number of these is expected to +increase over time. + +
+
+The simplest way to run an application +is to run the same executable program on all PETs. Different Components +can still be run on mutually exclusive PETs by using branching +(e.g., if this is PET 1, 2, or 3, run Component A, if it is +PET 4, 5, or 6 run Component B). This is a SPMD model, +Single Program Multiple Data. + +
+The alternative is to start a different executable program on different +PETs. This is a MPMD model, Multiple Program Multiple Data. +There are complications with many job control systems on multiprocessor +machines in getting the different executables started, and getting +inter-process communications established. ESMF currently has some +support for MPMD: different Components can run as separate executables, +but the Coupler that transfers data between the Components must still +run on the union of their PETs. This means that the Coupler Component +must be linked into all of the executables. + +
+
+ +
+ +
+DESCRIPTION:
+
+The ESMF_End_Flag determines how an ESMF application is shut down.
+
+
+The type of this flag is: + +
+type(ESMF_End_Flag) + +
+The valid values are: +
+ESMF encourages application organization in which there is a single +top-level Gridded Component. This provides a simple, clear sequence +of operations at the highest level, and also enables the entire +application to be treated as a sub-Component of another, larger +application if desired. When a simple application is organized in this fashion +the standard AppDriver can probably be used without much modification. + +
+Examples of program organization using the AppDriver can be found in the +src/Superstructure/AppDriver directory. A set of subdirectories +within the AppDriver directory follows the naming convention: + +
+<seq|concur>_<pairwise|hub>_<f|c>driver_<spmd|mpmd> ++ +
+The example that is currently implemented is +seq_pairwise_fdriver_spmd, which +has sequential component execution, a pairwise coupler, a main program +in Fortran, and all processors launching the same executable. +It is also copied automatically into a top-level +quick_start directory at compilation time. + +
+The user can copy the AppDriver files into +their own local directory. Some of the files can be used unchanged. +Others are template files which have the rough outline of the code but +need additional application-specific code added in order to perform a +meaningful function. The README file in the AppDriver +subdirectory or quick_start directory contains instructions about +which files to change. + +
+Examples of concurrent component execution can be found in the +system tests that are bundled with the ESMF distribution. + +
+ +
+ +
+ +
+
+ + --------------------------------------------------------------------------- + --------------------------------------------------------------------------- + EXAMPLE: This is an AppDriver.F90 file for a sequential ESMF application. + --------------------------------------------------------------------------- + --------------------------------------------------------------------------- + + The ChangeMe.F90 file that's included below contains a number of + definitions that are used by the AppDriver, such as the name of the + application's main configuration file and the name of the application's + SetServices routine. This file is in the same directory as the + AppDriver.F90 file. + --------------------------------------------------------------------------- + + #include "ChangeMe.F90" + + program ESMF_AppDriver + #define ESMF_METHOD "program ESMF_AppDriver" + + #include "ESMF.h" + + ! ESMF module, defines all ESMF data types and procedures + use ESMF + + ! Gridded Component registration routines. Defined in "ChangeMe.F90" + use USER_APP_Mod, only : SetServices => USER_APP_SetServices + + implicit none + + --------------------------------------------------------------------------- + Define local variables + --------------------------------------------------------------------------- + + ! Components and States + type(ESMF_GridComp) :: compGridded + type(ESMF_State) :: defaultstate + + ! Configuration information + type(ESMF_Config) :: config + + ! A common Grid + type(ESMF_Grid) :: grid + + ! A Clock, a Calendar, and timesteps + type(ESMF_Clock) :: clock + type(ESMF_TimeInterval) :: timeStep + type(ESMF_Time) :: startTime + type(ESMF_Time) :: stopTime + + ! Variables related to the Grid + integer :: i_max, j_max + + ! Return codes for error checks + integer :: rc, localrc + + --------------------------------------------------------------------------- + Initialize ESMF. Note that an output Log is created by default. + --------------------------------------------------------------------------- + + call ESMF_Initialize(defaultCalKind=ESMF_CALKIND_GREGORIAN, rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + call ESMF_LogWrite("ESMF AppDriver start", ESMF_LOGMSG_INFO) + + --------------------------------------------------------------------------- + Create and load a configuration file. + The USER_CONFIG_FILE is set to sample.rc in the ChangeMe.F90 file. + The sample.rc file is also included in the directory with the + AppDriver.F90 file. + --------------------------------------------------------------------------- + + config = ESMF_ConfigCreate(rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + call ESMF_ConfigLoadFile(config, USER_CONFIG_FILE, rc = localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + --------------------------------------------------------------------------- + Get configuration information. + + A configuration file like sample.rc might include: + - size and coordinate information needed to create the default Grid. + - the default start time, stop time, and running intervals + for the main time loop. + --------------------------------------------------------------------------- + + call ESMF_ConfigGetAttribute(config, i_max, label='I Counts:', & + default=10, rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + call ESMF_ConfigGetAttribute(config, j_max, label='J Counts:', & + default=40, rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + --------------------------------------------------------------------------- + Create the top Gridded Component. + --------------------------------------------------------------------------- + + compGridded = ESMF_GridCompCreate(name="ESMF Gridded Component", & + rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + call ESMF_LogWrite("Component Create finished", ESMF_LOGMSG_INFO) + + ---------------------------------------------------------------------------- + Register the set services method for the top Gridded Component. + ---------------------------------------------------------------------------- + + call ESMF_GridCompSetServices(compGridded, userRoutine=SetServices, rc=rc) + if (ESMF_LogFoundError(rc, msg="Registration failed", rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + ---------------------------------------------------------------------------- + Create and initialize a Clock. + ---------------------------------------------------------------------------- + + call ESMF_TimeIntervalSet(timeStep, s=2, rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + call ESMF_TimeSet(startTime, yy=2004, mm=9, dd=25, rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + call ESMF_TimeSet(stopTime, yy=2004, mm=9, dd=26, rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + clock = ESMF_ClockCreate(timeStep, startTime, stopTime=stopTime, & + name="Application Clock", rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + ---------------------------------------------------------------------------- + Create and initialize a Grid. + + The default lower indices for the Grid are (/1,1/). + The upper indices for the Grid are read in from the sample.rc file, + where they are set to (/10,40/). This means a Grid will be + created with 10 grid cells in the x direction and 40 grid cells in the + y direction. The Grid section in the Reference Manual shows how to set + coordinates. + ---------------------------------------------------------------------------- + + grid = ESMF_GridCreateNoPeriDim(maxIndex=(/i_max, j_max/), & + name="source grid", rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + ! Attach the grid to the Component + call ESMF_GridCompSet(compGridded, grid=grid, rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + ---------------------------------------------------------------------------- + Create and initialize a State to use for both import and export. + In a real code, separate import and export States would normally be + created. + ---------------------------------------------------------------------------- + + defaultstate = ESMF_StateCreate(name="Default State", rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + ---------------------------------------------------------------------------- + Call the initialize, run, and finalize methods of the top component. + When the initialize method of the top component is called, it will in + turn call the initialize methods of all its child components, they + will initialize their children, and so on. The same is true of the + run and finalize methods. + ---------------------------------------------------------------------------- + + call ESMF_GridCompInitialize(compGridded, importState=defaultstate, & + exportState=defaultstate, clock=clock, rc=localrc) + if (ESMF_LogFoundError(rc, msg="Initialize failed", rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + call ESMF_GridCompRun(compGridded, importState=defaultstate, & + exportState=defaultstate, clock=clock, rc=localrc) + if (ESMF_LogFoundError(rc, msg="Run failed", rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + call ESMF_GridCompFinalize(compGridded, importState=defaultstate, & + exportState=defaultstate, clock=clock, rc=localrc) + if (ESMF_LogFoundError(rc, msg="Finalize failed", rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + + ---------------------------------------------------------------------------- + Destroy objects. + ---------------------------------------------------------------------------- + + call ESMF_ClockDestroy(clock, rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + call ESMF_StateDestroy(defaultstate, rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + call ESMF_GridCompDestroy(compGridded, rc=localrc) + if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rcToReturn=rc)) & + call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT) + + ---------------------------------------------------------------------------- + Finalize and clean up. + ---------------------------------------------------------------------------- + + call ESMF_Finalize() + + end program ESMF_AppDriver ++ + +
+There are a few methods that every ESMF application must contain. First, +ESMF_Initialize() and ESMF_Finalize() are in complete analogy +to MPI_Init() and MPI_Finalize() known from MPI. All ESMF +programs, serial or parallel, must initialize the ESMF system at the beginning, +and finalize it at the end of execution. The behavior of calling any +ESMF method before ESMF_Initialize(), or after ESMF_Finalize() +is undefined. + +
+Second, every ESMF Component that is accessed by an ESMF application requires +that its set services routine is called through +ESMF_<Grid/Cpl>CompSetServices(). The Component must implement +one public entry point, its set services routine, that can be called +through the ESMF_<Grid/Cpl>CompSetServices() library routine. The +Component set services routine is responsible for setting entry points +for the standard ESMF Component methods Initialize, Run, and Finalize. + +
+Finally, the Component can optionally call ESMF_<Grid/Cpl>CompSetVM() +before calling +ESMF_<Grid/Cpl>CompSetServices(). Similar to +ESMF_<Grid/Cpl>CompSetServices(), the +ESMF_<Grid/Cpl>CompSetVM() +call requires a public entry point into the Component. It allows the Component +to adjust certain aspects of its execution environment, i.e. its own VM, before +it is started up. + +
+The following sections discuss the above mentioned aspects in more detail. + +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_Initialize(configFilenameFromArgNum, & + configFilename, configKey, & + defaultDefaultCalKind, defaultCalKind, & + defaultDefaultLogFilename, defaultLogFilename, & + defaultLogAppendFlag, logAppendFlag, defaultLogKindFlag, logKindFlag, & + mpiCommunicator, ioUnitLBound, ioUnitUBound, & + defaultGlobalResourceControl, globalResourceControl, config, hconfig, & + vm, rc) +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: configFilenameFromArgNum + character(len=*), intent(in), optional :: configFilename + character(len=*), intent(in), optional :: configKey(:) + type(ESMF_CalKind_Flag), intent(in), optional :: defaultDefaultCalKind + type(ESMF_CalKind_Flag), intent(in), optional :: defaultCalKind + character(len=*), intent(in), optional :: defaultDefaultLogFilename + character(len=*), intent(in), optional :: defaultLogFilename + logical, intent(in), optional :: defaultLogAppendFlag + logical, intent(in), optional :: logAppendFlag + type(ESMF_LogKind_Flag), intent(in), optional :: defaultLogKindFlag + type(ESMF_LogKind_Flag), intent(in), optional :: logKindFlag + integer, intent(in), optional :: mpiCommunicator + integer, intent(in), optional :: ioUnitLBound + integer, intent(in), optional :: ioUnitUBound + logical, intent(in), optional :: defaultGlobalResourceControl + logical, intent(in), optional :: globalResourceControl + type(ESMF_Config), intent(out), optional :: config + type(ESMF_HConfig), intent(out), optional :: hconfig + type(ESMF_VM), intent(out), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This method must be called once on each PET before + any other ESMF methods are used. The method contains a + barrier before returning, ensuring that all processes + made it successfully through initialization. + +
+Typically ESMF_Initialize() will call MPI_Init() + internally unless MPI has been initialized by the user code before + initializing the framework. If the MPI initialization is left to + ESMF_Initialize() it inherits all of the MPI implementation + dependent limitations of what may or may not be done before + MPI_Init(). For instance, it is unsafe for some MPI + implementations, such as MPICH1, to do I/O before the MPI environment + is initialized. Please consult the documentation of your MPI + implementation for details. + +
+Note that when using MPICH1 as the MPI library, ESMF needs to use + the application command line arguments for MPI_Init(). However, + ESMF acquires these arguments internally and the user does not need + to worry about providing them. Also, note that ESMF does not alter + the command line arguments, so that if the user obtains them they will + be as specified on the command line (including those which MPICH1 would + normally strip out). + +
+ESMF_Initialize() supports running ESMF inside a user MPI program. + Details of this feature are discussed under the VM example + 51.3.5. It is not necessary that all MPI ranks are + handed to ESMF. Section 51.3.6 shows how an MPI + communicator can be used to execute ESMF on a subset of MPI ranks. + ESMF_Initialize() supports running multiple concurrent + instances of ESMF under the same user MPI program. This feature is + discussed under 51.3.7. + +
+In order to use any of the advanced resource management functions that + ESMF provides via the ESMF_*CompSetVM*() methods, the MPI + environment must be thread-safe. ESMF_Initialize() handles this + automatically if it is in charge of initializing MPI. However, if the + user code initializes MPI before calling into ESMF_Initialize(), + it must do so via MPI_Init_thread(), specifying + MPI_THREAD_SERIALIZED or above for the required level of thread + support. + +
+In cases where ESMF_*CompSetVM*() methods are used to move + processing elements (PEs), i.e. CPU cores, between persistent execution + threads (PETs), ESMF uses POSIX signals between PETs. In order to do so + safely, the proper signal handlers must be installed before MPI is + initialized. ESMF_Initialize() handles this automatically if it is + in charge of initializing MPI. If, however, MPI is explicitly initialized + by user code, then to ensure correct signal handling it is necessary to + call ESMF_InitializePreMPI() from the user code prior to the MPI + initialization. + +
+By default, ESMF_Initialize() opens multiple error log files, + one per processor. This is very useful for debugging purpose. However, + when running the application on a large number of tasks, opening a + large number of log files and writing log messages from all the tasks + can become a performance bottleneck. Therefore, it is recommended + for production runs to set logKindFlag to ESMF_LOGKIND_NONE, or + ESMF_LOGKIND_Multi_On_Error. The latter only creates log files + when an error occurs. + +
+When integrating ESMF with applications where Fortran unit number conflicts + exist, the optional ioUnitLBound and ioUnitUBound arguments may be + used to specify an alternate unit number range. See section 53.2.1 + for more information on how ESMF uses Fortran unit numbers. + +
+Before exiting the application the user must call ESMF_Finalize() + to release resources and clean up ESMF gracefully. See the + ESMF_Finalize() documentation about details relating to the MPI + environment. + +
+The arguments are: +
+The traditional ESMF_Config format and the YAML format + are supported. The latter is identified by file suffix .yaml + and .yml, including all lower/upper case letter combinations + that map to either suffix. + +
+In the case of the traditional ESMF_Config format, the + predefined labels of initialization options discussed below are + expected on the top level of the configuration. The expected + termination character for this case is a single colon following + each label. + +
+For the YAML case, the predefined initialization option labels are + expected as the keys of a map. If the optional argument + configKey is specified, it is used to locate this map. The + map is expected as the terminal value of a succession of mappings: +
+ configKey(1) : + configKey(2) : + ... + configKey(size(configKey)) : + {map of specified init options} ++ By default, in the absence of argument configKey, the top + level itself is searched for a mapping of predefined labels, + analogous to the traditional case. + +
+If any of the following predefined labels are found in the specified + configuration file (as per the above defined rules), their + values are used to set the associated ESMF_Initialize() + argument, overriding any defaults. + If the same argument is also specified in the + ESMF_Initialize() call directly, an error is returned, + and ESMF is not initialized. + The supported config labels are: + +
+ESMF allows the user to affect certain details about the execution + of an application through a number of run-time environment variables. + The following list of variables are checked within the specified + configuration file. If a matching label is found, the respective + value is set, potentially overriding the value defined within the + user environment for the same variable. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InitializePreMPI(rc) +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This method is only needed for cases where MPI is initialized + explicitly by user code. In most typical cases ESMF_Initialize() + is called before MPI is initialized, and takes care of all the internal + initialization, including MPI. + +
+There are circumstances where it is necessary or convenient to + initialize MPI before calling into ESMF_Initialize(). This option + is supported by ESMF, and for most cases no special action is required + on the user side. However, for cases where ESMF_*CompSetVM*() + methods are used to move processing elements (PEs), i.e. CPU cores, + between persistent execution threads (PETs), ESMF uses POSIX signals + between PETs. In order to do so safely, the proper signal handlers must + be installed before MPI is initialized. This is accomplished by calling + ESMF_InitializePreMPI() from the user code prior to the MPI + initialization. + +
+Note also that in order to use any of the advanced resource management + functions that ESMF provides via the ESMF_*CompSetVM*() methods, + the MPI environment must be thread-safe. ESMF_Initialize() handles + this automatically if it is in charge of initializing MPI. However, if the + user code initializes MPI before calling into ESMF_Initialize(), + it must do so via MPI_Init_thread(), specifying + MPI_THREAD_SERIALIZED or above for the required level of thread + support. + +
+The arguments are: +
+
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_IsInitialized(rc) +RETURN VALUE: +
logical :: ESMF_IsInitialized +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Returns .true. if the framework has been initialized. This means + that ESMF_Initialize() has been called. Otherwise returns + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_IsFinalized(rc) +RETURN VALUE: +
logical :: ESMF_IsFinalized +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Returns .true. if the framework has been finalized. This means + that ESMF_Finalize() has been called. Otherwise returns + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_Finalize(endflag, rc) +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_End_Flag), intent(in), optional :: endflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This must be called once on each PET before the application exits + to allow ESMF to flush buffers, close open connections, and + release internal resources cleanly. The optional argument + endflag may be used to indicate the mode of termination. + Note that this call must be issued only once per PET with + endflag=ESMF_END_NORMAL, and that this call may not be followed + by ESMF_Initialize(). This last restriction means that it is not + possible to restart ESMF within the same execution. + +
+The arguments are: +
+ + +
+ +
+Many programs call some library routines. The library +documentation must explain what the routine name is, what arguments +are required and what are optional, and what the code does. + +
+In contrast, all ESMF components must be written to be called +by another part of the program; in effect, an ESMF component takes the +place of a library. The interface is prescribed by the framework, +and the component writer must provide specific subroutines which +have standard argument lists and perform specific operations. +For technical reasons none of the arguments in user-provided subroutines +must be declared as optional. + +
+The only required public interface of a Component is its +SetServices method. This subroutine must have an +externally accessible name (be a public symbol), take a component +as the first argument, and an integer return code as the second. +Both arguments are required and must not be declared as +optional. If an intent is specified in the interface it must be +intent(inout) for the first and intent(out) for the +second argument. The subroutine name is not predefined, it is set by the +component writer, but must be provided as part of the component +documentation. + +
+The required function that the SetServices subroutine must provide is to +specify the user-code entry points for the standard ESMF Component methods. To +this end the user-written SetServices routine calls the + +
+ESMF_<Grid/Cpl>CompSetEntryPoint() method to set each +Component entry point. + +
+See sections 17.2.1 and 18.2.1 for examples of +how to write a user-code SetServices routine. + +
+Note that a component does not call its own SetServices routine; +the AppDriver or parent component code, which is creating a component, +will first call ESMF_<Grid/Cpl>CompCreate() to create a component object, and then must call into ESMF_<Grid/Cpl>CompSetServices(), supplying the user-code SetServices routine as an argument. The framework then calls into the user-code SetServices, after the Component's VM has been started up. + +
+It is good practice to package the user-code implementing a component into a Fortran module, with the user-code SetService routine being the only public module method. ESMF supports three mechanisms for accessing the user-code SetServices routine from the calling AppDriver or parent component. + +
+ +
+Pros: Standard Fortran module use: name mangling and interface checking is handled by the Fortran compiler. + +
+Cons: Fortran 90/95 has no mechanism to implement a "smart" dependency scheme through USE association. Any change in a lower level component module (even just adding or changing a comment!) will trigger a complete recompilation of all of the higher level components throughout the component hierarchy. This situation is particularly annoying for ESMF componentized code, where the prescribed ESMF component interfaces, in principle, remove all interdependencies between components that would require recompilation. + +
+Fortran submodules, introduced as an extension to Fortran 2003, and now part for the Fortran 2008 standard, are designed to avoid this "false" dependency issue. A code change to an ESMF component that keeps the actual implementation within a submodule, will not trigger a recompilation of the components further up in the component hierarchy. Unfortunately, as of mid-2015, only two compiler vendors support submodules. + +
+
+Pros: Avoids Fortran USE dependencies: a change to lower level component code will not trigger a complete recompilation of all of the higher level components throughout the component hierarchy. Name mangling is handled by the Fortran compiler. + +
+Cons: The user-code SetServices interface is not checked by the compiler. The user must ensure uniqueness of the external routine name across the entire application. + +
+ +
+Pros: Avoids Fortran USE dependencies: a change to lower level component code will not trigger a complete recompilation of all of the higher level components throughout the component hierarchy. The component code does not have to be accessible until runtime and may be located in a shared object, thus avoiding relinking of the application. + +
+Cons: The user-code SetServices interface is not checked by the compiler. The user must explicitly deal with all of the Fortran name mangling issues: 1) Accessing a module routine requires precise knowledge of the name mangling rules of the specific compiler. Alternatively, the user-code SetServices routine may be implemented as an external routine, avoiding the module name mangling. 2) Even then, Fortran compilers typically append one or two underscores on a symbol name. This must be considered when passing the name into the ESMF_<Grid/Cpl>CompSetServices() method. + +
+
+ +
+The required standard ESMF Component methods, for which user-code entry +points must be set, are Initialize, Run, and Finalize. Currently optional, +a Component may also set entry points for the WriteRestart and +ReadRestart methods. + +
+Sections 17.2.1 and 18.2.1 provide examples +of how the entry points for Initialize, Run, and Finalize are set during +the user-code SetServices routine, using the +ESMF_<Grid/Cpl>CompSetEntryPoint() library call. + +
+All standard user-code methods must abide exactly to the prescribed +interfaces. None of the arguments must be declared as optional. + +
+The names of the Initialize, Run, and Finalize user-code subroutines do +not need to be public; in fact it is far better for them to be private to +lower the chances of public symbol clashes between different components. + +
+See sections 17.2.2, 17.2.3, +17.2.4, and 18.2.2, 18.2.3, +18.2.4 for examples of how to write entry points for the +standard ESMF Component methods. + +
+ +
+When the AppDriver or parent component code calls +ESMF_<Grid/Cpl>CompCreate() it has the option to specify a +petList argument. All of the parent PETs contained in this list become +resources of the child component. By default, without the petList argument, all of the parent PETs are provided to the child component. + +
+Typically each component has its own virtual machine (VM) object. However, using the optional contextflag argument during ESMF_<Grid/Cpl>CompCreate() a child component can inherit its parent component's VM. Unless a child component inherits the parent VM, it has the option to set certain aspects of how its VM utilizes the provided resources. The resources provided via the parent PETs are the associated processing elements (PEs) and virtual address spaces (VASs). + +
+The optional user-written SetVM routine is called from the parent for the child through the ESMF_<Grid/Cpl>CompSetVM() method. This is the only place where the child component can set aspects of its own VM before it is started up. The child component's VM must be running before the SetServices routine can be called, and thus the parent must call the optional ESMF_<Grid/Cpl>CompSetVM() method before ESMF_<Grid/Cpl>CompSetServices(). + +
+Inside the user-code called by the SetVM routine, the component has the option to specify how the PETs share the provided parent PEs. Further, PETs on the same single system image (SSI) can be set to run multi-threaded within a reduced number of virtual address spaces (VAS), allowing a component to leverage shared memory concepts. + +
+Sections 17.2.5 and 18.2.5 provide examples for +simple user-written SetVM routines. + +
+One common use of the SetVM approach is to implement hybrid parallelism based on MPI+OpenMP. Under ESMF, each component can use its own hybrid parallelism implementation. Different components, even if running on the same PE resources, do not have to agree on the number of MPI processes (i.e. PETs), or the number of OpenMP threads launched under each PET. Hybrid and non-hybrid components can be mixed within the same application. Coupling between components of any flavor is supported under ESMF. + +
+In order to obtain best performance when using SetVM based resource control for hybrid parallelism, it is strongly recommended to set OMP_WAIT_POLICY=PASSIVE in the environment. This is one of the standard OpenMP environment variables. The PASSIVE setting ensures that OpenMP threads relinquish the PEs as soon as they have completed their work. Without that setting ESMF resource control threads can be delayed, and context switching between components becomes more expensive. + +
+ +
+Internal procedures are nested within a surrounding procedure, and only local to the surrounding procedure. +They are specified by using the CONTAINS statement. + +
+Prior to Fortran-2008 an internal procedure could not be used as a user-provided callback procedure. +In Fortran-2008 this restriction was lifted. It is important to note that if ESMF is passed an internal +procedure, that the surrounding procedure be active whenever ESMF calls it. This helps ensure that +local variables at the surrounding procedures scope are properly initialized. + +
+When internal procedures contained within a main program unit are used for callbacks, there is no problem. +This is because the main program unit is always active. However when internal procedures are used within +other program units, initialization could become a problem. The following outlines the issue: + +
+
+ module my_procs_mod + use ESMF + implicit none + + contains + + subroutine my_procs (...) + integer :: my_setting + : + call ESMF_GridCompSetEntryPoint(gridcomp, methodflag=ESMF_METHOD_INITIALIZE, & + userRoutine=my_grid_proc_init, rc=localrc) + : + my_setting = 42 + + contains + + subroutine my_grid_proc_init (gridcomp, importState, exportState, clock, rc) + : + ! my_setting is possibly uninitialized when my_grid_proc_init is used as a call-back + something = my_setting + : + end subroutine my_grid_proc_init + end subroutine my_procs + end module my_procs_mod ++ +
+The Fortran standard does not specify whether variable my_setting is statically or +automatically allocated, unless it is explicitly given the SAVE attribute. Thus there is no +guarantee that its value will persist after my_procs has finished. The SAVE attribute +is usually given to a variable via specifying a SAVE attribute in its delaration. However it can +also be inferred by initializing the variable in its declaration: + +
+
+ : + integer, save : my_setting + : ++ +
+or, + +
+
+ : + integer :: my_setting = 42 + : ++ +
+Because of the potential initialization issues, it is recommended that internal procedures +only be used as ESMF callbacks when the surrounding procedure is also active. + +
+In Earth system modeling, the most natural way to think about an ESMF +Gridded Component, or ESMF_GridComp, is as a piece of code +representing a particular physical domain, such as an atmospheric +model or an ocean model. Gridded Components may also represent individual +processes, such as radiation or chemistry. It's up to the application +writer to decide how deeply to “componentize.” + +
+Earth system software components tend to share a number of basic +features. Most ingest and produce a variety of physical fields, refer to +a (possibly noncontiguous) spatial region and a grid that is +partitioned across a set of computational resources, and require +a clock for things like stepping a governing set of PDEs forward in time. +Most can also be divided into distinct initialize, run, and finalize +computational phases. These common characteristics are used +within ESMF to define a Gridded Component data structure that +is tailored for Earth system modeling and yet is still flexible +enough to represent a variety of domains. + +
+A well designed Gridded Component does not store information +internally about how it couples to other Gridded Components. That +allows it to be used in different contexts without changes to source +code. The idea here is to avoid situations in which slightly +different versions of the same model source are maintained for use in +different contexts - standalone vs. coupled versions, for example. +Data is passed in and out of Gridded Components using an ESMF State, +this is described in Section 21.1. + +
+An ESMF Gridded Component has two parts, one which is user-written +and another which is part of the framework. The user-written +part is software that represents a physical domain or performs some +other computational function. It forms the body of the Gridded +Component. It may be a piece of legacy code, or it may be developed +expressly for use with ESMF. It must contain routines with +standard ESMF interfaces that can be called to initialize, run, and +finalize the Gridded Component. These routines can have separate +callable phases, such as distinct first and second initialization steps. + +
+ESMF provides the Gridded Component derived type, +ESMF_GridComp. An ESMF_GridComp must be created +for every portion of the application that will be represented +as a separate component. For example, in a climate model, there may +be Gridded Components representing the land, ocean, sea ice, and +atmosphere. If the application contains an ensemble of identical +Gridded Components, every one has its own associated ESMF_GridComp. +Each Gridded Component has its own name and is allocated +a set of computational resources, in the form of an ESMF Virtual +Machine, or VM. + +
+The user-written part of a Gridded Component is associated with an +ESMF_GridComp derived type through a routine called +ESMF_SetServices(). +This is a routine that the user must write, and declare public. +Inside the SetServices routine the user must call +ESMF_SetEntryPoint() methods that associate a standard ESMF +operation with the name of the corresponding Fortran subroutine +in their user code. + +
+A Gridded Component is a computational entity which consumes and produces data. It uses a State object to exchange data between itself and other Components. It uses a Clock object to manage time, and a VM to describe its own and its child components' computational resources. + +
+This section shows how to create Gridded Components. For demonstrations +of the use of Gridded Components, see the system tests that are bundled with the ESMF software +distribution. These can be found in the directory esmf/src/system_tests. + +
+ +
+ +
+ +
+ +
+Every ESMF_GridComp is required to provide and document + a public set services routine. It can have any name, but must + follow the declaration below: a subroutine which takes an + ESMF_GridComp as the first argument, and + an integer return code as the second. + Both arguments are required and must not be declared as + optional. If an intent is specified in the interface it must be + intent(inout) for the first and intent(out) for the + second argument. + +
+The set services routine must call the ESMF method + ESMF_GridCompSetEntryPoint() to + register with the framework what user-code subroutines should be called + to initialize, run, and finalize the component. There are + additional routines which can be registered as well, for checkpoint + and restart functions. + +
+Note that the actual subroutines being registered do not have to be + public to this module; only the set services routine itself must + be available to be used by other code. +
+
+ ! Example Gridded Component + module ESMF_GriddedCompEx + + ! ESMF Framework module + use ESMF + implicit none + public GComp_SetServices + public GComp_SetVM + + contains + + subroutine GComp_SetServices(comp, rc) + type(ESMF_GridComp) :: comp ! must not be optional + integer, intent(out) :: rc ! must not be optional + + ! Set the entry points for standard ESMF Component methods + call ESMF_GridCompSetEntryPoint(comp, ESMF_METHOD_INITIALIZE, & + userRoutine=GComp_Init, rc=rc) + call ESMF_GridCompSetEntryPoint(comp, ESMF_METHOD_RUN, & + userRoutine=GComp_Run, rc=rc) + call ESMF_GridCompSetEntryPoint(comp, ESMF_METHOD_FINALIZE, & + userRoutine=GComp_Final, rc=rc) + + rc = ESMF_SUCCESS + + end subroutine ++ +
+ +
+ +
+When a higher level component is ready to begin using an + ESMF_GridComp, it will call its initialize routine. + +
+The component writer must supply a subroutine with the exact interface + shown below. Arguments must not be declared as optional, and the types and + order must match. + +
+At initialization time the component can allocate data space, open + data files, set up initial conditions; anything it needs to do to + prepare to run. + +
+The rc return code should be set if an error occurs, otherwise + the value ESMF_SUCCESS should be returned. +
+
+ subroutine GComp_Init(comp, importState, exportState, clock, rc) + type(ESMF_GridComp) :: comp ! must not be optional + type(ESMF_State) :: importState ! must not be optional + type(ESMF_State) :: exportState ! must not be optional + type(ESMF_Clock) :: clock ! must not be optional + integer, intent(out) :: rc ! must not be optional + + print *, "Gridded Comp Init starting" + + ! This is where the model specific setup code goes. + + ! If the initial Export state needs to be filled, do it here. + !call ESMF_StateAdd(exportState, field, rc) + !call ESMF_StateAdd(exportState, bundle, rc) + print *, "Gridded Comp Init returning" + + rc = ESMF_SUCCESS + + end subroutine GComp_Init ++ +
+ +
+ +
+During the execution loop, the run routine may be called many times. + Each time it should read data from the importState, use the + clock to determine what the current time is in the calling + component, compute new values or process the data, + and produce any output and place it in the exportState. + +
+When a higher level component is ready to use the ESMF_GridComp + it will call its run routine. + +
+The component writer must supply a subroutine with the exact interface + shown below. Arguments must not be declared as optional, and the types and + order must match. + +
+It is expected that this is where the bulk of the model computation + or data analysis will occur. + +
+The rc return code should be set if an error occurs, otherwise + the value ESMF_SUCCESS should be returned. +
+
+ subroutine GComp_Run(comp, importState, exportState, clock, rc) + type(ESMF_GridComp) :: comp ! must not be optional + type(ESMF_State) :: importState ! must not be optional + type(ESMF_State) :: exportState ! must not be optional + type(ESMF_Clock) :: clock ! must not be optional + integer, intent(out) :: rc ! must not be optional + + print *, "Gridded Comp Run starting" + ! call ESMF_StateGet(), etc to get fields, bundles, arrays + ! from import state. + + ! This is where the model specific computation goes. + + ! Fill export state here using ESMF_StateAdd(), etc + + print *, "Gridded Comp Run returning" + + rc = ESMF_SUCCESS + + end subroutine GComp_Run ++ +
+ +
+ +
+At the end of application execution, each ESMF_GridComp should + deallocate data space, close open files, and flush final results. + These functions should be placed in a finalize routine. + +
+The component writer must supply a subroutine with the exact interface + shown below. Arguments must not be declared as optional, and the types and + order must match. + +
+The rc return code should be set if an error occurs, otherwise + the value ESMF_SUCCESS should be returned. + +
+
+ subroutine GComp_Final(comp, importState, exportState, clock, rc) + type(ESMF_GridComp) :: comp ! must not be optional + type(ESMF_State) :: importState ! must not be optional + type(ESMF_State) :: exportState ! must not be optional + type(ESMF_Clock) :: clock ! must not be optional + integer, intent(out) :: rc ! must not be optional + + print *, "Gridded Comp Final starting" + + ! Add whatever code here needed + + print *, "Gridded Comp Final returning" + + rc = ESMF_SUCCESS + + end subroutine GComp_Final ++ +
+ +
+ +
+Every ESMF_GridComp can optionally provide and document + a public set vm routine. It can have any name, but must + follow the declaration below: a subroutine which takes an + ESMF_GridComp as the first argument, and + an integer return code as the second. + Both arguments are required and must not be declared as + optional. If an intent is specified in the interface it must be + intent(inout) for the first and intent(out) for the + second argument. + +
+The set vm routine is the only place where the child component can + use the ESMF_GridCompSetVMMaxPEs(), or + ESMF_GridCompSetVMMaxThreads(), or + ESMF_GridCompSetVMMinThreads() call to modify aspects of its own VM. + +
+A component's VM is started up right before its set services routine is + entered. ESMF_GridCompSetVM() is executing in the parent VM, and must + be called before ESMF_GridCompSetServices(). +
+
+ subroutine GComp_SetVM(comp, rc) + type(ESMF_GridComp) :: comp ! must not be optional + integer, intent(out) :: rc ! must not be optional + + type(ESMF_VM) :: vm + logical :: pthreadsEnabled + + ! Test for Pthread support, all SetVM calls require it + call ESMF_VMGetGlobal(vm, rc=rc) + call ESMF_VMGet(vm, pthreadsEnabledFlag=pthreadsEnabled, rc=rc) + + if (pthreadsEnabled) then + ! run PETs single-threaded + call ESMF_GridCompSetVMMinThreads(comp, rc=rc) + endif + + rc = ESMF_SUCCESS + + end subroutine + + end module ESMF_GriddedCompEx ++ +
+ + +
+ +
+ +
+ +
+ESMF provides the concept of an Internal State that is associated with + a Component. Through the Internal State API a user can attach a private + data block to a Component, and later retrieve a pointer to this memory + allocation. Setting and getting of Internal State information are + supported from anywhere in the Component's SetServices, Initialize, Run, + or Finalize code. + +
+The code below demonstrates the basic Internal State API + of ESMF_<Grid|Cpl>SetInternalState() and + ESMF_<Grid|Cpl>GetInternalState(). Notice that an extra level of + indirection to the user data is necessary! + +
+
+ ! ESMF Framework module + use ESMF + use ESMF_TestMod + implicit none + + type(ESMF_GridComp) :: comp + integer :: rc, finalrc + + ! Internal State Variables + type testData + sequence + integer :: testValue + real :: testScaling + end type + + type dataWrapper + sequence + type(testData), pointer :: p + end type + + type(dataWrapper) :: wrap1, wrap2 + type(testData), target :: data + type(testData), pointer :: datap ! extra level of indirection ++ +
+
+!------------------------------------------------------------------------- + + call ESMF_Initialize(defaultlogfilename="InternalStateEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + +!------------------------------------------------------------------------- + + ! Creation of a Component + comp = ESMF_GridCompCreate(name="test", rc=rc) + if (rc .ne. ESMF_SUCCESS) finalrc = ESMF_FAILURE + +!------------------------------------------------------------------------- +! This could be called, for example, during a Component's initialize phase. + + ! Initialize private data block + data%testValue = 4567 + data%testScaling = 0.5 + + ! Set Internal State + wrap1%p => data + call ESMF_GridCompSetInternalState(comp, wrap1, rc) + if (rc .ne. ESMF_SUCCESS) finalrc = ESMF_FAILURE + +!------------------------------------------------------------------------- +! This could be called, for example, during a Component's run phase. + + ! Get Internal State + call ESMF_GridCompGetInternalState(comp, wrap2, rc) + if (rc .ne. ESMF_SUCCESS) finalrc = ESMF_FAILURE + + ! Access private data block and verify data + datap => wrap2%p + if ((datap%testValue .ne. 4567) .or. (datap%testScaling .ne. 0.5)) then + print *, "did not get same values back" + finalrc = ESMF_FAILURE + else + print *, "got same values back from GetInternalState as original" + endif ++ +
+ + +
+ +
+ +
+When working with ESMF Internal States it is important to consider the + applying scoping rules. The user must ensure that the private data block + that is being referenced persists for the entire access period. This is + not an issue in the previous example, where the private data block was + defined on the scope of the main program. However, the Internal State + construct is often useful inside of Component modules to hold Component + specific data between calls. One option to ensure persisting private data + blocks is to use the Fortran SAVE attribute either on local or module + variables. A second option, illustrated in the following example, is to + use Fortran pointers and user controlled memory management via allocate() + and deallocate() calls. + +
+One situation where the Internal State is useful is in the + creation of ensembles of the same Component. In this case it can + be tricky to distinguish which data, held in saved module variables, + belongs to which ensemble member - especially if the ensemble members + are executing on the same set of PETs. The Internal State solves this + problem by providing a handle to instance specific data allocations. + +
+
+module user_mod + + use ESMF + + implicit none + + ! module variables + private + + ! Internal State Variables + type testData + sequence + integer :: testValue ! scalar data + real :: testScaling ! scalar data + real, pointer :: testArray(:) ! array data + end type + + type dataWrapper + sequence + type(testData), pointer :: p + end type ++ +
+
+ contains !-------------------------------------------------------------- ++ +
+
+ subroutine mygcomp_init(gcomp, istate, estate, clock, rc) + type(ESMF_GridComp):: gcomp + type(ESMF_State):: istate, estate + type(ESMF_Clock):: clock + integer, intent(out):: rc + + ! Local variables + type(dataWrapper) :: wrap + type(testData), pointer :: data + integer :: i + + rc = ESMF_SUCCESS + + ! Allocate private data block + allocate(data) + + ! Initialize private data block + data%testValue = 4567 ! initialize scalar data + data%testScaling = 0.5 ! initialize scalar data + allocate(data%testArray(10)) ! allocate array data + + do i=1, 10 + data%testArray(i) = real(i) ! initialize array data + enddo + + ! In a real ensemble application the initial data would be set to + ! something unique for this ensemble member. This could be + ! accomplished for example by reading a member specific config file + ! that was specified by the driver code. Alternatively, Attributes, + ! set by the driver, could be used to label the Component instances + ! as specific ensemble members. + + ! Set Internal State + wrap%p => data + call ESMF_GridCompSetInternalState(gcomp, wrap, rc) + + end subroutine !------------------------------------------------------- + + subroutine mygcomp_run(gcomp, istate, estate, clock, rc) + type(ESMF_GridComp):: gcomp + type(ESMF_State):: istate, estate + type(ESMF_Clock):: clock + integer, intent(out):: rc + + ! Local variables + type(dataWrapper) :: wrap + type(testData), pointer :: data + logical :: match = .true. + integer :: i + + rc = ESMF_SUCCESS + + ! Get Internal State + call ESMF_GridCompGetInternalState(gcomp, wrap, rc) + if (rc/=ESMF_SUCCESS) return + + ! Access private data block and verify data + data => wrap%p + if (data%testValue .ne. 4567) match = .false. ! test scalar data + if (data%testScaling .ne. 0.5) match = .false. ! test scalar data + do i=1, 10 + if (data%testArray(i) .ne. real(i)) match = .false. ! test array data + enddo + + if (match) then + print *, "got same values back from GetInternalState as original" + else + print *, "did not get same values back" + rc = ESMF_FAILURE + endif + + end subroutine !------------------------------------------------------- + + subroutine mygcomp_final(gcomp, istate, estate, clock, rc) + type(ESMF_GridComp):: gcomp + type(ESMF_State):: istate, estate + type(ESMF_Clock):: clock + integer, intent(out):: rc + + ! Local variables + type(dataWrapper) :: wrap + type(testData), pointer :: data + + rc = ESMF_SUCCESS + + ! Get Internal State + call ESMF_GridCompGetInternalState(gcomp, wrap, rc) + if (rc/=ESMF_SUCCESS) return + + ! Deallocate private data block + data => wrap%p + deallocate(data%testArray) ! deallocate array data + deallocate(data) + + end subroutine !-------------------------------------------------------------- + + +end module ++ +
+ + +
+ +
+
+
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + gridcomp1 = gridcomp2 +ARGUMENTS: +
type(ESMF_GridComp) :: gridcomp1 + type(ESMF_GridComp) :: gridcomp2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign gridcomp1 as an alias to the same ESMF GridComp object in memory + as gridcomp2. If gridcomp2 is invalid, then gridcomp1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (gridcomp1 == gridcomp2) then ... endif + OR + result = (gridcomp1 == gridcomp2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: gridcomp1 + type(ESMF_GridComp), intent(in) :: gridcomp2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether gridcomp1 and gridcomp2 are valid aliases to the same ESMF + GridComp object in memory. For a more general comparison of two ESMF GridComps, + going beyond the simple alias test, the ESMF_GridCompMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (gridcomp1 /= gridcomp2) then ... endif + OR + result = (gridcomp1 /= gridcomp2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: gridcomp1 + type(ESMF_GridComp), intent(in) :: gridcomp2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether gridcomp1 and gridcomp2 are not valid aliases to the + same ESMF GridComp object in memory. For a more general comparison of two ESMF + GridComps, going beyond the simple alias test, the ESMF_GridCompMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive function ESMF_GridCompCreate(grid, gridList, & + mesh, meshList, locstream, locstreamList, xgrid, xgridList, & + hconfig, config, configFile, clock, petList, devList, contextflag, name, rc) +RETURN VALUE: +
type(ESMF_GridComp) :: ESMF_GridCompCreate +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Grid), intent(in), optional :: grid + type(ESMF_Grid), intent(in), optional :: gridList(:) + type(ESMF_Mesh), intent(in), optional :: mesh + type(ESMF_Mesh), intent(in), optional :: meshList(:) + type(ESMF_LocStream), intent(in), optional :: locstream + type(ESMF_LocStream), intent(in), optional :: locstreamList(:) + type(ESMF_XGrid), intent(in), optional :: xgrid + type(ESMF_XGrid), intent(in), optional :: xgridList(:) + type(ESMF_HConfig), intent(in), optional :: hconfig + type(ESMF_Config), intent(in), optional :: config + character(len=*), intent(in), optional :: configFile + type(ESMF_Clock), intent(in), optional :: clock + integer, intent(in), optional :: petList(:) + integer, intent(in), optional :: devList(:) + type(ESMF_Context_Flag), intent(in), optional :: contextflag + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This interface creates an ESMF_GridComp object. By default, a + separate VM context will be created for each component. This implies + creating a new MPI communicator and allocating additional memory to + manage the VM resources. When running on a large number of processors, + creating a separate VM for each component could be both time and memory + inefficient. If the application is sequential, i.e., each component is + running on all the PETs of the global VM, it will be more efficient to use + the global VM instead of creating a new one. This can be done by setting + contextflag to ESMF_CONTEXT_PARENT_VM. + +
+The return value is the new ESMF_GridComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_GridCompDestroy(gridcomp, & + timeout, timeoutFlag, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroys an ESMF_GridComp, releasing the resources associated + with the object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_GridCompFinalize(gridcomp, & + importState, exportState, clock, syncflag, phase, timeout, timeoutFlag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: phase + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Call the associated user-supplied finalization routine for + an ESMF_GridComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_GridCompGet(gridcomp, & + gridIsPresent, grid, gridList, meshIsPresent, mesh, meshList, & + locstreamIsPresent, locstream, locstreamList, xgridIsPresent, & + xgrid, xgridList, importStateIsPresent, importState, & + exportStateIsPresent, exportState, hconfigIsPresent, hconfig, & + configIsPresent, config, configFileIsPresent, configFile, & + clockIsPresent, clock, localPet, petCount, contextflag, & + currentMethod, currentPhase, comptype, vmIsPresent, vm, name, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(out), optional :: gridIsPresent + type(ESMF_Grid), intent(out), optional :: grid + type(ESMF_Grid), allocatable, intent(out), optional :: gridList(:) + logical, intent(out), optional :: meshIsPresent + type(ESMF_Mesh), intent(out), optional :: mesh + type(ESMF_Mesh), allocatable, intent(out), optional :: meshList(:) + logical, intent(out), optional :: locstreamIsPresent + type(ESMF_LocStream), intent(out), optional :: locstream + type(ESMF_LocStream), allocatable, intent(out), optional :: locstreamList(:) + logical, intent(out), optional :: xgridIsPresent + type(ESMF_XGrid), intent(out), optional :: xgrid + type(ESMF_XGrid), allocatable, intent(out), optional :: xgridList(:) + logical, intent(out), optional :: importStateIsPresent + type(ESMF_State), intent(out), optional :: importState + logical, intent(out), optional :: exportStateIsPresent + type(ESMF_State), intent(out), optional :: exportState + logical, intent(out), optional :: hconfigIsPresent + type(ESMF_HConfig), intent(out), optional :: hconfig + logical, intent(out), optional :: configIsPresent + type(ESMF_Config), intent(out), optional :: config + logical, intent(out), optional :: configFileIsPresent + character(len=*), intent(out), optional :: configFile + logical, intent(out), optional :: clockIsPresent + type(ESMF_Clock), intent(out), optional :: clock + integer, intent(out), optional :: localPet + integer, intent(out), optional :: petCount + type(ESMF_Context_Flag), intent(out), optional :: contextflag + type(ESMF_Method_Flag), intent(out), optional :: currentMethod + integer, intent(out), optional :: currentPhase + type(ESMF_CompType_Flag), intent(out), optional :: comptype + logical, intent(out), optional :: vmIsPresent + type(ESMF_VM), intent(out), optional :: vm + character(len=*), intent(out), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get information about an ESMF_GridComp object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridCompGetInternalState(gridcomp, wrappedDataPointer, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: gridcomp + type(wrapper) :: wrappedDataPointer + integer, intent(out) :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Available to be called by an ESMF_GridComp at any time after + ESMF_GridCompSetInternalState has been called. + Since init, run, and finalize must be separate subroutines, data that + they need to share in common can either be module global data, or can + be allocated in a private data block and the address of that block + can be registered with the framework and retrieved by this call. + When running multiple instantiations of an ESMF_GridComp, + for example during ensemble runs, + it may be simpler to maintain private data specific to + each run with private data blocks. A corresponding + ESMF_GridCompSetInternalState call sets the data pointer to + this block, and this call retrieves the data pointer. + Note that the wrappedDataPointer argument needs to be a derived type + which contains only a pointer of the type of the data block defined + by the user. When making this call the pointer needs to be unassociated. + When the call returns, the pointer will now reference the original + data block which was set during the previous call to + ESMF_GridCompSetInternalState. + +
+Only the last data block set via + ESMF_GridCompSetInternalState will be accessible. + +
+CAUTION: If you are working with a compiler that does not support Fortran 2018 + assumed-type dummy arguments, then this method does not have an explicit + Fortran interface. In this case do not specify argument keywords when calling + this method! + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_GridCompInitialize(gridcomp, & + importState, exportState, clock, syncflag, phase, timeout, timeoutFlag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: phase + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Call the associated user initialization routine for + an ESMF_GridComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_GridCompIsCreated(gridcomp, rc) +RETURN VALUE: +
logical :: ESMF_GridCompIsCreated +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the gridcomp has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive function ESMF_GridCompIsPetLocal(gridcomp, rc) +RETURN VALUE: +
logical :: ESMF_GridCompIsPetLocal +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Inquire if this ESMF_GridComp object is to execute on the calling PET. + +
+The return value is .true. if the component is to execute on the + calling PET, .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridCompPrint(gridcomp, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Prints information about an ESMF_GridComp to stdout.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_GridCompReadRestart(gridcomp, & + importState, exportState, clock, syncflag, phase, timeout, timeoutFlag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: phase + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Call the associated user read restart routine for + an ESMF_GridComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_GridCompRun(gridcomp, & + importState, exportState, clock, syncflag, phase, timeout, timeoutFlag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: phase + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Call the associated user run routine for + an ESMF_GridComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_GridCompServiceLoop(gridcomp, & + importState, exportState, clock, syncflag, port, timeout, timeoutFlag, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: port + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Call the ServiceLoop routine for an ESMF_GridComp. + This tries to establish a "component tunnel" between the actual + Component (calling this routine) and a dual Component connecting to it + through a matching SetServices call. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridCompSet(gridcomp, grid, gridList, & + mesh, meshList, locstream, locstreamList, xgrid, xgridList, & + hconfig, config, configFile, clock, name, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Grid), intent(in), optional :: grid + type(ESMF_Grid), intent(in), optional :: gridList(:) + type(ESMF_Mesh), intent(in), optional :: mesh + type(ESMF_Mesh), intent(in), optional :: meshList(:) + type(ESMF_LocStream), intent(in), optional :: locstream + type(ESMF_LocStream), intent(in), optional :: locstreamList(:) + type(ESMF_XGrid), intent(in), optional :: xgrid + type(ESMF_XGrid), intent(in), optional :: xgridList(:) + type(ESMF_HConfig), intent(in), optional :: hconfig + type(ESMF_Config), intent(in), optional :: config + character(len=*), intent(in), optional :: configFile + type(ESMF_Clock), intent(in), optional :: clock + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets or resets information about an ESMF_GridComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_GridCompSetEntryPoint(gridcomp, methodflag, & + userRoutine, phase, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + type(ESMF_Method_Flag), intent(in) :: methodflag + interface + subroutine userRoutine(gridcomp, importState, exportState, clock, rc) + use ESMF_CompMod + use ESMF_StateMod + use ESMF_ClockMod + implicit none + type(ESMF_GridComp) :: gridcomp ! must not be optional + type(ESMF_State) :: importState ! must not be optional + type(ESMF_State) :: exportState ! must not be optional + type(ESMF_Clock) :: clock ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: phase + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Registers a user-supplied userRoutine as the entry point for one of the + predefined Component methodflags. After this call the userRoutine + becomes accessible via the standard Component method API. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridCompSetInternalState(gridcomp, wrappedDataPointer, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: gridcomp + type(wrapper) :: wrappedDataPointer + integer, intent(out) :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Available to be called by an ESMF_GridComp at any time, but + expected to be + most useful when called during the registration process, or initialization. + Since init, run, and finalize must be separate subroutines, data that + they need to share in common can either be module global data, or can + be allocated in a private data block and the address of that block + can be registered with the framework and retrieved by subsequent calls. + When running multiple instantiations of an ESMF_GridComp, + for example during + ensemble runs, it may be simpler to maintain private data specific to + each run with private data blocks. A corresponding + ESMF_GridCompGetInternalState call retrieves the data pointer. + +
+Only the last data block set via + ESMF_GridCompSetInternalState will be accessible. + +
+CAUTION: If you are working with a compiler that does not support Fortran 2018 + assumed-type dummy arguments, then this method does not have an explicit + Fortran interface. In this case do not specify argument keywords when calling + this method! + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_GridCompSetServices(gridcomp, & + userRoutine, userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + interface + subroutine userRoutine(gridcomp, rc) + use ESMF_CompMod + implicit none + type(ESMF_GridComp) :: gridcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+ Call into user provided userRoutine which is responsible for + setting Component's Initialize(), Run(), and Finalize() services. + +
+The arguments are: +
+The userRoutine, when called by the framework, must make successive calls + to ESMF_GridCompSetEntryPoint() to preset callback routines for + standard Component Initialize(), Run(), and Finalize() methods. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCompSetServices() + recursive subroutine ESMF_GridCompSetServicesShObj(gridcomp, userRoutine, & + sharedObj, userRoutineFound, userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + character(len=*), intent(in) :: userRoutine + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: sharedObj + logical, intent(out), optional :: userRoutineFound + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+ Call into a user provided routine which is responsible for setting + Component's Initialize(), Run(), and Finalize() services. The named + userRoutine must exist in the executable, or in the shared object + specified by sharedObj. In the latter case all of the platform + specific details about dynamic linking and loading apply. + +
+The arguments are: +
+ +
+
+INTERFACE:
+
interface + subroutine userRoutine(gridcomp, rc) + type(ESMF_GridComp) :: gridcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface ++DESCRIPTION: +
+The userRoutine, when called by the framework, must make successive calls + to ESMF_GridCompSetEntryPoint() to preset callback routines for + standard Component Initialize(), Run(), and Finalize() methods. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCompSetServices() + recursive subroutine ESMF_GridCompSetServicesComp(gridcomp, & + actualGridcomp, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + type(ESMF_GridComp), intent(in) :: actualGridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the services of a Gridded Component to serve a "dual" Component for an + "actual" Component. The component tunnel is VM based. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCompSetServices() + recursive subroutine ESMF_GridCompSetServicesSock(gridcomp, port, & + server, timeout, timeoutFlag, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + integer, intent(in) :: port + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: server + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the services of a Gridded Component to serve a "dual" Component for an + "actual" Component. The component tunnel is socket based. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_GridCompSetVM(gridcomp, userRoutine, & + userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + interface + subroutine userRoutine(gridcomp, rc) + use ESMF_CompMod + implicit none + type(ESMF_GridComp) :: gridcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Optionally call into user provided userRoutine which is responsible + for setting Component's VM properties. + +
+The arguments are: +
+The subroutine, when called by the framework, is expected to use any of the + ESMF_GridCompSetVMxxx() methods to set the properties of the VM + associated with the Gridded Component. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCompSetVM() + recursive subroutine ESMF_GridCompSetVMShObj(gridcomp, userRoutine, & + sharedObj, userRoutineFound, userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + character(len=*), intent(in) :: userRoutine + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: sharedObj + logical, intent(out), optional :: userRoutineFound + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Optionally call into user provided userRoutine which is responsible + for setting Component's VM properties. The named + userRoutine must exist in the executable, or in the shared object + specified by sharedObj. In the latter case all of the platform + specific details about dynamic linking and loading apply. + +
+The arguments are: +
+ +
+
+INTERFACE:
+
interface + subroutine userRoutine(gridcomp, rc) + type(ESMF_GridComp) :: gridcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface ++DESCRIPTION: +
+The subroutine, when called by the framework, is expected to use any of the + ESMF_GridCompSetVMxxx() methods to set the properties of the VM + associated with the Gridded Component. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridCompSetVMMaxPEs(gridcomp, & + maxPeCountPerPet, prefIntraProcess, prefIntraSsi, prefInterSsi, & + pthreadMinStackSize, openMpHandling, openMpNumThreads, & + forceChildPthreads, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: maxPeCountPerPet + integer, intent(in), optional :: prefIntraProcess + integer, intent(in), optional :: prefIntraSsi + integer, intent(in), optional :: prefInterSsi + integer, intent(in), optional :: pthreadMinStackSize + character(*), intent(in), optional :: openMpHandling + integer, intent(in), optional :: openMpNumThreads + logical, intent(in), optional :: forceChildPthreads + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set characteristics of the ESMF_VM for this ESMF_GridComp. + Attempts to associate up to maxPeCountPerPet PEs with each PET. Only + PEs that are located on the same single system image (SSI) can be associated + with the same PET. Within this constraint the call tries to get as close as + possible to the number specified by maxPeCountPerPet. + +
+The other constraint to this call is that the number of PEs is preserved. + This means that the child Component in the end is associated with as many + PEs as the parent Component provided to the child. The number of child PETs + however is adjusted according to the above rule. + +
+The typical use of ESMF_GridCompSetVMMaxPEs() is to allocate + multiple PEs per PET in a Component for user-level threading, e.g. OpenMP. + +
+The arguments are: +
+For cases where OpenMP threads + are used by the user code, each thread allocates its own private stack. For + all threads other than the master, the stack size is set via the + typical OMP_STACKSIZE environment variable mechanism. The PET itself, + however, becomes the master of the OpenMP thread team, and is not + affected by OMP_STACKSIZE. It is the master's stack that can be + sized via the pthreadMinStackSize argument, and a large enough size + is often critical. + +
+When pthreadMinStackSize + is absent, the default is to use the system default + set by the limit or ulimit command. However, the stack of a + Pthread cannot be unlimited, and a shell stacksize setting of + unlimited, or any setting below the ESMF implemented minimum, + will result in setting the stack size to 20MiB (the ESMF minimum). + Depending on how much private data is used by the user code under + the master thread, the default might be too small, and + pthreadMinStackSize must be used to allocate sufficient stack space. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridCompSetVMMaxThreads(gridcomp, & + maxPetCountPerVas, prefIntraProcess, prefIntraSsi, prefInterSsi, & + pthreadMinStackSize, forceChildPthreads, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: maxPetCountPerVas + integer, intent(in), optional :: prefIntraProcess + integer, intent(in), optional :: prefIntraSsi + integer, intent(in), optional :: prefInterSsi + integer, intent(in), optional :: pthreadMinStackSize + logical, intent(in), optional :: forceChildPthreads + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set characteristics of the ESMF_VM for this ESMF_GridComp. + Attempts to provide maxPetCountPerVas threaded PETs in each + virtual address space (VAS). Only as many threaded PETs as there are PEs + located on the single system image (SSI) can be associated with the VAS. + Within this constraint the call tries to get as close as possible to the + number specified by maxPetCountPerVas. + +
+The other constraint to this call is that the number of PETs is preserved. + This means that the child Component in the end is associated with as many + PETs as the parent Component provided to the child. The threading level of + the child PETs however is adjusted according to the above rule. + +
+The typical use of ESMF_GridCompSetVMMaxThreads() is to run a + Component multi-threaded with groups of PETs executing within a common + virtual address space. + +
+The arguments are: +
+For cases where OpenMP threads + are used by the user code, each thread allocates its own private stack. For + all threads other than the master, the stack size is set via the + typical OMP_STACKSIZE environment variable mechanism. The PET itself, + however, becomes the master of the OpenMP thread team, and is not + affected by OMP_STACKSIZE. It is the master's stack that can be + sized via the pthreadMinStackSize argument, and a large enough size + is often critical. + +
+When pthreadMinStackSize + is absent, the default is to use the system default + set by the limit or ulimit command. However, the stack of a + Pthread cannot be unlimited, and a shell stacksize setting of + unlimited, or any setting below the ESMF implemented minimum, + will result in setting the stack size to 20MiB (the ESMF minimum). + Depending on how much private data is used by the user code under + the master thread, the default might be too small, and + pthreadMinStackSize must be used to allocate sufficient stack space. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridCompSetVMMinThreads(gridcomp, & + maxPeCountPerPet, prefIntraProcess, prefIntraSsi, prefInterSsi, & + pthreadMinStackSize, forceChildPthreads, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: maxPeCountPerPet + integer, intent(in), optional :: prefIntraProcess + integer, intent(in), optional :: prefIntraSsi + integer, intent(in), optional :: prefInterSsi + integer, intent(in), optional :: pthreadMinStackSize + logical, intent(in), optional :: forceChildPthreads + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set characteristics of the ESMF_VM for this ESMF_GridComp. + Reduces the number of threaded PETs in each VAS. The max argument + may be specified to limit the maximum number of PEs that a single PET + can be associated with. + +
+Several constraints apply: 1) the number of PEs cannot change, 2) PEs + cannot migrate between single system images (SSIs), 3) the number of PETs + cannot increase, only decrease, 4) PETs cannot migrate between virtual + address spaces (VASs), nor can VASs migrate between SSIs. + +
+The typical use of ESMF_GridCompSetVMMinThreads() is to run a + Component across a set of single-threaded PETs. + +
+The arguments are: +
+For cases where OpenMP threads + are used by the user code, each thread allocates its own private stack. For + all threads other than the master, the stack size is set via the + typical OMP_STACKSIZE environment variable mechanism. The PET itself, + however, becomes the master of the OpenMP thread team, and is not + affected by OMP_STACKSIZE. It is the master's stack that can be + sized via the pthreadMinStackSize argument, and a large enough size + is often critical. + +
+When pthreadMinStackSize + is absent, the default is to use the system default + set by the limit or ulimit command. However, the stack of a + Pthread cannot be unlimited, and a shell stacksize setting of + unlimited, or any setting below the ESMF implemented minimum, + will result in setting the stack size to 20MiB (the ESMF minimum). + Depending on how much private data is used by the user code under + the master thread, the default might be too small, and + pthreadMinStackSize must be used to allocate sufficient stack space. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridCompValidate(gridcomp, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Currently all this method does is to check that the gridcomp + was created. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridCompWait(gridcomp, syncflag, & + timeout, timeoutFlag, userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+When executing asynchronously, wait for an ESMF_GridComp to return. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_GridCompWriteRestart(gridcomp, & + importState, exportState, clock, syncflag, phase, timeout, timeoutFlag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: gridcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: phase + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Call the associated user write restart routine for + an ESMF_GridComp. + +
+The arguments are: +
+ + +
+In a large, multi-component application such as a weather +forecasting or climate prediction system running within ESMF, +physical domains and major system functions are represented +as Gridded Components +(see Section 17.1). A Coupler Component, or +ESMF_CplComp, arranges and executes the data +transformations between the Gridded Components. Ideally, +Coupler Components should contain all the information +about inter-component communication for an application. +This enables the Gridded Components in the application to be +used in multiple contexts; that is, used in different coupled +configurations without changes to their source code. +For example, the same atmosphere might in one case be coupled +to an ocean in a hurricane prediction model, and to a +data assimilation system for numerical weather prediction in +another. A single Coupler Component can couple +two or more Gridded Components. + +
+Like Gridded Components, Coupler Components have two parts, one +that is provided by the user and another that is part of the +framework. The user-written portion of the software is the coupling +code necessary for a particular exchange between Gridded Components. +This portion of the Coupler Component code must be divided into +separately callable initialize, run, and finalize methods. The +interfaces for these methods are prescribed by ESMF. + +
+The term “user-written” is somewhat misleading here, since within +a Coupler Component the user can leverage ESMF infrastructure +software for regridding, redistribution, lower-level communications, +calendar management, and other functions. However, ESMF is unlikely +to offer all the software necessary to customize a data transfer +between Gridded Components. For instance, ESMF does not currently +offer tools for unit tranformations or time averaging operations, +so users must manage those operations themselves. + +
+The second part of a Coupler Component is the ESMF_CplComp +derived type within ESMF. The user must create one of these types +to represent a specific coupling function, such as the regular +transfer of data between a data assimilation system and an +atmospheric model. 2 +
+The user-written part of a Coupler Component is associated with an +ESMF_CplComp derived type through a routine called +ESMF_SetServices(). +This is a routine that the user must write and declare public. +Inside the ESMF_SetServices() routine the user must call +ESMF_SetEntryPoint() methods that associate a standard ESMF +operation with the name of the corresponding Fortran subroutine in +their user code. For example, a user routine called “couplerInit” +might be associated with the standard initialize routine in a +Coupler Component. + +
+A Coupler Component manages the transformation of data between Components. +It contains a list of State objects and the operations needed to +make them compatible, including such things as regridding and unit conversion. +Coupler Components are user-written, following prescribed ESMF interfaces +and, wherever desired, using ESMF infrastructure tools. + +
+ +
+ +
+ +
+Every ESMF_CplComp is required to provide and document + a public set services routine. It can have any name, but must + follow the declaration below: a subroutine which takes an + ESMF_CplComp as the first argument, and + an integer return code as the second. + Both arguments are required and must not be declared as + optional. If an intent is specified in the interface it must be + intent(inout) for the first and intent(out) for the + second argument. + +
+The set services routine must call the ESMF method + ESMF_CplCompSetEntryPoint() to + register with the framework what user-code subroutines should be called + to initialize, run, and finalize the component. There are + additional routines which can be registered as well, for checkpoint + and restart functions. + +
+Note that the actual subroutines being registered do not have to be + public to this module; only the set services routine itself must + be available to be used by other code. +
+
+ ! Example Coupler Component + module ESMF_CouplerEx + + ! ESMF Framework module + use ESMF + implicit none + public CPL_SetServices + + contains + + subroutine CPL_SetServices(comp, rc) + type(ESMF_CplComp) :: comp ! must not be optional + integer, intent(out) :: rc ! must not be optional + + ! Set the entry points for standard ESMF Component methods + call ESMF_CplCompSetEntryPoint(comp, ESMF_METHOD_INITIALIZE, & + userRoutine=CPL_Init, rc=rc) + call ESMF_CplCompSetEntryPoint(comp, ESMF_METHOD_RUN, & + userRoutine=CPL_Run, rc=rc) + call ESMF_CplCompSetEntryPoint(comp, ESMF_METHOD_FINALIZE, & + userRoutine=CPL_Final, rc=rc) + + rc = ESMF_SUCCESS + end subroutine ++ +
+ +
+ +
+When a higher level component is ready to begin using an + ESMF_CplComp, it will call its initialize routine. + +
+The component writer must supply a subroutine with the exact interface + shown below. Arguments must not be declared as optional, and the types and + order must match. + +
+At initialization time the component can allocate data space, open + data files, set up initial conditions; anything it needs to do to + prepare to run. + +
+The rc return code should be set if an error occurs, otherwise + the value ESMF_SUCCESS should be returned. +
+
+ subroutine CPL_Init(comp, importState, exportState, clock, rc) + type(ESMF_CplComp) :: comp ! must not be optional + type(ESMF_State) :: importState ! must not be optional + type(ESMF_State) :: exportState ! must not be optional + type(ESMF_Clock) :: clock ! must not be optional + integer, intent(out) :: rc ! must not be optional + + print *, "Coupler Init starting" + + ! Add whatever code here needed + ! Precompute any needed values, fill in any inital values + ! needed in Import States + + rc = ESMF_SUCCESS + + print *, "Coupler Init returning" + + end subroutine CPL_Init ++ +
+ +
+ +
+During the execution loop, the run routine may be called many times. + Each time it should read data from the importState, use the + clock to determine what the current time is in the calling + component, compute new values or process the data, + and produce any output and place it in the exportState. + +
+When a higher level component is ready to use the ESMF_CplComp + it will call its run routine. + +
+The component writer must supply a subroutine with the exact interface + shown below. Arguments must not be declared as optional, and the types and + order must match. + +
+It is expected that this is where the bulk of the model computation + or data analysis will occur. + +
+The rc return code should be set if an error occurs, otherwise + the value ESMF_SUCCESS should be returned. +
+
+ subroutine CPL_Run(comp, importState, exportState, clock, rc) + type(ESMF_CplComp) :: comp ! must not be optional + type(ESMF_State) :: importState ! must not be optional + type(ESMF_State) :: exportState ! must not be optional + type(ESMF_Clock) :: clock ! must not be optional + integer, intent(out) :: rc ! must not be optional + + print *, "Coupler Run starting" + + ! Add whatever code needed here to transform Export state data + ! into Import states for the next timestep. + + rc = ESMF_SUCCESS + + print *, "Coupler Run returning" + + end subroutine CPL_Run ++ +
+ +
+ +
+At the end of application execution, each ESMF_CplComp should + deallocate data space, close open files, and flush final results. + These functions should be placed in a finalize routine. + +
+The component writer must supply a subroutine with the exact interface + shown below. Arguments must not be declared as optional, and the types and + order must match. + +
+The rc return code should be set if an error occurs, otherwise + the value ESMF_SUCCESS should be returned. + +
+
+ subroutine CPL_Final(comp, importState, exportState, clock, rc) + type(ESMF_CplComp) :: comp ! must not be optional + type(ESMF_State) :: importState ! must not be optional + type(ESMF_State) :: exportState ! must not be optional + type(ESMF_Clock) :: clock ! must not be optional + integer, intent(out) :: rc ! must not be optional + + print *, "Coupler Final starting" + + ! Add whatever code needed here to compute final values and + ! finish the computation. + + rc = ESMF_SUCCESS + + print *, "Coupler Final returning" + + end subroutine CPL_Final ++ +
+ +
+ +
+Every ESMF_CplComp can optionally provide and document + a public set vm routine. It can have any name, but must + follow the declaration below: a subroutine which takes an + ESMF_CplComp as the first argument, and + an integer return code as the second. + Both arguments are required and must not be declared as + optional. If an intent is specified in the interface it must be + intent(inout) for the first and intent(out) for the + second argument. + +
+The set vm routine is the only place where the child component can + use the ESMF_CplCompSetVMMaxPEs(), or + ESMF_CplCompSetVMMaxThreads(), or + ESMF_CplCompSetVMMinThreads() call to modify aspects of its own VM. + +
+A component's VM is started up right before its set services routine is + entered. ESMF_CplCompSetVM() is executing in the parent VM, and must + be called before ESMF_CplCompSetServices(). +
+
+ subroutine GComp_SetVM(comp, rc) + type(ESMF_CplComp) :: comp ! must not be optional + integer, intent(out) :: rc ! must not be optional + + type(ESMF_VM) :: vm + logical :: pthreadsEnabled + + ! Test for Pthread support, all SetVM calls require it + call ESMF_VMGetGlobal(vm, rc=rc) + call ESMF_VMGet(vm, pthreadsEnabledFlag=pthreadsEnabled, rc=rc) + + if (pthreadsEnabled) then + ! run PETs single-threaded + call ESMF_CplCompSetVMMinThreads(comp, rc=rc) + endif + + rc = ESMF_SUCCESS + + end subroutine + + end module ESMF_CouplerEx ++ +
+ + +
+ +
+
+
+
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + cplcomp1 = cplcomp2 +ARGUMENTS: +
type(ESMF_CplComp) :: cplcomp1 + type(ESMF_CplComp) :: cplcomp2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign cplcomp1 as an alias to the same ESMF CplComp object in memory + as cplcomp2. If cplcomp2 is invalid, then cplcomp1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (cplcomp1 == cplcomp2) then ... endif + OR + result = (cplcomp1 == cplcomp2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: cplcomp1 + type(ESMF_CplComp), intent(in) :: cplcomp2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether cplcomp1 and cplcomp2 are valid aliases to the same ESMF + CplComp object in memory. For a more general comparison of two ESMF CplComps, + going beyond the simple alias test, the ESMF_CplCompMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (cplcomp1 /= cplcomp2) then ... endif + OR + result = (cplcomp1 /= cplcomp2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: cplcomp1 + type(ESMF_CplComp), intent(in) :: cplcomp2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether cplcomp1 and cplcomp2 are not valid aliases to the + same ESMF CplComp object in memory. For a more general comparison of two ESMF + CplComps, going beyond the simple alias test, the ESMF_CplCompMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive function ESMF_CplCompCreate(hconfig, config, & + configFile, clock, petList, devList, contextflag, name, rc) +RETURN VALUE: +
type(ESMF_CplComp) :: ESMF_CplCompCreate +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_HConfig), intent(in), optional :: hconfig + type(ESMF_Config), intent(in), optional :: config + character(len=*), intent(in), optional :: configFile + type(ESMF_Clock), intent(in), optional :: clock + integer, intent(in), optional :: petList(:) + integer, intent(in), optional :: devList(:) + type(ESMF_Context_Flag), intent(in), optional :: contextflag + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This interface creates an ESMF_CplComp object. By default, a + separate VM context will be created for each component. This implies + creating a new MPI communicator and allocating additional memory to + manage the VM resources. When running on a large number of processors, + creating a separate VM for each component could be both time and memory + inefficient. If the application is sequential, i.e., each component is + running on all the PETs of the global VM, it will be more efficient to use + the global VM instead of creating a new one. This can be done by setting + contextflag to ESMF_CONTEXT_PARENT_VM. + +
+The return value is the new ESMF_CplComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_CplCompDestroy(cplcomp, & + timeout, timeoutFlag, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroys an ESMF_CplComp, releasing the resources associated + with the object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_CplCompFinalize(cplcomp, & + importState, exportState, clock, syncflag, phase, timeout, timeoutFlag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: phase + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Call the associated user-supplied finalization routine for + an ESMF_CplComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CplCompGet(cplcomp, hconfigIsPresent, hconfig, & + configIsPresent, config, configFileIsPresent, configFile, clockIsPresent, clock, localPet, & + petCount, contextflag, currentMethod, currentPhase, vmIsPresent, & + vm, name, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(out), optional :: hconfigIsPresent + type(ESMF_HConfig), intent(out), optional :: hconfig + logical, intent(out), optional :: configIsPresent + type(ESMF_Config), intent(out), optional :: config + logical, intent(out), optional :: configFileIsPresent + character(len=*), intent(out), optional :: configFile + logical, intent(out), optional :: clockIsPresent + type(ESMF_Clock), intent(out), optional :: clock + integer, intent(out), optional :: localPet + integer, intent(out), optional :: petCount + type(ESMF_Context_Flag), intent(out), optional :: contextflag + type(ESMF_Method_Flag), intent(out), optional :: currentMethod + integer, intent(out), optional :: currentPhase + logical, intent(out), optional :: vmIsPresent + type(ESMF_VM), intent(out), optional :: vm + character(len=*), intent(out), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get information about an ESMF_CplComp object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CplCompGetInternalState(cplcomp, wrappedDataPointer, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: cplcomp + type(wrapper) :: wrappedDataPointer + integer, intent(out) :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Available to be called by an ESMF_CplComp at any time after + ESMF_CplCompSetInternalState has been called. + Since init, run, and finalize must be separate subroutines, data that + they need to share in common can either be module global data, or can + be allocated in a private data block and the address of that block + can be registered with the framework and retrieved by this call. + When running multiple instantiations of an ESMF_CplComp, + for example during ensemble runs, + it may be simpler to maintain private data specific to + each run with private data blocks. A corresponding + ESMF_CplCompSetInternalState call sets the data pointer to + this block, and this call retrieves the data pointer. + Note that the wrappedDataPointer argument needs to be a derived type + which contains only a pointer of the type of the data block defined + by the user. When making this call the pointer needs to be unassociated. + When the call returns, the pointer will now reference the original + data block which was set during the previous call to + ESMF_CplCompSetInternalState. + +
+Only the last data block set via + ESMF_CplCompSetInternalState will be accessible. + +
+CAUTION: If you are working with a compiler that does not support Fortran 2018 + assumed-type dummy arguments, then this method does not have an explicit + Fortran interface. In this case do not specify argument keywords when calling + this method! + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_CplCompInitialize(cplcomp, & + importState, exportState, clock, syncflag, phase, timeout, timeoutFlag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: phase + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Call the associated user initialization routine for + an ESMF_CplComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_CplCompIsCreated(cplcomp, rc) +RETURN VALUE: +
logical :: ESMF_CplCompIsCreated +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the cplcomp has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive function ESMF_CplCompIsPetLocal(cplcomp, rc) +RETURN VALUE: +
logical :: ESMF_CplCompIsPetLocal +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Inquire if this ESMF_CplComp object is to execute on the calling PET. + +
+The return value is .true. if the component is to execute on the + calling PET, .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CplCompPrint(cplcomp, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Prints information about an ESMF_CplComp to stdout.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_CplCompReadRestart(cplcomp, & + importState, exportState, clock, syncflag, phase, timeout, timeoutFlag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: phase + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Call the associated user read restart routine for + an ESMF_CplComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_CplCompRun(cplcomp, & + importState, exportState, clock, syncflag, phase, timeout, timeoutFlag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: phase + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Call the associated user run routine for + an ESMF_CplComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_CplCompServiceLoop(cplcomp, & + importState, exportState, clock, syncflag, port, timeout, timeoutFlag, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: port + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Call the ServiceLoop routine for an ESMF_CplComp. + This tries to establish a "component tunnel" between the actual + Component (calling this routine) and a dual Component connecting to it + through a matching SetServices call. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CplCompSet(cplcomp, hconfig, config, & + configFile, clock, name, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_HConfig), intent(in), optional :: hconfig + type(ESMF_Config), intent(in), optional :: config + character(len=*), intent(in), optional :: configFile + type(ESMF_Clock), intent(in), optional :: clock + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets or resets information about an ESMF_CplComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_CplCompSetEntryPoint(cplcomp, methodflag, & + userRoutine, phase, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + type(ESMF_Method_Flag), intent(in) :: methodflag + interface + subroutine userRoutine(cplcomp, importState, exportState, clock, rc) + use ESMF_CompMod + use ESMF_StateMod + use ESMF_ClockMod + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + type(ESMF_State) :: importState ! must not be optional + type(ESMF_State) :: exportState ! must not be optional + type(ESMF_Clock) :: clock ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: phase + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Registers a user-supplied userRoutine as the entry point for one of the + predefined Component methodflags. After this call the userRoutine + becomes accessible via the standard Component method API. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CplCompSetInternalState(cplcomp, wrappedDataPointer, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: cplcomp + type(wrapper) :: wrappedDataPointer + integer, intent(out) :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Available to be called by an ESMF_CplComp at any time, but + expected to be + most useful when called during the registration process, or initialization. + Since init, run, and finalize must be separate subroutines data that + they need to share in common can either be module global data, or can + be allocated in a private data block and the address of that block + can be registered with the framework and retrieved by subsequent calls. + When running multiple instantiations of an ESMF_CplComp, + for example during + ensemble runs, it may be simpler to maintain private data specific to + each run with private data blocks. A corresponding + ESMF_CplCompGetInternalState call retrieves the data pointer. + +
+Only the last data block set via + ESMF_CplCompSetInternalState will be accessible. + +
+CAUTION: If you are working with a compiler that does not support Fortran 2018 + assumed-type dummy arguments, then this method does not have an explicit + Fortran interface. In this case do not specify argument keywords when calling + this method! + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_CplCompSetServices(cplcomp, userRoutine, & + userRc, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + interface + subroutine userRoutine(cplcomp, rc) + use ESMF_CompMod + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+ Call into user provided userRoutine which is responsible + for setting Component's Initialize(), Run(), and Finalize() services. + +
+The arguments are: +
+The userRoutine, when called by the framework, must make successive calls to + ESMF_CplCompSetEntryPoint() to preset callback routines for standard + Component Initialize(), Run(), and Finalize() methods. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CplCompSetServices() + recursive subroutine ESMF_CplCompSetServicesShObj(cplcomp, userRoutine, & + sharedObj, userRoutineFound, userRc, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + character(len=*), intent(in) :: userRoutine + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: sharedObj + logical, intent(out), optional :: userRoutineFound + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+ Call into a user provided routine which is responsible for setting + Component's Initialize(), Run(), and Finalize() services. The named + userRoutine must exist in the executable, or in the shared object + specified by sharedObj. In the latter case all of the platform + specific details about dynamic linking and loading apply. + +
+The arguments are: +
+ +
+
+INTERFACE:
+
interface + subroutine userRoutine(cplcomp, rc) + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface ++DESCRIPTION: +
+The userRoutine, when called by the framework, must make successive + calls to ESMF_CplCompSetEntryPoint() to preset callback routines for + standard Component Initialize(), Run(), and Finalize() methods. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CplCompSetServices() + recursive subroutine ESMF_CplCompSetServicesComp(cplcomp, & + actualCplcomp, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + type(ESMF_CplComp), intent(in) :: actualCplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the services of a Coupler Component to serve a "dual" Component for an + "actual" Component. The component tunnel is VM based. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CplCompSetServices() + recursive subroutine ESMF_CplCompSetServicesSock(cplcomp, port, & + server, timeout, timeoutFlag, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + integer, intent(in) :: port + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: server + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the services of a Coupler Component to serve a "dual" Component for an + "actual" Component. The component tunnel is socket based. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_CplCompSetVM(cplcomp, userRoutine, & + userRc, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + interface + subroutine userRoutine(cplcomp, rc) + use ESMF_CompMod + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Optionally call into user provided userRoutine which is responsible + for setting Component's VM properties. + +
+The arguments are: +
+The subroutine, when called by the framework, is expected to use any of the + ESMF_CplCompSetVMxxx() methods to set the properties of the VM + associated with the Coupler Component. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CplCompSetVM() + recursive subroutine ESMF_CplCompSetVMShObj(cplcomp, userRoutine, & + sharedObj, userRoutineFound, userRc, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + character(len=*), intent(in) :: userRoutine + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: sharedObj + logical, intent(out), optional :: userRoutineFound + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Optionally call into user provided userRoutine which is responsible + for setting Component's VM properties. The named + userRoutine must exist in the executable, or in the shared object + specified by sharedObj. In the latter case all of the platform + specific details about dynamic linking and loading apply. + +
+The arguments are: +
+ +
+
+INTERFACE:
+
interface + subroutine userRoutine(cplcomp, rc) + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface ++DESCRIPTION: +
+The subroutine, when called by the framework, is expected to use any of the + ESMF_CplCompSetVMxxx() methods to set the properties of the VM + associated with the Coupler Component. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CplCompSetVMMaxPEs(cplcomp, & + maxPeCountPerPet, prefIntraProcess, prefIntraSsi, prefInterSsi, & + pthreadMinStackSize, forceChildPthreads, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: maxPeCountPerPet + integer, intent(in), optional :: prefIntraProcess + integer, intent(in), optional :: prefIntraSsi + integer, intent(in), optional :: prefInterSsi + integer, intent(in), optional :: pthreadMinStackSize + logical, intent(in), optional :: forceChildPthreads + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set characteristics of the ESMF_VM for this ESMF_CplComp. + Attempts to associate up to maxPeCountPerPet PEs with each PET. Only + PEs that are located on the same single system image (SSI) can be associated + with the same PET. Within this constraint the call tries to get as close as + possible to the number specified by maxPeCountPerPet. + +
+The other constraint to this call is that the number of PEs is preserved. + This means that the child Component in the end is associated with as many + PEs as the parent Component provided to the child. The number of child PETs + however is adjusted according to the above rule. + +
+The typical use of ESMF_CplCompSetVMMaxPEs() is to allocate + multiple PEs per PET in a Component for user-level threading, e.g. OpenMP. + +
+The arguments are: +
+For cases where OpenMP threads + are used by the user code, each thread allocates its own private stack. For + all threads other than the master, the stack size is set via the + typical OMP_STACKSIZE environment variable mechanism. The PET itself, + however, becomes the master of the OpenMP thread team, and is not + affected by OMP_STACKSIZE. It is the master's stack that can be + sized via the pthreadMinStackSize argument, and a large enough size + is often critical. + +
+When pthreadMinStackSize + is absent, the default is to use the system default + set by the limit or ulimit command. However, the stack of a + Pthread cannot be unlimited, and a shell stacksize setting of + unlimited, or any setting below the ESMF implemented minimum, + will result in setting the stack size to 20MiB (the ESMF minimum). + Depending on how much private data is used by the user code under + the master thread, the default might be too small, and + pthreadMinStackSize must be used to allocate sufficient stack space. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CplCompSetVMMaxThreads(cplcomp, & + maxPetCountPerVas, prefIntraProcess, prefIntraSsi, prefInterSsi, & + pthreadMinStackSize, forceChildPthreads, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: maxPetCountPerVas + integer, intent(in), optional :: prefIntraProcess + integer, intent(in), optional :: prefIntraSsi + integer, intent(in), optional :: prefInterSsi + integer, intent(in), optional :: pthreadMinStackSize + logical, intent(in), optional :: forceChildPthreads + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set characteristics of the ESMF_VM for this ESMF_CplComp. + Attempts to provide maxPetCountPerVas threaded PETs in each + virtual address space (VAS). Only as many threaded PETs as there are PEs + located on the single system image (SSI) can be associated with the VAS. + Within this constraint the call tries to get as close as possible to the + number specified by maxPetCountPerVas. + +
+The other constraint to this call is that the number of PETs is preserved. + This means that the child Component in the end is associated with as many + PETs as the parent Component provided to the child. The threading level of + the child PETs however is adjusted according to the above rule. + +
+The typical use of ESMF_CplCompSetVMMaxThreads() is to run a + Component multi-threaded with groups of PETs executing within a common + virtual address space. + +
+The arguments are: +
+For cases where OpenMP threads + are used by the user code, each thread allocates its own private stack. For + all threads other than the master, the stack size is set via the + typical OMP_STACKSIZE environment variable mechanism. The PET itself, + however, becomes the master of the OpenMP thread team, and is not + affected by OMP_STACKSIZE. It is the master's stack that can be + sized via the pthreadMinStackSize argument, and a large enough size + is often critical. + +
+When pthreadMinStackSize + is absent, the default is to use the system default + set by the limit or ulimit command. However, the stack of a + Pthread cannot be unlimited, and a shell stacksize setting of + unlimited, or any setting below the ESMF implemented minimum, + will result in setting the stack size to 20MiB (the ESMF minimum). + Depending on how much private data is used by the user code under + the master thread, the default might be too small, and + pthreadMinStackSize must be used to allocate sufficient stack space. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CplCompSetVMMinThreads(cplcomp, & + maxPeCountPerPet, prefIntraProcess, prefIntraSsi, prefInterSsi, & + pthreadMinStackSize, forceChildPthreads, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: maxPeCountPerPet + integer, intent(in), optional :: prefIntraProcess + integer, intent(in), optional :: prefIntraSsi + integer, intent(in), optional :: prefInterSsi + integer, intent(in), optional :: pthreadMinStackSize + logical, intent(in), optional :: forceChildPthreads + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set characteristics of the ESMF_VM for this ESMF_CplComp. + Reduces the number of threaded PETs in each VAS. The max argument + may be specified to limit the maximum number of PEs that a single PET + can be associated with. + +
+Several constraints apply: 1) the number of PEs cannot change, 2) PEs + cannot migrate between single system images (SSIs), 3) the number of PETs + cannot increase, only decrease, 4) PETs cannot migrate between virtual + address spaces (VASs), nor can VASs migrate between SSIs. + +
+The typical use of ESMF_CplCompSetVMMinThreads() is to run a + Component across a set of single-threaded PETs. + +
+The arguments are: +
+For cases where OpenMP threads + are used by the user code, each thread allocates its own private stack. For + all threads other than the master, the stack size is set via the + typical OMP_STACKSIZE environment variable mechanism. The PET itself, + however, becomes the master of the OpenMP thread team, and is not + affected by OMP_STACKSIZE. It is the master's stack that can be + sized via the pthreadMinStackSize argument, and a large enough size + is often critical. + +
+When pthreadMinStackSize + is absent, the default is to use the system default + set by the limit or ulimit command. However, the stack of a + Pthread cannot be unlimited, and a shell stacksize setting of + unlimited, or any setting below the ESMF implemented minimum, + will result in setting the stack size to 20MiB (the ESMF minimum). + Depending on how much private data is used by the user code under + the master thread, the default might be too small, and + pthreadMinStackSize must be used to allocate sufficient stack space. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CplCompValidate(cplcomp, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Currently all this method does is to check that the cplcomp + was created. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CplCompWait(cplcomp, syncflag, & + timeout, timeoutFlag, userRc, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+When executing asynchronously, wait for an ESMF_CplComp to return. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_CplCompWriteRestart(cplcomp, & + importState, exportState, clock, syncflag, phase, timeout, timeoutFlag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(inout) :: cplcomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_State), intent(inout), optional :: importState + type(ESMF_State), intent(inout), optional :: exportState + type(ESMF_Clock), intent(inout), optional :: clock + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + integer, intent(in), optional :: phase + integer, intent(in), optional :: timeout + logical, intent(out), optional :: timeoutFlag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Call the associated user write restart routine for + an ESMF_CplComp. + +
+The arguments are: +
+ + +
+In Earth system modeling, a particular piece of code representing a physical +domain, such as an atmospheric model or an ocean model, is typically +implemented as an ESMF Gridded Component, or ESMC_GridComp. +However, there are times when physical domains, or realms, need to be +represented, but aren't actual pieces of code, or software. These domains +can be implemented as ESMF Science Components, or ESMC_SciComp. + +
+Unlike Gridded and Coupler Components, Science Components are not associated +with software; they don't include execution routines such as initialize, +run and finalize. The main purpose of a Science Component +is to provide a container for Attributes within a Component hierarchy. + +
+A Science Component is a container object intended to represent scientific +domains, or realms, in an Earth Science Model. It's primary purpose is to +provide a means for representing Component metadata within a hierarchy of +Components, and it does this by being a container for Attributes as well +as other Components. + +
+ +
+ +
+ +
+This example illustrates the use of the ESMF_SciComp to attach Attributes + within a Component hierarchy. The hierarchy includes Coupler, Gridded, + and Science Components and Attributes are attached to the Science Components. + For demonstrable purposes, we'll add some CIM Component attributes to + the Gridded Component. + +
+Create the top 2 levels of the Component hierarchy. This example creates + a parent Coupler Component and 2 Gridded Components as children. + +
+
+ ! Create top-level Coupler Component + cplcomp = ESMF_CplCompCreate(name="coupler_component", rc=rc) + + ! Create Gridded Component for Atmosphere + atmcomp = ESMF_GridCompCreate(name="Atmosphere", rc=rc) + + ! Create Gridded Component for Ocean + ocncomp = ESMF_GridCompCreate(name="Ocean", rc=rc) ++ +
+Now add CIM Attribute packages to the Component. Also, add + a CIM Component Properties package, to contain two custom attributes. + +
+
+ convCIM = 'CIM 1.5' + purpComp = 'ModelComp' + purpProp = 'CompProp' + purpField = 'Inputs' + purpPlatform = 'Platform' + + convISO = 'ISO 19115' + purpRP = 'RespParty' + purpCitation = 'Citation' + + ! Add CIM Attribute package to the Science Component + call ESMF_AttributeAdd(atmcomp, convention=convCIM, & + purpose=purpComp, attpack=attpack, rc=rc) ++ +
+The Attribute package can also be retrieved in a multi-Component + setting like this: + +
+
+ call ESMF_AttributeGetAttPack(atmcomp, convCIM, purpComp, & + attpack=attpack, rc=rc) ++ +
+Now, add some CIM Component attributes to the Atmosphere Grid Component. + +
+
+ ! + ! Top-level model component attributes, set on gridded component + ! + call ESMF_AttributeSet(atmcomp, 'ShortName', 'EarthSys_Atmos', & + attpack=attpack, rc=rc) ++ +
+
+ call ESMF_AttributeSet(atmcomp, 'LongName', & + 'Earth System High Resolution Global Atmosphere Model', & + attpack=attpack, rc=rc) ++ +
+
+ call ESMF_AttributeSet(atmcomp, 'Description', & + 'EarthSys brings together expertise from the global ' // & + 'community in a concerted effort to develop coupled ' // & + 'climate models with increased horizontal resolutions. ' // & + 'Increasing the horizontal resolution of coupled climate ' // & + 'models will allow us to capture climate processes and ' // & + 'weather systems in much greater detail.', & + attpack=attpack, rc=rc) ++ +
+
+ call ESMF_AttributeSet(atmcomp, 'Version', '2.0', & + attpack=attpack, rc=rc) ++ +
+
+ call ESMF_AttributeSet(atmcomp, 'ReleaseDate', '2009-01-01T00:00:00Z', & + attpack=attpack, rc=rc) ++ +
+
+ call ESMF_AttributeSet(atmcomp, 'ModelType', 'aerosol', & + attpack=attpack, rc=rc) ++ +
+
+ call ESMF_AttributeSet(atmcomp, 'URL', & + 'www.earthsys.org', attpack=attpack, rc=rc) ++ +
+Now create a set of Science Components as a children of the Atmosphere + Gridded Component. The hierarchy is as follows: + +
+
+ ! + ! Atmosphere Dynamical Core Science Component + ! + dc_scicomp = ESMF_SciCompCreate(name="AtmosDynamicalCore", rc=rc) ++ +
+
+ call ESMF_AttributeAdd(dc_scicomp, & + convention=convCIM, purpose=purpComp, & + attpack=attpack, rc=rc) + + call ESMF_AttributeSet(dc_scicomp, "ShortName", "AtmosDynamicalCore", & + attpack=attpack, rc=rc) + call ESMF_AttributeSet(dc_scicomp, "LongName", & + "Atmosphere Dynamical Core", & + attpack=attpack, rc=rc) ++ +
+
+ purpSci = 'SciProp' + + dc_sciPropAtt(1) = 'TopBoundaryCondition' + dc_sciPropAtt(2) = 'HeatTreatmentAtTop' + dc_sciPropAtt(3) = 'WindTreatmentAtTop' + + call ESMF_AttributeAdd(dc_scicomp, & + convention=convCIM, purpose=purpSci, & + attrList=dc_sciPropAtt, & + attpack=attpack, rc=rc) + + call ESMF_AttributeSet(dc_scicomp, 'TopBoundaryCondition', & + 'radiation boundary condition', & + attpack=attpack, rc=rc) + call ESMF_AttributeSet(dc_scicomp, 'HeatTreatmentAtTop', & + 'some heat treatment', & + attpack=attpack, rc=rc) + call ESMF_AttributeSet(dc_scicomp, 'WindTreatmentAtTop', & + 'some wind treatment', & + attpack=attpack, rc=rc) ++ +
+
+ ! + ! Atmosphere Advection Science Component + ! + adv_scicomp = ESMF_SciCompCreate(name="AtmosAdvection", rc=rc) ++ +
+
+ call ESMF_AttributeAdd(adv_scicomp, & + convention=convCIM, purpose=purpComp, & + attpack=attpack, rc=rc) + + call ESMF_AttributeSet(adv_scicomp, "ShortName", "AtmosAdvection", & + attpack=attpack, rc=rc) + call ESMF_AttributeSet(adv_scicomp, "LongName", "Atmosphere Advection", & + attpack=attpack, rc=rc) ++ +
+
+ adv_sciPropAtt(1) = 'TracersSchemeName' + adv_sciPropAtt(2) = 'TracersSchemeCharacteristics' + adv_sciPropAtt(3) = 'MomentumSchemeName' + + call ESMF_AttributeAdd(adv_scicomp, & + convention=convCIM, purpose=purpSci, & + attrList=adv_sciPropAtt, & + attpack=attpack, rc=rc) + + call ESMF_AttributeSet(adv_scicomp, 'TracersSchemeName', 'Prather', & + attpack=attpack, rc=rc) + call ESMF_AttributeSet(adv_scicomp, 'TracersSchemeCharacteristics', & + 'modified Euler', & + attpack=attpack, rc=rc) + call ESMF_AttributeSet(adv_scicomp, 'MomentumSchemeName', 'Van Leer', & + attpack=attpack, rc=rc) ++ +
+
+ ! + ! Atmosphere Radiation Science Component + ! + rad_scicomp = ESMF_SciCompCreate(name="AtmosRadiation", rc=rc) ++ +
+
+ call ESMF_AttributeAdd(rad_scicomp, & + convention=convCIM, purpose=purpComp, & + attpack=attpack, rc=rc) + + call ESMF_AttributeSet(rad_scicomp, "ShortName", "AtmosRadiation", & + attpack=attpack, rc=rc) + call ESMF_AttributeSet(rad_scicomp, "LongName", & + "Atmosphere Radiation", & + attpack=attpack, rc=rc) ++ +
+
+ rad_sciPropAtt(1) = 'LongwaveSchemeType' + rad_sciPropAtt(2) = 'LongwaveSchemeMethod' + + call ESMF_AttributeAdd(rad_scicomp, & + convention=convCIM, purpose=purpSci, & + attrList=rad_sciPropAtt, & + attpack=attpack, rc=rc) + + call ESMF_AttributeSet(rad_scicomp, & + 'LongwaveSchemeType', & + 'wide-band model', & + attpack=attpack, rc=rc) + call ESMF_AttributeSet(rad_scicomp, & + 'LongwaveSchemeMethod', & + 'two-stream', & + attpack=attpack, rc=rc) ++ +
+Finally, destroy all of the Components. + +
+
+ call ESMF_SciCompDestroy(rad_scicomp, rc=rc) + call ESMF_SciCompDestroy(adv_scicomp, rc=rc) + call ESMF_SciCompDestroy(dc_scicomp, rc=rc) + call ESMF_GridCompDestroy(atmcomp, rc=rc) + call ESMF_GridCompDestroy(ocncomp, rc=rc) + call ESMF_CplCompDestroy(cplcomp, rc=rc) ++ +
+ + +
+ +
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + scicomp1 = scicomp2 +ARGUMENTS: +
type(ESMF_SciComp) :: scicomp1 + type(ESMF_SciComp) :: scicomp2 ++DESCRIPTION: +
+Assign scicomp1 as an alias to the same ESMF SciComp object in memory + as scicomp2. If scicomp2 is invalid, then scicomp1 will be equally + invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (scicomp1 == scicomp2) then ... endif + OR + result = (scicomp1 == scicomp2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_SciComp), intent(in) :: scicomp1 + type(ESMF_SciComp), intent(in) :: scicomp2 ++DESCRIPTION: +
+Test whether scicomp1 and scicomp2 are valid aliases to the same ESMF + SciComp object in memory. For a more general comparison of two ESMF + SciComps, going beyond the simple alias test, the ESMF_SciCompMatch() + function (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (scicomp1 /= scicomp2) then ... endif + OR + result = (scicomp1 /= scicomp2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_SciComp), intent(in) :: scicomp1 + type(ESMF_SciComp), intent(in) :: scicomp2 ++DESCRIPTION: +
+Test whether scicomp1 and scicomp2 are not valid aliases to the + same ESMF SciComp object in memory. For a more general comparison of two + ESMF SciComps, going beyond the simple alias test, the ESMF_SciCompMatch() + function (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive function ESMF_SciCompCreate(name, rc) +RETURN VALUE: +
type(ESMF_SciComp) :: ESMF_SciCompCreate +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This interface creates an ESMF_SciComp object. + The return value is the new ESMF_SciComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_SciCompDestroy(scicomp, rc) +ARGUMENTS: +
type(ESMF_SciComp), intent(inout) :: scicomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Destroys an ESMF_SciComp, releasing the resources associated + with the object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_SciCompGet(scicomp, name, rc) +ARGUMENTS: +
type(ESMF_SciComp), intent(in) :: scicomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(out), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get information about an ESMF_SciComp object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_SciCompIsCreated(scicomp, rc) +RETURN VALUE: +
logical :: ESMF_SciCompIsCreated +ARGUMENTS: +
type(ESMF_SciComp), intent(in) :: scicomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the scicomp has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_SciCompPrint(scicomp, rc) +ARGUMENTS: +
type(ESMF_SciComp), intent(in) :: scicomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Prints information about an ESMF_SciComp to stdout.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_SciCompSet(scicomp, name, rc) +ARGUMENTS: +
type(ESMF_SciComp), intent(inout) :: scicomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets or resets information about an ESMF_SciComp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_SciCompValidate(scicomp, rc) +ARGUMENTS: +
type(ESMF_SciComp), intent(in) :: scicomp + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Currently all this method does is to check that the scicomp + was created. + +
+The arguments are: +
+ + +
+For ensemble runs with many ensemble members, fault-tolerance becomes an issue of very critical practical impact. The meaning of fault-tolerance in this context refers to the ability of an ensemble application to continue with normal execution after one or more ensemble members have experienced catastrophic conditions, from which they cannot recover. ESMF implements this type of fault-tolerance on the Component level via a timeout paradigm: A timeout parameter is specified for all interactions that need to be fault-tolerant. When a connection to a component times out, maybe because it has become inaccessible due to some catastrophic condition, the driver application can react to this condition, for example by not further interacting with the component during the otherwise normal continuation of the model execution. + +
+The fault-tolerant connection between a driver application and a Component is established through a Component Tunnel. There are two sides to a Component Tunnel: the "actual" side is where the component is actually executing, and the "dual" side is the portal through which the Component becomes accessible on the driver side. Both the actual and the dual side of a Component Tunnel are implemented in form of a regular ESMF Gridded or Coupler Component. + +
+Component Tunnels between Components can be based on a number of low level implementations. The only implementation that currently provides fault-tolerance is socket based. In this case an actual Component typically runs as a separate executable, listening to a specific port for connections from the driver application. The dual Component is created on the driver side. It connects to the actual Component during the SetServices() call. + +
+A Component Tunnel connects a dual Component to an actual Component. This connection can be based on a number of different low level implementations, e.g. VM-based or socket-based. VM-based Component Tunnels require that both dual and actual Components run within the same application (i.e. execute under the same MPI_COMM_WORLD). Fault-tolerant Component Tunnels require that dual and actual Components run in separate applications, under different MPI_COMM_WORLD communicators. This mode is implemented in the socket-based Component Tunnels. + +
+ +
+ +
+ +
+The creation process of an actual Gridded Component, which will become + one of the two end points of a Component Tunnel, is identical to the creation + of a regular Gridded Component. On the actual side, an actual Component is + very similar to a regular Component. Here the actual Component is created + with a custom petList. +
+
+ petList = (/0,1,2/) + actualComp = ESMF_GridCompCreate(petList=petList, name="actual", rc=rc) ++ +
+ +
+The same way an actual Component appears as a regular Component in + the context of the actual side application, a dual Component + is created as a regular Component on the dual side. + A dual Gridded Component with custom petList is created using the + regular create call. +
+
+ petList = (/4,3,5/) + dualComp = ESMF_GridCompCreate(petList=petList, name="dual", rc=rc) ++ +
+ +
+After creation, the regular procedure for registering the standard Component + methods is followed for the actual Gridded Component. +
+
+ call ESMF_GridCompSetServices(actualComp, userRoutine=setservices, & + userRc=userRc, rc=rc) ++ +
+So far the actualComp object is no different from a regular Gridded + Component. In order to turn it into the actual end point of a Component + Tunnel the ServiceLoop() method is called. Here the socket-based + implementation is chosen. +
+
+ call ESMF_GridCompServiceLoop(actualComp, port=61010, timeout=20, rc=rc) ++ +
+This call opens the actual side of the Component Tunnel in form of a + socket-based server, listening on port 61010. The timeout argument + specifies how long the actual side will wait for the dual side + to connect, before the actual side returns with a time out condition. The + time out is set to 20 seconds. + +
+At this point, before a dual Component connects to the other side of the + Component Tunnel, it is + possible to manually connect to the waiting actual Component. This can be + useful when debugging connection issues. A convenient tool for this is the + standard telnet application. Below is a transcript of such a connection. + The manually typed commands are separate from the previous responses by a + blank line. + +
+
+ $ telnet localhost 61010 + Trying 127.0.0.1... + Connected to localhost. + Escape character is '^]'. + Hello from ESMF Actual Component server! + + date + Tue Apr 3 21:53:03 2012 + + version + ESMF_VERSION_STRING: 5.3.0 ++ +
+If at any point the telnet session is manually shut down, the + ServiceLoop() on the actual side will return with an error condition. + The clean way to + disconnect the telnet session, and to have the ServiceLoop() + wait for a new connection, e.g. from a dual Component, is to send the + reconnect command. This will automatically shut down the telnet + connection. + +
+
+ reconnect + Actual Component server will reconnect now! + Connection closed by foreign host. + $ ++ +
+At this point the actual Component is back in listening mode, with a time out + of 20 seconds, as specified during the ServiceLoop() call. + +
+Before moving on to the dual side of the GridComp based Component Tunnel + example, it should be pointed out that the exact same procedure is used to + set up the actual side of a CplComp based Component Tunnel. Assuming + that actualCplComp is a CplComp object for which SetServices has already + been called, the actual side uses ESMF_CplCompServiceLoop() to start + listening for connections from the dual side. + +
+
+ call ESMF_CplCompServiceLoop(actualCplComp, port=61011, timeout=2, & + timeoutFlag=timeoutFlag, rc=rc) ++ +
+Here the timeoutFlag is specified in order to prevent the expected + time-out condition to be indicated through the return code. Instead, when + timeoutFlag is present, the return code is still ESMF_SUCCESS, + but timeoutFlag is set to .true. when a time-out occurs. + +
+ +
+On the dual side, the dualComp object needs to be connected to the + actual Component in order to complete the Component Tunnel. Instead of + registering standard Component methods locally, a special variant of the + SetServices() call is used to connect to the actual Component. +
+
+ call ESMF_GridCompSetServices(dualComp, port=61010, server="localhost", & + timeout=10, timeoutFlag=timeoutFlag, rc=rc) ++ +
+The port and server arguments are used to connect to the desired + actual Component. The time out of 10 seconds ensures that if the actual + Component is not available, a time out condition is returned instead of + resulting in a hang. The timeoutFlag argument further absorbs the time + out condition, either returning as .true. or .false.. In this mode + the standard rc will indicate success even when a time out condition + was reached. + +
+ +
+Once a Component Tunnel is established, the actual Component is fully under + the control of the dual Component. A standard Component method invoked on the + dual Component is not executed by the dual Component itself, but by the + actual Component instead. In fact, it is the entry points registered with + the actual Component that are executed when standard methods are invoked on + the dual Component. The connected dualComp object serves as a portal + through which the connected actualComp becomes accessible on the dual + side. + +
+Typically the first standard method called is the CompInitialize() + routine. +
+
+ call ESMF_GridCompInitialize(dualComp, timeout=10, timeoutFlag=timeoutFlag, & + userRc=userRc, rc=rc) ++ +
+Again, the timeout argument serves to prevent the dual side from + hanging if the actual Component application has experienced a catastrophic + condition and is no longer available, or takes longer than expected. The + presence of the timeoutFlag allows time out conditions to be caught + gracefully, so the dual side can deal with it in an orderly fashion, instead + of triggering an application abort due to an error condition. + +
+The CompRun() and CompFinalize() methods follow the same format. + +
+
+ call ESMF_GridCompRun(dualComp, timeout=10, timeoutFlag=timeoutFlag, & + userRc=userRc, rc=rc) ++ +
+
+ call ESMF_GridCompFinalize(dualComp, timeout=10, timeoutFlag=timeoutFlag, & + userRc=userRc, rc=rc) ++ +
+ +
+Standard Component methods called on a connected dual Component are executed + on the actual side, across the PETs of the actual Component. By default the + dual Component PETs are blocked until the actual Component has finished + executing the invoked Component method, or until a time out condition has been + reached. In many practical applications a more loose synchronization between + dual and actual Components is useful. Having the PETs of a dual + Component return immediately from a standard Component method allows multiple + dual Component, on the same PETs, to control multiple actual Components. + If the actual Components are executing in separate executables, or the same + executable but on exclusive sets of PETs, they can execute concurrently, even + with the controlling dual Components all running on the same PETs. + The non-blocking dual side regains control over the actual Component by + synchronizing through the CompWait() call. + +
+Any of the standard Component methods can be called in non-blocking mode + by setting the optional syncflag argument to + ESMF_SYNC_NONBLOCKING. +
+
+ call ESMF_GridCompInitialize(dualComp, syncflag=ESMF_SYNC_NONBLOCKING, rc=rc) ++ +
+If communication between the dual and the actual Component was successful, + this call will return immediately on all of the dual Component PETs, while the + actual Component continues to execute the invoked Component method. + However, if the dual Component has difficulties reaching the actual Component, + the call will block on all dual PETs until successful contact was made, or the + default time out (3600 seconds, i.e. 1 hour) has been reached. In most cases a + shorter time out condition is desired with the non-blocking option, as shown + below. + +
+First the dual Component must wait for the outstanding method. +
+
+ call ESMF_GridCompWait(dualComp, rc=rc) ++ +
+Now the same non-blocking CompInitialize() call is issued again, but this time + with an explicit 10 second time out. +
+
+ call ESMF_GridCompInitialize(dualComp, syncflag=ESMF_SYNC_NONBLOCKING, & + timeout=10, timeoutFlag=timeoutFlag, rc=rc) ++ +
+This call is guaranteed to return within 10 seconds, or less, on the dual Component + PETs, either without time out condition, indicating that the actual Component + has been contacted successfully, or with time out condition, indicating that + the actual Component was unreachable at the time. Either way, the dual + Component PETs are back under user control quickly. + +
+Calling the CompWait() method on the dual Component causes the dual Component + PETs to block until the actual Component method has returned, or a time out + condition has been reached. +
+
+ call ESMF_GridCompWait(dualComp, userRc=userRc, rc=rc) ++ +
+The default time out for CompWait() is 3600 seconds, i.e. 1 hour, just like + for the other Component methods. However, the semantics of a time out + condition under CompWait() is different from the other Component methods. Typically the timeout is simply the + maximum time that any communication between dual and actual Component is allowed + to take before a time out condition is raised. For CompWait(), the timeout + is the maximum time that an actual Component is allowed to execute before + reporting back to the dual Component. Here, even with the default time out, + the dual Component would return from CompWait() immediately with a time out + condition if the actual Component has already been executing for over 1 hour, + and is not already waiting to report back when the dual Component calls + CompWait(). On the other hand, if it has only been 30 minutes since + CompInitialize() was called on the dual Component, then the actual Component + still has 30 minutes before CompWait() returns with a time out condition. + During this time (or until the actual Component returns) the dual Component + PETs are blocked. + +
+A standard Component method is invoked in non-blocking mode. +
+
+ call ESMF_GridCompRun(dualComp, syncflag=ESMF_SYNC_NONBLOCKING, & + timeout=10, timeoutFlag=timeoutFlag, rc=rc) ++ +
+Once the user code on the dual side is ready to regain control over the + actual Component it calls CompWait() on the dual Component. Here a + timeout of 60s is specified, meaning that the total execution time the + actual Component spends in the registered Run() routine may not exceed 60s + before CompWait() returns with a time out condition. +
+
+ call ESMF_GridCompWait(dualComp, timeout=60, userRc=userRc, rc=rc) ++ +
+ +
+A dual Component that is connected to an actual Component through a Component + Tunnel is destroyed the same way a regular Component is. The only + difference is that a connected dual Component may specify a timeout + argument to the CompDestroy() call. +
+
+ call ESMF_GridCompDestroy(dualComp, timeout=10, rc=rc) ++ +
+The timeout argument again ensures that the dual side does not hang + indefinitely in case the actual Component has become unavailable. If the + actual Component is available, the destroy call will indicate to the actual + Component that it should break out of the ServiceLoop(). Either way, + the local dual Component is destroyed. + +
+ +
+An actual Component that is in a ServiceLoop() must first return from + that call before it can be destroyed. This can either happen when a connected + dual Component calls its CompDestroy() method, or if the + ServiceLoop() reaches the specified time out condition. Either way, + once control has been returned to the user code, the actual Component is + destroyed in the same way a regular Component is, by calling the destroy + method. +
+
+ call ESMF_GridCompDestroy(actualComp, rc=rc) ++ +
+ + +
+ +
+
+A State contains the data and metadata to be transferred between +ESMF Components. It is an important class, because it defines a +standard for how data is represented in data transfers between Earth +science components. The +State construct is a rational compromise between a fully prescribed +interface - one that would dictate what specific fields should be +transferred between components - and an interface in which data structures +are completely ad hoc. + +
+There are two types of States, import and export. +An import State contains data that is necessary for a Gridded Component +or Coupler Component to execute, and an export State contains the data +that a Gridded Component or Coupler Component can make available. + +
+States can contain Arrays, ArrayBundles, Fields, FieldBundles, +and other States. They cannot directly contain native language arrays +(i.e. Fortran or C style arrays). Objects in a State must span +the VM on which they are running. For sequentially executing components +which run on the same set of PETs this happens by calling the object +create methods on each PET, creating the object in unison. For +concurrently executing components which are running on subsets of PETs, +an additional method, called ESMF_StateReconcile(), is provided by +ESMF to broadcast information +about objects which were created in sub-components. + +
+State methods include creation and deletion, adding and retrieving +data items, adding and retrieving attributes, and performing queries. + +
+ +
+ +
+DESCRIPTION:
+
+Specifies whether a ESMF_State contains data to be imported
+into a component or exported from a component.
+
+
+The type of this flag is: + +
+type(ESMF_StateIntent_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+Specifies the type of object being added to or retrieved from an
+ESMF_State.
+
+
+The type of this flag is: + +
+type(ESMF_StateItem_Flag) + +
+The valid values are: +
+ +
+A Gridded Component generally has one associated import +State and one export State. Generally the States +associated with a Gridded Component will be created by +the Gridded Component's parent component. +In many cases, the States will be created containing +no data. Both the empty States and the +newly created Gridded Component are passed +by the parent component into the Gridded Component's initialize +method. This is where the States get prepared for use +and the import State is first filled with data. + +
+States can be filled with data items that do not yet +have data allocated. Fields, FieldBundles, Arrays, and ArrayBundles each have +methods that support their creation without actual data +allocation - the Grid and Attributes are set up but no +Fortran array of data values is allocated. In this approach, +when a State is passed into its associated Gridded Component's +initialize method, the incomplete Arrays, Fields, FieldBundles, +and ArrayBundles within the State can allocate or reference data +inside the initialize method. + +
+States are passed through the interfaces of the Gridded +and Coupler Components' run methods in order to carry data +between the components. While we expect +a Gridded Component's import State to be filled with data +during initialization, its export State will typically be +filled over the course of its run method. At the end of +a Gridded Component's run method, the filled export State +is passed out through the argument list into a Coupler +Component's run method. We recommend the convention that +it enters the Coupler Component as the Coupler Component's +import State. Here is it transformed into a form +that another Gridded Component requires, and passed out +of the Coupler Component as its export State. It can then +be passed into the run method of a recipient Gridded Component +as that component's import State. + +
+While the above sounds complicated, the rule is simple: +a State going into a component is an import State, and a +State leaving a component is an export State. + +
+Objects inside States are normally created in unison where +each PET executing a component makes the same object create call. +If the object contains data, like a Field, each PET may have a +different local chunk of the entire dataset but each Field has +the same name and is logically one part of a single distributed +object. As States are passed between components, if any object +in a State was not created in unison on all the current PETs +then some PETs have no object to pass into a +communication method (e.g. regrid or data redistribution). +The ESMF_StateReconcile() method must be called to broadcast +information about these objects to all PETs in a component; +after which all PETs have a single uniform view of all objects and metadata. + +
+If components are running in sequential mode on all available PETs +and States are being passed between them there is no need to call +ESMF_StateReconcile since all PETs have a uniform view of the objects. +However, if components are running on a subset of the PETs, as is +usually the case when running in concurrent mode, then when States +are passed into components which contain a superset of those PETs, +for example, a Coupler Component, all PETs must call ESMF_StateReconcile +on the States before using them in any ESMF communication methods. +The reconciliation process broadcasts information about objects +which exist only on a subset of the PETs. On PETs missing those +objects it creates a proxy object which contains any +qualities of the original object plus enough information for it +to be a data source or destination for a regrid or data redistribution +operation. + +
+ +
+States can be created and destroyed at any time during +application execution. The ESMF_StateCreate() routine +can take many different combinations of optional arguments. Refer +to the API description for all possible methods of creating a State. +An empty State can be created by providing only a name and type for +the intended State: + +
+state = ESMF_StateCreate(name, stateintent=ESMF_STATEINTENT_IMPORT, rc=rc) + +
+When finished with an ESMF_State, the ESMF_StateDestroy method +removes it. However, the objects inside the ESMF_State +created externally should be destroyed separately, +since objects can be added to more than one ESMF_State. + +
+ +
+ +
+ +
+Creation of an empty ESMF_State, and adding an ESMF_FieldBundle + to it. Note that the ESMF_FieldBundle does not get destroyed when + the ESMF_State is destroyed; the ESMF_State only contains + a reference to the objects it contains. It also does not make a copy; + the original objects can be updated and code accessing them by using + the ESMF_State will see the updated version. +
+
+ statename = "Ocean" + state2 = ESMF_StateCreate(name=statename, & + stateintent=ESMF_STATEINTENT_EXPORT, rc=rc) ++ +
+
+ bundlename = "Temperature" + bundle1 = ESMF_FieldBundleCreate(name=bundlename, rc=rc) + print *, "FieldBundle Create returned", rc ++ +
+
+ call ESMF_StateAdd(state2, (/bundle1/), rc=rc) + print *, "StateAdd returned", rc ++ +
+
+ call ESMF_StateDestroy(state2, rc=rc) ++ +
+
+ call ESMF_FieldBundleDestroy(bundle1, rc=rc) ++ +
+ +
+If a component could potentially produce a large number of optional + items, one strategy is to add the names only of those objects to the + ESMF_State. Other components can call framework routines to + set the ESMF_NEEDED flag to indicate they require that data. + The original component can query this flag and then produce only the + data that is required by another component. +
+
+ statename = "Ocean" + state3 = ESMF_StateCreate(name=statename, & + stateintent=ESMF_STATEINTENT_EXPORT, rc=rc) ++ +
+
+ dataname = "Downward wind:needed" + call ESMF_AttributeSet (state3, dataname, .false., rc=rc) ++ +
+
+ dataname = "Humidity:needed" + call ESMF_AttributeSet (state3, dataname, .false., rc=rc) ++ +
+ +
+How to set the NEEDED state of an item. +
+
+ dataname = "Downward wind:needed" + call ESMF_AttributeSet (state3, name=dataname, value=.true., rc=rc) ++ +
+ +
+Query an item for the NEEDED status, and creating an item on demand. + Similar flags exist for "Ready", "Valid", and "Required for Restart", + to mark each data item as ready, having been validated, or needed if the + application is to be checkpointed and restarted. The flags are supported + to help coordinate the data exchange between components. +
+
+ dataname = "Downward wind:needed" + call ESMF_AttributeGet (state3, dataname, value=neededFlag, rc=rc) ++ +
+
+ if (rc == ESMF_SUCCESS .and. neededFlag) then + bundlename = dataname + bundle2 = ESMF_FieldBundleCreate(name=bundlename, rc=rc) ++ +
+
+ call ESMF_StateAdd(state3, (/bundle2/), rc=rc) ++ +
+
+ else + print *, "Data not marked as needed", trim(dataname) + endif ++ +
+ + +
+ +
+ +
+ +
+The set services routines are used to tell ESMF which routine + hold the user code for the initialize, run, and finalize + blocks of user level Components. + These are the separate subroutines called by the code below. +
+
+! Initialize routine which creates "field1" on PETs 0 and 1 +subroutine comp1_init(gcomp, istate, ostate, clock, rc) + type(ESMF_GridComp) :: gcomp + type(ESMF_State) :: istate, ostate + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + type(ESMF_Field) :: field1 + integer :: localrc + + print *, "i am comp1_init" + + field1 = ESMF_FieldEmptyCreate(name="Comp1 Field", rc=localrc) + + call ESMF_StateAdd(istate, (/field1/), rc=localrc) + + rc = localrc + +end subroutine comp1_init + +! Initialize routine which creates "field2" on PETs 2 and 3 +subroutine comp2_init(gcomp, istate, ostate, clock, rc) + type(ESMF_GridComp) :: gcomp + type(ESMF_State) :: istate, ostate + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + type(ESMF_Field) :: field2 + integer :: localrc + + print *, "i am comp2_init" + + field2 = ESMF_FieldEmptyCreate(name="Comp2 Field", rc=localrc) + + call ESMF_StateAdd(istate, (/field2/), rc=localrc) + + rc = localrc + +end subroutine comp2_init + +subroutine comp_dummy(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + rc = ESMF_SUCCESS +end subroutine comp_dummy ++ +
+
+! !PROGRAM: ESMF_StateReconcileEx - State reconciliation +! +! !DESCRIPTION: +! +! This program shows examples of using the State Reconcile function +!----------------------------------------------------------------------------- +#include "ESMF.h" + + ! ESMF Framework module + use ESMF + use ESMF_TestMod + use ESMF_StateReconcileEx_Mod + implicit none + + ! Local variables + integer :: rc, petCount + type(ESMF_State) :: state1 + type(ESMF_GridComp) :: comp1, comp2 + type(ESMF_VM) :: vm + character(len=ESMF_MAXSTR) :: comp1name, comp2name, statename ++ +
+A Component can be created which will run only on a subset of the + current PET list. +
+
+ ! Get the global VM for this job. + call ESMF_VMGetGlobal(vm=vm, rc=rc) + + comp1name = "Atmosphere" + comp1 = ESMF_GridCompCreate(name=comp1name, petList=(/ 0, 1 /), rc=rc) + print *, "GridComp Create returned, name = ", trim(comp1name) ++ +
+
+ comp2name = "Ocean" + comp2 = ESMF_GridCompCreate(name=comp2name, petList=(/ 2, 3 /), rc=rc) + print *, "GridComp Create returned, name = ", trim(comp2name) ++ +
+
+ statename = "Ocn2Atm" + state1 = ESMF_StateCreate(name=statename, rc=rc) ++ +
+Here we register the subroutines which should be called for initialization. + Then we call ESMF_GridCompInitialize() on all PETs, but the code runs + only on the PETs given in the petList when the Component was created. + +
+Because this example is so short, we call the entry point code + directly instead of the normal procedure of nesting it in a separate + SetServices() subroutine. + +
+
+ ! This is where the VM for each component is initialized. + ! Normally you would call SetEntryPoint inside set services, + ! but to make this example very short, they are called inline below. + ! This is o.k. because the SetServices routine must execute from within + ! the parent component VM. + call ESMF_GridCompSetVM(comp1, comp_dummy, rc=rc) ++ +
+
+ call ESMF_GridCompSetVM(comp2, comp_dummy, rc=rc) ++ +
+
+ call ESMF_GridCompSetServices(comp1, userRoutine=comp_dummy, rc=rc) ++ +
+
+ call ESMF_GridCompSetServices(comp2, userRoutine=comp_dummy, rc=rc) ++ +
+
+ print *, "ready to set entry point 1" + call ESMF_GridCompSetEntryPoint(comp1, ESMF_METHOD_INITIALIZE, & + comp1_init, rc=rc) ++ +
+
+ print *, "ready to set entry point 2" + call ESMF_GridCompSetEntryPoint(comp2, ESMF_METHOD_INITIALIZE, & + comp2_init, rc=rc) ++ +
+
+ print *, "ready to call init for comp 1" + call ESMF_GridCompInitialize(comp1, exportState=state1, rc=rc) ++ +
+
+ print *, "ready to call init for comp 2" + call ESMF_GridCompInitialize(comp2, exportState=state1, rc=rc) ++ +
+Now we have state1 containing field1 on PETs 0 and 1, and + state1 containing field2 on PETs 2 and 3. For the code + to have a rational view of the data, we call ESMF_StateReconcile + which determines which objects are missing from any PET, and communicates + information about the object. After the call to reconcile, all + ESMF_State objects now have a consistent view of the data. +
+
+ print *, "State before calling StateReconcile()" + call ESMF_StatePrint(state1, rc=rc) ++ +
+
+ call ESMF_StateReconcile(state1, vm=vm, rc=rc) ++ +
+
+ print *, "State after calling StateReconcile()" + call ESMF_StatePrint(state1, rc=rc) ++ +
+
+end program ESMF_StateReconcileEx ++ +
+ + +
+ +
+One important request by the user community during the ESMF object design was +that there be no communication overhead or synchronization when creating +distributed ESMF objects. As a consequence it is required to create these +objects in unison across all PETs in order to keep the ESMF object +identification in sync. + +
+
+ +
+ +
+
+When running components on subsets of the original VM all the +PETs can create consistent objects but then when they are put +into a State and passed to a component with a different VM and +a different set of PETs, a communication call (reconcile) must be +made to communicate the missing information to the PETs which were +not involved in the original object creation. The reconcile call +broadcasts object lists; those PETs which are missing any objects +in the total list can receive enough information to +reconstruct a proxy object which contains all necessary information +about that object, with no local data, on that PET. These proxy +objects can be queried by ESMF routines to determine the amount +of data and what PETs contain data which is destined to be moved +to the local PET (for receiving data) and conversely, can determine +which other PETs are going to receive data and how much (for +sending data). + +
+For example, the FieldExcl system test creates 2 Gridded Components +on separate subsets of PETs. They use the option of mapping +particular, non-monotonic PETs to DEs. The following figures +illustrate how the DEs are mapped in each of the Gridded Components +in that test: + +
+
+ |
+
+ |
+In the coupler code, all PETs must make the reconcile call before +accessing data in the State. On PETs which already contain data, +the objects are unchanged. On PETs which were not involved during +the creation of the FieldBundles or Fields, the reconcile call adds an +object to the State which contains all the same metadata associated +with the object, but creates a slightly different Grid object, +called a Proxy Grid. These PETs contain no local data, so the +Array object is empty, and the DELayout for the Grid is like this: + +
+
+ |
+
+ |
+
+The following is a simplified UML diagram showing the structure of the +State class. States can contain FieldBundles, Fields, Arrays, or nested +States. See Appendix A, A Brief Introduction to UML, +for a translation table that lists the symbols in the diagram and their +meaning. + +
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + state1 = state2 +ARGUMENTS: +
type(ESMF_State) :: state1 + type(ESMF_State) :: state2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign state1 as an alias to the same ESMF State object in memory + as state2. If state2 is invalid, then state1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (state1 == state2) then ... endif + OR + result = (state1 == state2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_State), intent(in) :: state1 + type(ESMF_State), intent(in) :: state2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether state1 and state2 are valid aliases to the same ESMF + State object in memory. For a more general comparison of two ESMF States, + going beyond the simple alias test, the ESMF_StateMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (state1 /= state2) then ... endif + OR + result = (state1 /= state2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_State), intent(in) :: state1 + type(ESMF_State), intent(in) :: state2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether state1 and state2 are not valid aliases to the + same ESMF State object in memory. For a more general comparison of two ESMF + States, going beyond the simple alias test, the ESMF_StateMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_StateAdd(state, <itemList>, relaxedFlag, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + <itemList>, see below for supported values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: relaxedFlag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Add a list of items to a ESMF_State. It is an error if any item in + <itemlist> already matches, by name, an item already contained in state. + +
+Supported values for <itemList> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_StateAddReplace(state, <itemList>, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + <itemList>, see below for supported values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Add or replace a list of items to an ESMF_State. If an item in + <itemList> does not match any items already present in state, it is + added. Items with names already present in the state replace the + existing item. + +
+Supported values for <itemList> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_StateCreate(stateIntent, & + arrayList, arraybundleList, & + fieldList, fieldbundleList, & + nestedStateList, & + routehandleList, name, vm, rc) +RETURN VALUE: +
type(ESMF_State) :: ESMF_StateCreate +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_StateIntent_Flag), intent(in), optional :: stateIntent + type(ESMF_Array), intent(in), optional :: arrayList(:) + type(ESMF_ArrayBundle), intent(in), optional :: arraybundleList(:) + type(ESMF_Field), intent(in), optional :: fieldList(:) + type(ESMF_FieldBundle), intent(in), optional :: fieldbundleList(:) + type(ESMF_State), intent(in), optional :: nestedStateList(:) + type(ESMF_RouteHandle), intent(in), optional :: routehandleList(:) + character(len=*), intent(in), optional :: name + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create a new ESMF_State, set default characteristics for + objects added to it, and optionally add initial objects to it. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_StateDestroy(state, noGarbage, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Releases resources associated with this ESMF_State. Actual + objects added to ESMF_States will not be destroyed, it + remains the responsibility of the user to destroy these objects in the correct + context. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_StateGet() + subroutine ESMF_StateGetInfo(state, & + itemSearch, itemorderflag, nestedFlag, & + stateIntent, itemCount, itemNameList, itemTypeList, name, vm, rc) +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len=*), intent(in), optional :: itemSearch + type(ESMF_ItemOrder_Flag), intent(in), optional :: itemorderflag + logical, intent(in), optional :: nestedFlag + type(ESMF_StateIntent_Flag), intent(out), optional :: stateIntent + integer, intent(out), optional :: itemCount + character (len=*), intent(out), optional :: itemNameList(:) + type(ESMF_StateItem_Flag), intent(out), optional :: itemTypeList(:) + character (len=*), intent(out), optional :: name + type(ESMF_VM), intent(out), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns the requested information about this ESMF_State. + The optional itemSearch argument may specify the name of + an individual item to search for. When used in conjunction with + the nestedFlag, nested States will also be searched. + +
+Typically, an ESMF_StateGet() information request will be performed + twice. The first time, the itemCount argument will be used to + query the size of arrays that are needed. Arrays can then be allocated + to the correct size for itemNameList and itemtypeList + as needed. A second call to ESMF_StateGet() will then fill in the + values. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_StateGet() + subroutine ESMF_StateGetItemInfo(state, itemName, itemType, rc) +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + character (len=*), intent(in) :: itemName + type(ESMF_StateItem_Flag), intent(out) :: itemType + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns the type for the item named + name in this ESMF_State. If no item with this name + exists, the value ESMF_STATEITEM_NOTFOUND will be returned + and the error code will not be set to an error. Thus this routine + can be used to safely query for the existence of items by name + whether or not they are expected to be there. The error code will + be set in case of other errors, for example if the ESMF_State + itself is invalid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_StateGet(state, itemName, <item>, rc) +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + character (len=*), intent(in) :: itemName + <item>, see below for supported values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns an <item> from an ESMF_State by item name. + If the ESMF_State contains the <item> directly, only + itemName is required. + +
+If the state contains nested ESMF_States, + the itemName argument may specify a fully qualified name + to access the desired item with a single call. This is performed + using the '/' character to separate the names of the intermediate + State names leading to the desired item. (E.g., + itemName='state1/state12/item'). + +
+Supported values for <item> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_StateIsCreated(state, rc) +RETURN VALUE: +
logical :: ESMF_StateIsCreated +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the state has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_StateLog(state, prefix, logMsgFlag, nestedFlag, deepFlag, rc) +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: prefix + type(ESMF_LogMsg_Flag), intent(in), optional :: logMsgFlag + logical, intent(in), optional :: nestedFlag + logical, intent(in), optional :: deepFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write information about state to the ESMF default Log. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_StatePrint(state, options, nestedFlag, rc) +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + character(len=*), intent(in), optional :: options + logical, intent(in), optional :: nestedFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Prints information about the state to stdout. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_StateReconcile(state, vm, checkflag, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_VM), intent(in), optional :: vm + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Must be called for any ESMF_State which contains ESMF objects + that have not been created on all the PETs of the current VM. + For example, if a coupler component is operating on data + which was created by another component that ran on only a subset + of the coupler PETs, the coupler must make this call first + before operating with any of the objects held by the ESMF_State. + After calling ESMF_StateReconcile() all PETs will have + a common view of all objects contained in this ESMF_State. + +
+This call is collective across the specified VM. + +
+The arguments are: +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_StateRemove () + subroutine ESMF_StateRemoveOneItem (state, itemName, & + relaxedFlag, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + character(*), intent(in) :: itemName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: relaxedFlag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Remove an existing reference to an item from a State. + +
+The arguments are: +
+If the state contains nested ESMF_States, + the itemName argument may specify a fully qualified name + to remove the desired item with a single call. This is performed + using the "/" character to separate the names of the intermediate + State names leading to the desired item. (E.g., + itemName="state1/state12/item". + +
+Since an item could potentially be referenced by multiple containers, + it remains the responsibility of the user to manage its + destruction when it is no longer in use. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_StateRemove () + subroutine ESMF_StateRemoveList (state, itemNameList, relaxedFlag, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + character(*), intent(in) :: itemNameList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: relaxedFlag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Remove existing references to items from a State. + +
+The arguments are: +
+If the state contains nested ESMF_States, + the itemName arguments may specify fully qualified names + to remove the desired items with a single call. This is performed + using the "/" character to separate the names of the intermediate + State names leading to the desired items. (E.g., + itemName="state1/state12/item". + +
+Since items could potentially be referenced by multiple containers, + it remains the responsibility of the user to manage their + destruction when they are no longer in use. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_StateReplace(state, <itemList>, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + <itemList>, see below for supported values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Replace a list of items with a ESMF_State. If an item in + <itemList> does not match any items already present in state, an + error is returned. + +
+Supported values for <itemList> are: +
+The arguments are: +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_StateSet(state, stateIntent, name, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_StateIntent_Flag), intent(in), optional :: stateIntent + character(len = *), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the info in the state object. + +
+he arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_StateValidate(state, nestedFlag, rc) +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: nestedFlag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Validates that the state is internally consistent. + Currently this method determines if the State is uninitialized + or already destroyed. The method returns an error code if problems + are found. + +
+The arguments are: +
+ + +
+ +
+ +
+ + +
+ESMF allows user methods to be attached to Components and States. Providing +this capability supports a more object oriented way of model design. + +
+Attachable methods on Components can be used to implement the concept of +generic Components where the specialization requires attaching methods with +well defined names. This methods are then called by the generic Component +code. + +
+Attaching methods to States can be used to supply data operations along with +the data objects inside of a State object. This can be useful where a producer +Component not only supplies a data set, but also the associated processing +functionality. This can be more efficient than providing all of the possible +sets of derived data. + +
+The following examples demonstrate how a producer Component attaches a +user defined method to a State, and how it implements the method. The attached +method is then executed by the consumer Component. + +
+ +
+ +
+ +
+The producer Component attaches a user defined method to exportState + during the Component's initialize method. The user defined method is + attached with label finalCalculation by which it will become + accessible to the consumer Component. +
+
+ subroutine init(gcomp, importState, exportState, clock, rc) + ! arguments + type(ESMF_GridComp):: gcomp + type(ESMF_State):: importState, exportState + type(ESMF_Clock):: clock + integer, intent(out):: rc + + rc = ESMF_SUCCESS + call ESMF_MethodAdd(exportState, label="finalCalculation", & + userRoutine=finalCalc, rc=rc) + if (rc /= ESMF_SUCCESS) return + + ! just for testing purposes add the same method with a crazy string label + call ESMF_MethodAdd(exportState, label="Somewhat of a SILLY @$^@_ label", & + userRoutine=finalCalc, rc=rc) + if (rc /= ESMF_SUCCESS) return + + end subroutine !-------------------------------------------------------------- ++ +
+ +
+The producer Component implements the attached, user defined method + finalCalc. Strict interface rules apply for the user defined + method. +
+
+ subroutine finalCalc(state, rc) + ! arguments + type(ESMF_State):: state + integer, intent(out):: rc + + rc = ESMF_SUCCESS + + ! access data objects in state and perform calculation + print *, "dummy output from attached method " + + end subroutine !-------------------------------------------------------------- ++ +
+ +
+The consumer Component executes the user defined method on the + importState. + +
+
+ subroutine init(gcomp, importState, exportState, clock, rc) + ! arguments + type(ESMF_GridComp):: gcomp + type(ESMF_State):: importState, exportState + type(ESMF_Clock):: clock + integer, intent(out):: rc + + integer:: userRc, i + logical:: isPresent + character(len=:), allocatable :: labelList(:) + + rc = ESMF_SUCCESS ++ +
+The importState can be queried for a list of all the attached methods. +
+
+ call ESMF_MethodGet(importState, labelList=labelList, rc=rc) + if (rc /= ESMF_SUCCESS) return + + ! print the labels + do i=1, size(labelList) + print *, labelList(i) + enddo ++ +
+It is also possible to check the importState whether a specific method + is attached. This allows the consumer code to implement alternatives in case + the method is not available. +
+
+ call ESMF_MethodGet(importState, label="finalCalculation", & + isPresent=isPresent, rc=rc) + if (rc /= ESMF_SUCCESS) return ++ +
+Finally call into the attached method from the consumer side. +
+
+ call ESMF_MethodExecute(importState, label="finalCalculation", & + userRc=userRc, rc=rc) + if (rc /= ESMF_SUCCESS) return + rc = userRc + if (rc /= ESMF_SUCCESS) return + + end subroutine !-------------------------------------------------------------- ++ +
+ + +
+ +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAdd() + subroutine ESMF_MethodCplCompAdd(cplcomp, label, index, userRoutine, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: cplcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + interface + subroutine userRoutine(cplcomp, rc) + use ESMF_CompMod + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Error out if there is a previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown above + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAdd() + subroutine ESMF_MethodCplCompAddShObj(cplcomp, label, index, userRoutine, & + sharedObj, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: cplcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + character(len=*), intent(in) :: userRoutine + character(len=*), intent(in), optional :: sharedObj + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Error out if there is a previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown in ESMF_MethodCplCompAdd + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAdd() + subroutine ESMF_MethodGridCompAdd(gcomp, label, index, userRoutine, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: gcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + interface + subroutine userRoutine(gcomp, rc) + use ESMF_CompMod + implicit none + type(ESMF_GridComp) :: gcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Error out if there is a previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown above + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAdd() + subroutine ESMF_MethodGridCompAddShObj(gcomp, label, index, userRoutine, & + sharedObj, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: gcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + character(len=*), intent(in) :: userRoutine + character(len=*), intent(in), optional :: sharedObj + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Error out if there is a previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown in ESMF_MethodGridCompAdd + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAdd() + subroutine ESMF_MethodStateAdd(state, label, index, userRoutine, rc) +ARGUMENTS: +
type(ESMF_State) :: state + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + interface + subroutine userRoutine(state, rc) + use ESMF_StateMod + implicit none + type(ESMF_State) :: state ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Error out if there is a previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown above + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAdd() + subroutine ESMF_MethodStateAddShObj(state, label, index, userRoutine, & + sharedObj, rc) +ARGUMENTS: +
type(ESMF_State) :: state + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + character(len=*), intent(in) :: userRoutine + character(len=*), intent(in), optional :: sharedObj + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Error out if there is a previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown in ESMF_MethodStateAdd + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAddReplace() + subroutine ESMF_MethodCplCompAddRep(cplcomp, label, index, userRoutine, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: cplcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + interface + subroutine userRoutine(cplcomp, rc) + use ESMF_CompMod + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Replacing potential previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown above + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAddReplace() + subroutine ESMF_MethodCplCompAddRepShObj(cplcomp, label, index, userRoutine, & + sharedObj, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: cplcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + character(len=*), intent(in) :: userRoutine + character(len=*), intent(in), optional :: sharedObj + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Replacing potential previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown in ESMF_MethodCplCompAdd + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAddReplace() + subroutine ESMF_MethodGridCompAddRep(gcomp, label, index, userRoutine, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: gcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + interface + subroutine userRoutine(gcomp, rc) + use ESMF_CompMod + implicit none + type(ESMF_GridComp) :: gcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Replacing potential previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown above + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAddReplace() + subroutine ESMF_MethodGridCompAddRepShObj(gcomp, label, index, userRoutine, & + sharedObj, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: gcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + character(len=*), intent(in) :: userRoutine + character(len=*), intent(in), optional :: sharedObj + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Replacing potential previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown in ESMF_MethodGridCompAdd + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAddReplace() + subroutine ESMF_MethodStateAddRep(state, label, index, userRoutine, rc) +ARGUMENTS: +
type(ESMF_State) :: state + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + interface + subroutine userRoutine(state, rc) + use ESMF_StateMod + implicit none + type(ESMF_State) :: state ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Replacing potential previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown above + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodAddReplace() + subroutine ESMF_MethodStateAddRepShObj(state, label, index, userRoutine, & + sharedObj, rc) +ARGUMENTS: +
type(ESMF_State) :: state + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + character(len=*), intent(in) :: userRoutine + character(len=*), intent(in), optional :: sharedObj + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Attach userRoutine. + Replacing potential previous attached method under the same + label and index. + +
+The arguments are: +
+The subroutine must have the exact interface shown in ESMF_MethodStateAdd + for the userRoutine argument. Arguments in userRoutine + must not be declared as optional, and the types, intent and order must + match. + Prior to Fortran-2008, the subroutine must be either a module scope procedure, + or an external procedure that has a matching interface block specified for it. + An internal procedure which is contained within another procedure must not be used. + From Fortran-2008 onwards, an internal procedure contained within either a main program + or a module procedure may be used. If the internal procedure is contained within a + module procedure, it is subject to initialization requirements. See: 16.4.9 + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodExecute() + recursive subroutine ESMF_MethodCplCompExecute(cplcomp, label, index, existflag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: cplcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + logical, intent(out), optional :: existflag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Execute attached method. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodExecute() + recursive subroutine ESMF_MethodGridCompExecute(gcomp, label, index, existflag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: gcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + logical, intent(out), optional :: existflag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Execute attached method. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodExecute() + recursive subroutine ESMF_MethodStateExecute(state, label, index, existflag, & + userRc, rc) +ARGUMENTS: +
type(ESMF_State) :: state + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + logical, intent(out), optional :: existflag + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Execute attached method. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodGet() + subroutine ESMF_MethodCplCompGet(cplcomp, label, index, isPresent, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: cplcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + logical, intent(out), optional :: isPresent + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access information about attached method. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodGet() + subroutine ESMF_MethodCplCompGetList(cplcomp, labelList, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: cplcomp + character(len=:), allocatable, intent(out) :: labelList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access labels of all attached methods. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodGet() + subroutine ESMF_MethodGridCompGet(gcomp, label, index, isPresent, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: gcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + logical, intent(out), optional :: isPresent + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access information about attached method. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodGet() + subroutine ESMF_MethodGridCompGetList(gcomp, labelList, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: gcomp + character(len=:), allocatable, intent(out) :: labelList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access labels of all attached methods. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodGet() + subroutine ESMF_MethodStateGet(state, label, index, isPresent, rc) +ARGUMENTS: +
type(ESMF_State) :: state + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + logical, intent(out), optional :: isPresent + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access information about attached method. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodGet() + subroutine ESMF_MethodStateGetList(state, labelList, rc) +ARGUMENTS: +
type(ESMF_State) :: state + character(len=:), allocatable, intent(out) :: labelList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access labels of all attached methods. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodRemove() + subroutine ESMF_MethodCplCompRemove(cplcomp, label, index, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: cplcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Remove attached method. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodRemove() + subroutine ESMF_MethodGridCompRemove(gcomp, label, index, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: gcomp + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Remove attached method. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MethodRemove() + subroutine ESMF_MethodStateRemove(state, label, index, rc) +ARGUMENTS: +
type(ESMF_State) :: state + character(len=*), intent(in) :: label + integer, intent(in), optional :: index + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Remove attached method. + +
+The arguments are: +
+ + +
+The goal of the ESMF Web Services is to provide the tools to allow ESMF Users to make +their Components available via a web service. The first step is to make the Component +a service, and then make it accessible via the Web. + +
+
+ |
+At the heart of this architecture is the Component Service; this is the +application that does the model work. The ESMF Web Services part provides a way to make +the model accessible via a network API (Application Programming Interface). ESMF provides +the tools to turn a model component into a service as well as the tools to access the +service from the network. + +
+The Process Controller is a stand-alone application that provides a control mechanism between +the end user and the Component Service. The Process Controller is responsible for managing +client information as well as restricting client access to a Component Service. +(The role of the Process Controller is expected to expand in the future.) + +
+The tomcat/axis2 application provides the access via the Web using standard SOAP +protocols. Part of this application includes the SOAP interface definition +(using a WSDL file) as well as some java code that provides the access to the Process +Controller application. + +
+Finally, the Registrar maintains a list of Component Services that are currently +available; Component Services register themselves with the Registrar when they +startup, and unregister themselves when they shutdown. The list of available services +is maintained in an XML file and is accessible from the Registrar using its network API. + +
+ +
+The primary function in ESMF Web Services is the ESMF_WebServicesLoop routine. This +function registers the Component Service with the Registrar and then sets up a +network socket service that listens for requests from a client. It starts a loop +that waits for incoming requests and manages the routing of these requests to +all PETs. It is also responsible for making sure the appropriate ESMF +routine (ESMF_Initialize, ESMF_Run or ESMF_Finalize) is called based on the incoming +request. When the client has completed its interaction with the Component Service, +the loop will be terminated and it will unregister the Component Service from the Registrar. + +
+To make all of this happen, the Application Driver just needs to replace its calls to +ESMF_Initialize, ESMF_Run, and ESMF_Finalize with a single call to ESMF_WebServicesLoop. + +
+
+ use ESMF_WebServMod + .... + + call ESMF_WebServicesLoop(gridComponent, portNumber, returnCode) ++ +
+That's all there is to turning an ESMF Component into a network-accessible +ESMF Component Service. For a detailed example of an ESMF Component turned into +an ESMF Component Service, see the Examples in the Web Services section of the +Developer' Guide. + +
+ +
+However, the goal of ESMF Web Services is to make an ESMF Component accessible through +a standard web service, which is accomplished through the Process Controller and the +Tomcat/Axis2 applications + +
+ +
+Interfacing to a Component service is fairly simple using the ESMF library. The following +code is a simple example of how to interface to a Component Service in C++ and request +the initialize operation (the entire sample client can be found in the Web Services examples +section of the ESMF Distribution): + +
+
+ #include "ESMCI_WebServCompSvrClient.h" + + int main(int argc, char* argv[]) + { + int portNum = 27060; + int clientId = 101; + int rc = ESMF_SUCCESS; + + ESMCI::ESMCI_WebServCompSvrClient + client("localhost", portNum, clientId); + + rc = client.init(); + printf("Initialize return code: %d\n", rc); + } ++ +
+To see a complete description of the NetEsmfClient class, refer to the netesmf library +section of the Web Services Reference Manual. + +
+ +
+The Process Controller is basically just a instance of a C++ client application. It manages +client access to the Component Service (only 1 client can access the service at a time), +and will eventually be responsible for starting up and shutting down instances of +Component Services (planned for a future release). The Process Controller application is +built with the ESMF library and is included in the apps section of the distribution. + +
+ +
+The Tomcat/Axis2 "application" is essentially the Apache Tomcat server using +the Apache Axis2 servlet to implement web services using SOAP protocols. The web +interface is defined by a WSDL file, and its implementation is handled by the Component +Connector java code. Tomcat and Axis2 are both open source projects that should be +downloaded from the Apache web site, but the WSDL file, the Component Connector java +code, and all required software for supporting the interface can be found next to the +ESMF distribution in the web_services_server directory. This code is not included with +the ESMF distribution because they can be distributed and installed independent of each other. + +
+The following examples demonstrate how to use ESMF Web Services. + +
+ +
+ +
+ +
+In this example, a standard ESMF Component is made available through + the Web Services interface. + +
+The first step is to make sure your callback routines for initialize, run + and finalize are setup. This is done by creating a register routine that + sets the entry points for each of these callbacks. In this example, we've + packaged it all up into a separate module. +
+
+module ESMF_WebServUserModel + + ! ESMF Framework module + use ESMF + + implicit none + + public ESMF_WebServUserModelRegister + + contains + + !------------------------------------------------------------------------- + ! The Registration routine + ! + subroutine ESMF_WebServUserModelRegister(comp, rc) + type(ESMF_GridComp) :: comp + integer, intent(out) :: rc + + ! Initialize return code + rc = ESMF_SUCCESS + + print *, "User Comp1 Register starting" + + ! Register the callback routines. + + call ESMF_GridCompSetEntryPoint(comp, ESMF_METHOD_INITIALIZE, & + userRoutine=user_init, rc=rc) + if (rc/=ESMF_SUCCESS) return ! bail out + + call ESMF_GridCompSetEntryPoint(comp, ESMF_METHOD_RUN, & + userRoutine=user_run, rc=rc) + if (rc/=ESMF_SUCCESS) return ! bail out + + call ESMF_GridCompSetEntryPoint(comp, ESMF_METHOD_FINALIZE, & + userRoutine=user_final, rc=rc) + if (rc/=ESMF_SUCCESS) return ! bail out + + print *, "Registered Initialize, Run, and Finalize routines" + print *, "User Comp1 Register returning" + + end subroutine + + !------------------------------------------------------------------------- + ! The Initialization routine + ! + subroutine user_init(comp, importState, exportState, clock, rc) + type(ESMF_GridComp) :: comp + type(ESMF_State) :: importState, exportState + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + ! Initialize return code + rc = ESMF_SUCCESS + + print *, "User Comp1 Init" + + end subroutine user_init + + !------------------------------------------------------------------------- + ! The Run routine + ! + subroutine user_run(comp, importState, exportState, clock, rc) + type(ESMF_GridComp) :: comp + type(ESMF_State) :: importState, exportState + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + ! Initialize return code + rc = ESMF_SUCCESS + + print *, "User Comp1 Run" + + end subroutine user_run + + !------------------------------------------------------------------------- + ! The Finalization routine + ! + subroutine user_final(comp, importState, exportState, clock, rc) + type(ESMF_GridComp) :: comp + type(ESMF_State) :: importState, exportState + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + ! Initialize return code + rc = ESMF_SUCCESS + + print *, "User Comp1 Final" + + end subroutine user_final + +end module ESMF_WebServUserModel ++ +
+The actual driver code then becomes very simple; ESMF is initialized, + the component is created, the callback functions for the component are + registered, and the Web Service loop is started. +
+
+program WebServicesEx +#include "ESMF.h" + + ! ESMF Framework module + use ESMF + use ESMF_TestMod + + use ESMF_WebServMod + use ESMF_WebServUserModel + + implicit none + + ! Local variables + type(ESMF_GridComp) :: comp1 !! Grid Component + integer :: rc !! Return Code + integer :: finalrc !! Final return code + integer :: portNum !! The port number for the listening socket ++ +
+A listening socket will be created on the local machine with the specified + port number. This socket is used by the service to + wait for and receive requests from the client. Check with your system + administrator to determine an appropriate port to use for your service. +
+
+ finalrc = ESMF_SUCCESS + + call ESMF_Initialize(defaultlogfilename="WebServicesEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+
+ ! create the grid component + comp1 = ESMF_GridCompCreate(name="My Component", rc=rc) ++ +
+
+ ! Set up the register routine + call ESMF_GridCompSetServices(comp1, & + userRoutine=ESMF_WebServUserModelRegister, rc=rc) ++ +
+
+ portNum = 27060 + + ! Call the Web Services Loop and wait for requests to come in + !call ESMF_WebServicesLoop(comp1, portNum, rc=rc) ++ +
+The call to ESMF_WebServicesLoop will setup the listening socket for your + service and will wait for requests from a client. As requests are received, + the Web Services software will process the requests and then return to the + loop to continue to wait. + +
+The 3 main requests processed are INIT, RUN, and FINAL. These requests + will then call the appropriate callback routine as specified in your + register routine (as specified in the ESMF_GridCompSetServices call). + In this example, when the INIT request is received, the user_init routine + found in the ESMF_WebServUserModel module is called. + +
+One other request is also processed by the Component Service, and that is + the EXIT request. When this request is received, the Web Services loop + is terminated and the remainder of the code after the ESMF_WebServicesLoop + call is executed. +
+
+ call ESMF_Finalize(rc=rc) ++ +
+
+end program WebServicesEx ++ +
+ + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_WebServicesLoop(comp, portNum, clientId, registrarHost, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + integer, intent(inout), optional :: portNum + character(len=*), intent(in), optional, target :: clientId + character(len=*), intent(in), optional, target :: registrarHost + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Encapsulates all of the functionality necessary to setup a component as + a component service. On the root PET, it registers the + component service and then enters into a loop that waits for requests on + a socket. The loop continues until an "exit" request is received, at + which point it exits the loop and unregisters the service. On + any PET other than the root PET, it sets up a process block that waits + for instructions from the root PET. Instructions will come as requests + are received from the socket. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_WebServicesCplCompLoop(comp, portNum, clientId, registrarHost, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + integer, intent(inout), optional :: portNum + character(len=*), intent(in), optional, target :: clientId + character(len=*), intent(in), optional, target :: registrarHost + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Encapsulates all of the functionality necessary to setup a component as + a component service. On the root PET, it registers the + component service and then enters into a loop that waits for requests on + a socket. The loop continues until an "exit" request is received, at + which point it exits the loop and unregisters the service. On + any PET other than the root PET, it sets up a process block that waits + for instructions from the root PET. Instructions will come as requests + are received from the socket. + +
+The arguments are: +
+ + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_refdoc/node5.html b/docs/nightly/fix/reconcile-info/ESMF_refdoc/node5.html new file mode 100644 index 000000000..2e2f9aa40 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_refdoc/node5.html @@ -0,0 +1,65565 @@ + + + + + ++The ESMF infrastructure data classes are part of the framework's +hierarchy of structures for handling Earth system model data and +metadata on parallel platforms. The hierarchy is in complexity; the +simplest data class in the infrastructure represents a distributed data +array and the most complex data class represents a bundle of physical +fields that are discretized on the same grid. Data class methods +are called both from user-written code and from other classes +internal to the framework. + +
+Data classes are distributed over DEs, or Decomposition Elements. +A DE represents a piece of a decomposition. A DELayout is a collection +of DEs with some associated connectivity that describes a specific +distribution. For example, the distribution of a grid divided +into four segments in the x-dimension would be expressed in ESMF as +a DELayout with four DEs lying along an x-axis. This abstract concept +enables a data decomposition to be defined in +terms of threads, MPI processes, virtual decomposition elements, or +combinations of these without changes to user code. This is a +primary strategy for ensuring optimal performance and portability +for codes using ESMF for communications. + +
+ESMF data classes provide a standard, +convenient way for developers to collect together information +related to model or observational data. The information assembled +in a data class includes a data pointer, a set of attributes +(e.g. units, although attributes can also be user-defined), and a +description of an associated grid. The same set of information within +an ESMF data object can be used by the framework to arrange +intercomponent data transfers, to perform I/O, for communications +such as gathers and scatters, for simplification of interfaces +within user code, for debugging, and for other functions. +This unifies and organizes codes overall so that the user need not +define different representations of metadata for the same field +for I/O and for component coupling. + +
+Since it is critical that users be able to introduce ESMF into their +codes easily and incrementally, ESMF data classes can be created based +on native Fortran pointers. Likewise, there are methods for retrieving +native Fortran pointers from within ESMF data objects. This allows +the user to perform allocations using ESMF, and to retrieve Fortran +arrays later for optimized model calculations. The ESMF data classes +do not have associated differential operators or other mathematical +methods. + +
+For flexibility, it is not necessary to build an ESMF data object +all at once. For example, it's possible to create a +field but to defer allocation of the associated field data until +a later time. + +
+
+ +Key Features |
+
Hierarchy of data structures designed specifically for the Earth +system domain and high performance, parallel computing. | +
Multi-use ESMF structures simplify user code overall. | +
Data objects support incremental construction and deferred allocation. | +
Native Fortran arrays can be associated with or retrieved from ESMF data +objects, for ease of adoption, convenience, and performance. | +
A variety of operations are provided for manipulating data in data objects +such as regridding, redistribution, halo communication, and sparse matrix multiply. | +
+The main classes that are used for model and observational data manipulation +are as follows: + +
+ +
+Data elements in Arrays are partitioned into categories +defined by the role the data element plays in distributed halo +operations. Haloing - sometimes called ghosting - is the +practice of copying portions of array data to multiple memory +locations to ensure that data dependencies can be satisfied +quickly when performing a calculation. ESMF Arrays contain +an exclusive domain, which contains data elements +updated exclusively and definitively by a given DE; a +computational domain, which contains all data elements +with values that are updated by the DE in computations; and +a total domain, which includes both the computational +domain and data elements from other DEs which may be read +but are not updated in computations. + +
+
+
+
+FieldBundle objects contain methods for setting and retrieving constituent +fields, regridding, data I/O, and reordering of data in memory. + +
+
+ +
+Bit-for-bit reproducibility is at the core of the regression testing +schemes of many scientific model codes. The bit-for-bit requirement makes it +easy to compare the numerical results of simulation runs using standard +binary diff tools. + +
+For the most part, ESMF methods do not modify user data numerically, and +thus have no effect on the bit-for-bit characteristics of the model code. +The exceptions are the regrid weight generation and the sparse matrix +multiplication. + +
+In the case of the regrid weight generation, user data is used to produce +interpolation weights following specific numerical schemes. The bit-for-bit +reproducibility of the generated weights depends on the implementation +details. Section 24.2 provides more details about the bit-for-bit +considerations with respect to the regrid weights generated by ESMF. + +
+In the case of the sparse matrix multiplication, which is the typical method +that is used to apply the regrid weights, user data is directly manipulated +by ESMF. In order to help users with the implementation of their bit-for-bit +requirements, while also considering the associated performance impact, +the ESMF sparse matrix implementation provides three levels of bit-for-bit +support. The strictest level ensures that the numerical results are +bit-for-bit identical, even when executing across different numbers of +PETs. In the relaxed level, bit-for-bit reproducibility is guaranteed when +running across an unchanged number of PETs. The lowest level makes no +guarantees about bit-for-bit reproducibility, however, it provides the +greatest performance potential for those cases where numerical round-off +differences are acceptable. An in-depth discussion of bit-for-bit +reproducibility, and the performance aspects of route-based communication +methods, such the sparse matrix multiplication, is given in section +37.2.1. + +
+ +
+This section describes the regridding methods provided by ESMF. Regridding, also called remapping or interpolation, is + the process of changing the grid that underlies data values while preserving qualities of the original data. Different + kinds of transformations are appropriate for different problems. Regridding may be needed when communicating data between + Earth system model components such as land and atmosphere, or between different data sets to support operations such as visualization. + +
+Regridding can be broken into two stages. The first stage is generation of an interpolation weight matrix that describes how points in + the source grid contribute to points in the destination grid. The second stage is the multiplication of values on the source grid by the + interpolation weight matrix to produce values on the destination grid. This is implemented as a parallel sparse matrix multiplication. + +
+There are two options for accessing ESMF regridding functionality: offline and integrated. Offline regridding is a process whereby interpolation + weights are generated by a separate ESMF command line tool, not within the user code. The ESMF offline regridding tool also only generates the interpolation + matrix, the user is responsible for reading in this matrix and doing the actual interpolation (multiplication by the sparse matrix) in their code. + Please see Section 12 for a description of the offline regridding command line tool and the options it supports. For user convenience, there + is also a method interface to the offline regrid tool functionality which is described in Section 24.3.1. + In contrast to offline regridding, integrated regridding is a process whereby interpolation weights are generated via subroutine calls during the + execution of the user's code. In addition to generating the weights, integrated regridding can also produce a RouteHandle (described in Section 37.1) which allows the user to perform the parallel sparse + matrix multiplication using ESMF methods. In other words, ESMF integrated regridding allows a user to perform the whole process of interpolation within their code. + +
+To see what types of grids and other options are supported in the two types of regridding and their testing status, please see the ESMF Regridding Status +webpage for this version of ESMF. + Figure 24.2 shows a comparison of different regrid interfaces and where they can be found in the documentation. + +
+The rest of this section further describes the various options available in ESMF regridding. + +
+
+
+
+
++
|
+ +
+ +
+ ++In 2D, ESMF supports bilinear regridding between any combination of the following: + +
+ +
+ ++In 3D, ESMF supports bilinear regridding between any combination of the following: + +
+ +
+ ++Restrictions: + +
+To use the bilinear method the user may create their Fields on any stagger location (e.g. ESMF_STAGGERLOC_CENTER) for a Grid, or + any Mesh location (e.g. ESMF_MESHLOC_NODE) for a Mesh. For either a Grid or a Mesh, the location upon which the Field is built + must contain coordinates. This method will also work with a destination Field built on a LocStream that contains coordinates, + or with a source or destination Field built on an XGrid. + +
+ +
+Patch (or higher-order) interpolation is the ESMF version of a technique called “patch recovery” commonly + used in finite element modeling [25] [22]. It typically results in better approximations to + values and derivatives when compared to bilinear interpolation. + Patch interpolation works by constructing multiple polynomial patches to represent + the data in a source cell. For 2D grids, these polynomials + are currently 2nd degree 2D polynomials. One patch is constructed for each corner of the source cell, and the patch is constructed + by doing a least squares fit through the data in the cells surrounding the corner. The interpolated value at the destination point is + then a weighted average of the values of the patches at that point. + +
+The patch method has a larger stencil than the bilinear, for this reason the patch weight matrix can be correspondingly larger + than the bilinear matrix (e.g. for a quadrilateral grid the patch matrix is around 4x the size of + the bilinear matrix). This can be an issue when performing a regrid operation close to the memory + limit on a machine. + +
+The patch method does not guarantee that after regridding the range of values in the destination field is within the range of + values in the source field. For example, if the mininum value in the source field is 0.0, then it's possible that after regridding with the + patch method, the destination field will contain values less than 0.0. + +
+ +
+ ++In 2D, ESMF supports patch regridding between any combination of the following: + +
+ +
+ ++In 3D, ESMF supports patch regridding between any combination of the following: + +
+ +
+ ++Restrictions: + +
+To use the patch method the user may create their Fields on any stagger location (e.g. ESMF_STAGGERLOC_CENTER) for a Grid, or + any Mesh location (e.g. ESMF_MESHLOC_NODE) for a Mesh. For either a Grid or a Mesh, the location upon which the Field is built + must contain coordinates. This method will also work with a destination Field built on a LocStream that contains coordinates, + or with a source or destination Field built on an XGrid. + +
+ +
+ +
+ ++In 2D, ESMF supports nearest source to destination regridding between any combination of the following: + +
+ +
+ ++In 3D, ESMF supports nearest source to destination regridding between any combination of the following: + +
+ +
+ +
+Restrictions:
+
+NONE
+
+
+ +
+ ++To use the nearest source to destination method the user may create their Fields on any stagger location (e.g. ESMF_STAGGERLOC_CENTER) for a Grid, or + any Mesh location (e.g. ESMF_MESHLOC_NODE) for a Mesh. For either a Grid or a Mesh, the location upon which the Field is built + must contain coordinates. This method will also work with a source or destination Field built on a LocStream that contains coordinates, or when the source +or destination Field is built on an XGrid. + +
+ +
+ +
+ ++In 2D, ESMF supports nearest destination to source regridding between any combination of the following: + +
+ +
+ ++In 3D, ESMF supports nearest destination to source regridding between any combination of the following: + +
+ +
+ +
+Restrictions:
+
+
+
+ +
+ ++To use the nearest destination to source method the user may create their Fields on any stagger location (e.g. ESMF_STAGGERLOC_CENTER) for a Grid, or + any Mesh location (e.g. ESMF_MESHLOC_NODE) for a Mesh. For either a Grid or a Mesh, the location upon which the Field is built + must contain coordinates. This method will also work with a source or destination Field built on a LocStream that contains coordinates, or when the source +or destination Field is built on an XGrid. + +
+ +
+In the first-order method, the values for a particular destination cell are a calculated as a combination of the values of the intersecting + source cells. The weight of a given source cell's contribution + to the total being the amount that that source cell overlaps with the destination cell. + In particular, the weight is the ratio of the area of intersection of the source and destination cells to the area of the whole destination cell. + +
+To see a description of how the different normalization options affect the values and integrals produced by the conservative methods see section 24.2.8. For Grids, Meshes, or XGrids on a sphere this method uses great circle cells, for a description of potential problems with these see 24.2.9. + +
+ +
+ ++In 2D, ESMF supports conservative regridding between any combination of the following: + +
+ +
+ ++In 3D, ESMF supports conservative regridding between any combination of the following: + +
+ +
+ ++Restrictions: + +
+ +
+ ++To use the conservative method the user should create their Fields on the center + stagger location (ESMF_STAGGERLOC_CENTER in 2D or ESMF_STAGGERLOC_CENTER_VCENTER in 3D) for Grids or the element location (ESMF_MESHLOC_ELEMENT) for Meshes. + For Grids, the corner stagger location (ESMF_STAGGERLOC_CORNER in 2D or ESMF_STAGGERLOC_CORNER_VFACE in 3D) must contain coordinates describing the outer perimeter of the Grid cells. This method will also work when the source or destination Field is built on an XGrid. + +
+ +
+Like the first-order method, the values for a particular destination cell with the second-order method + are a combination of the values of the intersecting source cells with the weight of a given source cell's contribution to the total + being the amount that that source cell overlaps with the destination cell. + However, with the second-order conservative interpolation there are additional terms that take into account the gradient of the field + across the source cell. In particular, the value for a given destination cell is calculated as: + +
+ + + +
+ +
+ +
+Where:
+
+
+ +
+ ++To see a description of how the different normalization options affect the values and integrals produced by the conservative methods see section 24.2.8. For Grids, Meshes, or XGrids on a sphere this method uses great circle cells, for a description of potential problems with these see 24.2.9. + +
+ +
+ ++In 2D, ESMF supports second-order conservative regridding between any combination of the following: + +
+ +
+ ++In 3D, ESMF supports second-order conservative regridding between any combination of the following: + +
+ +
+ ++Restrictions: + +
+ +
+ ++To use the second-order conservative method the user should create their Fields on the center + stagger location (ESMF_STAGGERLOC_CENTER for Grids or the element location (ESMF_MESHLOC_ELEMENT) for Meshes. + For Grids, the corner stagger location (ESMF_STAGGERLOC_CORNER in 2D must contain coordinates describing the outer perimeter of the Grid cells. + This method will also work when the source or destination Field is built on an XGrid. + +
+ +
+If the user doesn't specify a cell areas in the involved Grids or Meshes, then the areas (A) in the above equation are calculated by ESMF. + For Cartesian grids, the area of a grid cell calculated by ESMF is the typical Cartesian area. + For grids on a sphere, cell areas are calculated by connecting the corner coordinates of each grid cell with great circles. If the user + does specify the areas in the Grid or Mesh, then the conservation will be adjusted to work for the areas + provided by the user. This means that the above equation will hold, but with the areas (A) being the ones specified by the user. + +
+The user should be aware that because of the conservation relationship between the source and destination fields, the more the total source area + differs from the total destination area the more the values of the source field will differ from the corresponding values of the destination field, + likely giving a higher interpolation error. It is best to have the total source and destination areas the same + (this will automatically be true if no user areas are specified). For source and destination grids + that only partially overlap, the overlapping regions of the source and destination should be the same. + +
+ +
+For weights generated using destination area normalization (either by not specifying any normalization type or by specifying normType=ESMF_NORMTYPE_DSTAREA), if a destination field extends +outside the unmasked source field, then the values of the cells which +extend partway outside the unmasked source field are decreased by the fraction they extend outside. +To correct these values, the destination field (dst_field) resulting +from the ESMF_FieldRegrid() call can be divided by the destination fraction dst_frac +from the ESMF_FieldRegridStore() call. The following pseudocode demonstrates how to do this: + +
+
+ + for each destination element i + if (dst_frac(i) not equal to 0.0) then + dst_field(i)=dst_field(i)/dst_frac(i) + end if + end for ++ +
+For weights generated using destination area normalization (either by not specifying any normalization type or by specifying normType=ESMF_NORMTYPE_DSTAREA), +the following pseudo-code shows how to compute the total destination integral (dst_total) given the +destination field values (dst_field) resulting +from the ESMF_FieldRegrid() call, the destination area (dst_area) from the ESMF_FieldRegridGetArea() call, and the destination fraction (dst_frac) from the ESMF_FieldRegridStore() call. As shown in the previous paragraph, it also +shows how to adjust the destination field (dst_field) resulting from the ESMF_FieldRegrid() call by the +fraction (dst_frac) from the ESMF_FieldRegridStore() call: + +
+
+ + dst_total=0.0 + for each destination element i + if (dst_frac(i) not equal to 0.0) then + dst_total=dst_total+dst_field(i)*dst_area(i) + dst_field(i)=dst_field(i)/dst_frac(i) + ! If mass computed here after dst_field adjust, would need to be: + ! dst_total=dst_total+dst_field(i)*dst_area(i)*dst_frac(i) + end if + end for ++ +
+For weights generated using fraction area normalization (by specifying normType=ESMF_NORMTYPE_FRACAREA), +no adjustment of the destination field is necessary. The following pseudo-code shows how to compute +the total destination integral (dst_total) given the +destination field values (dst_field) resulting +from the ESMF_FieldRegrid() call, the destination area (dst_area) from the ESMF_FieldRegridGetArea() +call, and the destination fraction (dst_frac) from the ESMF_FieldRegridStore() call: + +
+
+ dst_total=0.0 + for each destination element i + dst_total=dst_total+dst_field(i)*dst_area(i)*dst_frac(i) + end for ++ +
+For both normalization types, the following pseudo-code shows how to compute the total source integral (src_total) given the source field values + (src_field), the source area (src_area) from the ESMF_FieldRegridGetArea() call, and + the source fraction (src_frac) from the ESMF_FieldRegridStore() call: + +
+
+ src_total=0.0 + for each source element i + src_total=src_total+src_field(i)*src_area(i)*src_frac(i) + end for ++ +
+ +
+A great circle edge isn't necessarily the same as a straight line in latitude longitude space. + For small edges, this difference will be small, but for long edges it + could be significant. This means if the user expects cell edges as straight lines in latitude longitude + space, they should avoid using one large cell with + long edges to compute an average over a region (e.g. over an ocean basin). + +
+Also, the user should also avoid using cells that contain one edge that runs half way or more around the earth, because the + regrid weight calculation assumes the edge follows the shorter great circle path. + There isn't a unique great circle edge defined between points on the + exact opposite side of the earth from one another (antipodal points). + However, the user can work around both of these problem by breaking the long edge into two smaller edges by inserting + an extra node, or by breaking the large target grid cells + into two or more smaller grid cells. This allows the application to resolve the ambiguity in edge direction. + +
+ +
+The user may mask out points in the source +Field or destination Field or both. To do masking the user sets +mask information in the Grid (see 31.3.17), Mesh +(see 33.3.11), or LocStream (see 32.2.2) +upon which the Fields passed into the +ESMF_FieldRegridStore() call are built. The srcMaskValues +and dstMaskValues arguments to that +call can then be used to specify which values in that mask +information indicate that a location should be masked out. For +example, if dstMaskValues is set to (/1,2/), then any location that +has a value of 1 or 2 in the mask information of the Grid, Mesh or LocStream +upon which the destination Field is built will be masked out. + +
+Masking behavior differs slightly between regridding methods. For +non-conservative regridding methods (e.g. bilinear or high-order +patch), masking is done on points. For these methods, masking a +destination point means that that point won't participate in +regridding (e.g. won't be interpolated to). For these methods, +masking a source point means that the entire source cell using +that point is masked out. In other words, if any corner point +making up a source cell is masked then the cell is masked. For +conservative regridding methods (e.g. first-order conservative) +masking is done on cells. Masking a destination cell means that +the cell won't participate in regridding (e.g. won't be +interpolated to). Similarly, masking a source cell means that the +cell won't participate in regridding (e.g. won't be interpolated +from). For any type of interpolation method (conservative or +non-conservative) the masking is set on the location upon +which the Fields passed into the regridding call are built. +For example, if Fields built on ESMF_STAGGERLOC_CENTER are +passed into the ESMF_FieldRegridStore() call then the masking +should also be set on ESMF_STAGGERLOC_CENTER. + +
+ +
+Extrapolation in the ESMF regridding system is a way to automatically fill some or all of the +destination points left unmapped by a regridding method. Weights generated by +the extrapolation method are merged into the regridding weights to yield one set of weights or +routehandle. Currently extrapolation is not supported with conservative regridding methods, because +doing so would result in non-conservative weights. + +
+ +
+If there is at least one unmasked source point, then this method is expected to fill all unmapped points. + +
+ +
+If there is at least one unmasked source point, then this method is expected to fill all unmapped points. + +
+ +
+Unlike some extrapolation methods, creep fill does not necessarily +fill all unmapped destination points. Unfilled destination points are still unmapped with the usual +consequences (e.g. they won't be in the resulting regridding matrix, and won't be set by the application +of the regridding weights). + +
+Because it depends on the connections in the destination grid, creep fill extrapolation is not supported when the +destination Field is built on a Location Stream (ESMF_LocStream). Also, creep fill is currently only supported for +2D Grids, Meshes, or XGrids + +
+ +
+ +
+For Grids on a sphere, the regridding occurs in 3D Cartesian to avoid +problems with periodicity and with the pole singularity. This library + supports four options for handling the pole region (i.e. the empty area above the top row of the source grid or below + the bottom row of the source grid). Note that all of these pole options currently only work for the Fields build on the Grid class. + +
+The first option is to leave the pole region empty (polemethod=ESMF_POLEMETHOD_NONE), in this + case if a destination point lies above or below the + top row of the source grid, it will fail to map, yielding an error (unless unmappedaction=ESMF_UNMAPPEDACTION_IGNORE is specified). + +
+With the next two options (ESMF_POLEMETHOD_ALLAVG and ESMF_POLEMETHOD_NPNTAVG), the pole region is handled by constructing + an artificial pole in the center of the top and bottom row of grid points and then filling + in the region from this pole to the edges of the source grid with triangles. + The pole is located at the average of the position of the points surrounding + it, but moved outward to be at the same radius as the rest of the points + in the grid. The difference between the two artificial pole options is what value is used at the pole. + The option (polemethod=ESMF_POLEMETHOD_ALLAVG) sets the value at the pole to be the average of the values + of all of the grid points surrounding the pole. The option (polemethod=ESMF_POLEMETHOD_NPNTAVG) allows the user to choose + a number N from 1 to the number of source grid points around the pole. The value N is set via the argument regridPoleNPnts. For + each destination point, the value at the pole is then the average of the N source points + surrounding that destination point. + +
+The last option (polemethod=ESMF_POLEMETHOD_TEETH) does not construct an artificial pole, instead the + pole region is covered by connecting points across the top and bottom row of the source Grid into triangles. As + this makes the top and bottom of the source sphere flat, for a big enough difference between the size of + the source and destination pole regions, this can still result in unmapped destination points. + Only pole option ESMF_POLEMETHOD_NONE is currently supported with the conservative interpolation methods + (e.g. regridmethod=ESMF_REGRIDMETHOD_CONSERVE) and with the nearest neighbor interpolation options (e.g. regridmethod=ESMF_REGRIDMETHOD_NEAREST_STOD). + +
+
+Another variation in the regridding supported with spherical grids is line type. This is controlled in the +ESMF_FieldRegridStore() method by the lineType argument. This argument allows the user to select the path of the line which connects +two points on a sphere surface. This in turn controls the path along which distances are calculated and the shape of +the edges that make up a cell. Both of these quantities can influence how interpolation weights are calculated, for example in +bilinear interpolation the distances are used to calculate the weights and the cell edges are used to determine to which source +cell a destination point should be mapped. + +
+ESMF currently supports two line types: ESMF_LINETYPE_CART and ESMF_LINETYPE_GREAT_CIRCLE. The ESMF_LINETYPE_CART option +specifies that the line between two points follows a straight path through the 3D Cartesian space in which the sphere is embedded. +Distances are measured along +this 3D Cartesian line. Under this option cells are approximated by planes in 3D space, and their boundaries are 3D Cartesian lines +between their corner points. The ESMF_LINETYPE_GREAT_CIRCLE option specifies that the line between two points follows +a great circle path along the sphere surface. (A great circle is the shortest path between two points on a sphere.) +Distances are measured along the great circle path. Under this option cells are on the sphere surface, and their boundaries +are great circle paths between their corner points. + +
+Figure 24.2.16 shows which line types are supported for each regrid method as well as the defaults (indicated by *). + +
+ +
+ESMF's initial vector regridding capability is intended to give cleaner results for 2D spherical vectors expressed in +terms of local directions (e.g. east and north) than regridding each vector component separately. To do this, it +converts the vectors to 3D Cartesian space and then does the regridding there. This allows all the vectors participating in +the regridding to have a consistent representation. After regridding, the resulting 3D vectors are then converted +back to the local direction form. This entire process is expressed in the usual weight matrix and/or routeHandle form and so +the typical ESMF_FieldRegridStore()/ESMF_FieldRegrid()/ESMF_FieldRegridRelease() regridding paradigm can be used. +However, the weight matrix will be in the format that allows it to contain tensor dimension indices (i.e. the leading +dimension of the factorIndexList will be of size 4). + +
+In this initial version, the meaning of the different entries in the vector dimension are fixed. They will be interpreted as:
+
+
+Note that because the different components are mixed, using vector regridding with a conservative regrid method will not necessarily produce vectors whose components are conservative. + +
+ +
+The below is a list of problems users commonly encounter with regridding and potential solutions. + This is by no means an exhaustive list, so if none of these problems fit your case, or if the solutions + don't fix your problem, please feel free to email esmf support (esmf_support@ucar.edu). + +
+ +
+
+
+
+Problem: Regridding is too slow. + +
+ +
+
+
+
+Possible Cause: The ESMF_FieldRegridStore() method is called more than is necessary.
+The ESMF_FieldRegridStore() operation is a complex one and can be
+ relatively slow for some cases (large Grids, 3D grids, etc.)
+
+
+ +
+ ++Solution: Reduce the number of ESMF_FieldRegridStore() calls to the minimum necessary. The + routeHandle generated by the ESMF_FieldRegridStore() call depends on only four factors: the + stagger locations that the input Fields are created on, the coordinates in the Grids the input Fields + are built on at those stagger locations, the padding of the input Fields + (specified by the totalWidth arguments in FieldCreate) and the size of the tensor + dimensions in the input Fields (specified by the ungridded arguments in FieldCreate). + For any pair of Fields which share these attributes with the Fields used in the + ESMF_FieldRegridStore call the same routeHandle can be used. Note that the data in the + Fields does NOT matter, the same routeHandle can be used no matter how the data in the Fields changes. + +
+ +
+ ++In particular: + +
+
+ +
+
+
+
+Problem: Distortions in destination Field at periodic boundary. + +
+ +
+
+
+
+Possible Cause: The Grid overlaps itself. With a periodic Grid, the regrid system expects + the first point to not be a repeat of the last point. In other words, + regrid constructs its own connection and overlap between the first and last points of the + periodic dimension and so the Grid doesn't need to contain these. If the Grid does, then this + can cause problems. + +
+ +
+ ++Solution: Define the Grid so that it doesn't contain the overlap point. This typically means simply making + the Grid one point smaller in the periodic dimension. If a Field + constructed on the Grid needs to contain these overlap points then the user can use the + totalWidth arguments to include this extra padding in the Field. Note, however, + that the regrid won't update these extra points, so the user will have to do a copy to fill the points + in the overlap region in the Field. + +
+ +
+ +
+
+ +
+The ESMF regrid weight calculation functionality has been designed to enable it to support a wide range +of grid and interpolation types without needing to support each individual combination of source grid type, +destination grid type, and interpolation method. To avoid the quadratic growth of the number of pairs +of grid types, all grids are converted to a common internal format and the regrid weight calculation +is performed on that format. This vastly reduces the variety of grids that need to be supported in +the weight calculations for each interpolation method. It also has the added benefit of making it +straightforward to add new grid types and to allow them to work with all the existing grid types. +To hook into the existing weight calculation code, the new type just needs to be converted to the +internal format. + +
+The internal grid format used by the ESMF regrid weight calculation is a finite element +unstructured mesh. This was chosen because it was the most general format and all the others could be +converted to it. The ESMF finite element unstructured mesh (ESMF FEM) is similar in some respects to the SIERRA [20] package +developed at Sandia National Laboratory. The ESMF code relies on some of the same underlying toolkits (e.g. Zoltan [18] library +for calculating mesh partitions) and adds a layer on top that allows the calculation of regrid weights and some mesh operations +(e.g. mesh redistribution) that ESMF needs. The ESMF FEM has similar notions to SIERRA about the basic structure of the +mesh entities, fields, iteration and a similar notion of parallel distribution. + +
+Currently we use the ESMF FEM internal mesh to hold the structure of our Mesh class and +in our regrid weight calculation. The parts of the internal FEM code that are used/tested by ESMF are the following: + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_RegridWeightGen() + subroutine ESMF_RegridWeightGenFile(srcFile, dstFile, & + weightFile, rhFile, regridmethod, polemethod, regridPoleNPnts, lineType, normType, & + extrapMethod, extrapNumSrcPnts, extrapDistExponent, extrapNumLevels, & + unmappedaction, ignoreDegenerate, srcFileType, dstFileType, & + srcRegionalFlag, dstRegionalFlag, srcMeshname, dstMeshname, & + srcMissingvalueFlag, srcMissingvalueVar, & + dstMissingvalueFlag, dstMissingvalueVar, & + useSrcCoordFlag, srcCoordinateVars, & + useDstCoordFlag, dstCoordinateVars, & + useSrcCornerFlag, useDstCornerFlag, & + useUserAreaFlag, largefileFlag, & + netcdf4fileFlag, weightOnlyFlag, & + tileFilePath, & + verboseFlag, checkFlag, rc) +ARGUMENTS: +
+ character(len=*), intent(in) :: srcFile + character(len=*), intent(in) :: dstFile + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: weightFile + character(len=*), intent(in), optional :: rhFile + type(ESMF_RegridMethod_Flag), intent(in), optional :: regridmethod + type(ESMF_PoleMethod_Flag), intent(in), optional :: polemethod + integer, intent(in), optional :: regridPoleNPnts + type(ESMF_LineType_Flag), intent(in), optional :: lineType + type(ESMF_NormType_Flag), intent(in), optional :: normType + type(ESMF_ExtrapMethod_Flag), intent(in), optional :: extrapMethod + integer, intent(in), optional :: extrapNumSrcPnts + real, intent(in), optional :: extrapDistExponent + integer, intent(in), optional :: extrapNumLevels + type(ESMF_UnmappedAction_Flag),intent(in), optional :: unmappedaction + logical, intent(in), optional :: ignoreDegenerate + type(ESMF_FileFormat_Flag), intent(in), optional :: srcFileType + type(ESMF_FileFormat_Flag), intent(in), optional :: dstFileType + logical, intent(in), optional :: srcRegionalFlag + logical, intent(in), optional :: dstRegionalFlag + character(len=*), intent(in), optional :: srcMeshname + character(len=*), intent(in), optional :: dstMeshname + logical, intent(in), optional :: srcMissingValueFlag + character(len=*), intent(in), optional :: srcMissingValueVar + logical, intent(in), optional :: dstMissingValueFlag + character(len=*), intent(in), optional :: dstMissingValueVar + logical, intent(in), optional :: useSrcCoordFlag + character(len=*), intent(in), optional :: srcCoordinateVars(:) + logical, intent(in), optional :: useDstCoordFlag + character(len=*), intent(in), optional :: dstCoordinateVars(:) + logical, intent(in), optional :: useSrcCornerFlag + logical, intent(in), optional :: useDstCornerFlag + logical, intent(in), optional :: useUserAreaFlag + logical, intent(in), optional :: largefileFlag + logical, intent(in), optional :: netcdf4fileFlag + logical, intent(in), optional :: weightOnlyFlag + character(len=*), intent(in), optional :: tileFilePath + logical, intent(in), optional :: verboseFlag + logical, intent(in), optional :: checkFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This subroutine provides the same function as the ESMF_RegridWeightGen application + described in Section 12. It takes two grid files in NetCDF format and writes out an + interpolation weight file also in NetCDF format. The interpolation weights can be generated with the + bilinear (24.2.1), higher-order patch (24.2.2), + or first order conservative (24.2.5) methods. The grid files can be in + one of the following four formats: + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_RegridWeightGen() + subroutine ESMF_RegridWeightGenDG(srcFile, dstFile, regridRouteHandle, & + srcElementDistgrid, dstElementDistgrid, & + srcNodalDistgrid, dstNodalDistgrid, & + weightFile, regridmethod, lineType, normType, & + extrapMethod, extrapNumSrcPnts, extrapDistExponent, extrapNumLevels,& + unmappedaction, ignoreDegenerate, useUserAreaFlag, & + largefileFlag, netcdf4fileFlag, & + weightOnlyFlag, verboseFlag, rc) +ARGUMENTS: +
+ character(len=*), intent(in) :: srcFile + character(len=*), intent(in) :: dstFile + type(ESMF_RouteHandle), intent(out) :: regridRouteHandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DistGrid), intent(in), optional :: srcElementDistgrid + type(ESMF_DistGrid), intent(in), optional :: dstElementDistgrid + character(len=*), intent(in), optional :: weightFile + type(ESMF_DistGrid), intent(in), optional :: srcNodalDistgrid + type(ESMF_DistGrid), intent(in), optional :: dstNodalDistgrid + type(ESMF_RegridMethod_Flag), intent(in), optional :: regridmethod + type(ESMF_LineType_Flag), intent(in), optional :: lineType + type(ESMF_NormType_Flag), intent(in), optional :: normType + type(ESMF_ExtrapMethod_Flag), intent(in), optional :: extrapMethod + integer, intent(in), optional :: extrapNumSrcPnts + real, intent(in), optional :: extrapDistExponent + integer, intent(in), optional :: extrapNumLevels + type(ESMF_UnmappedAction_Flag),intent(in), optional :: unmappedaction + logical, intent(in), optional :: ignoreDegenerate + logical, intent(in), optional :: useUserAreaFlag + logical, intent(in), optional :: largefileFlag + logical, intent(in), optional :: netcdf4fileFlag + logical, intent(in), optional :: weightOnlyFlag + logical, intent(in), optional :: verboseFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This subroutine does online regridding weight generation from files with user specified distribution. + The main differences between this API and the one in 24.3.1 are listed below: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FileRegrid(srcFile, dstFile, srcVarName, dstVarName, & + dstLoc, srcDataFile, dstDataFile, tileFilePath, & + dstCoordVars, regridmethod, polemethod, regridPoleNPnts, & + unmappedaction, ignoreDegenerate, srcRegionalFlag, dstRegionalFlag, & + verboseFlag, rc) +ARGUMENTS: +
+ character(len=*), intent(in) :: srcFile + character(len=*), intent(in) :: dstFile + character(len=*), intent(in) :: srcVarName + character(len=*), intent(in) :: dstVarName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: dstLoc + character(len=*), intent(in), optional :: srcDataFile + character(len=*), intent(in), optional :: dstDataFile + character(len=*), intent(in), optional :: tileFilePath + character(len=*), intent(in), optional :: dstCoordVars + type(ESMF_RegridMethod_Flag), intent(in), optional :: regridmethod + type(ESMF_PoleMethod_Flag), intent(in), optional :: polemethod + integer, intent(in), optional :: regridPoleNPnts + type(ESMF_UnmappedAction_Flag),intent(in), optional :: unmappedaction + logical, intent(in), optional :: ignoreDegenerate + logical, intent(in), optional :: srcRegionalFlag + logical, intent(in), optional :: dstRegionalFlag + logical, intent(in), optional :: verboseFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This subroutine provides the same function as the ESMF_Regrid application + described in Section 13. It takes two grid files in NetCDF format and interpolate + the variable defined in the source grid file to the destination variable using one of the ESMF supported + regrid methods - bilinear (24.2.1), higher-order patch (24.2.2), + first order conservative (24.2.5) or nearest neighbor methods. + The grid files can be in one of the following two formats: + +
+The arguments are: +
+ +
+A FieldBundle functions mainly as a convenient container for storing +similar Fields. It represents “bundles” of Fields that are +discretized on the same Grid, Mesh, LocStream, or XGrid and distributed in the same manner. +The FieldBundle is an important data structure because it can be added to a State, +which is used for sending and receiving data between Components. + +
+In the common case where FieldBundle is built on top of a Grid, +Fields within a FieldBundle may be located at different locations relative +to the vertices of their common Grid. The Fields in a FieldBundle may +be of different dimensions, as long as the Grid dimensions that +are distributed are the same. For example, a surface Field on +a distributed lat/lon Grid and a 3D Field with an added vertical +dimension on the same distributed lat/lon Grid can be included +in the same FieldBundle. + +
+FieldBundles can be created and destroyed, can have Attributes +added or retrieved, and can have Fields added, removed, replaced, or retrieved. +Methods include queries that return information about the FieldBundle +itself and about the Fields that it contains. The Fortran +data pointer of a Field within a FieldBundle can be obtained +by first retrieving the Field with a call to ESMF_FieldBundleGet(), +and then using ESMF_FieldGet() to get the data. + +
+In the future FieldBundles will serve as a mechanism for performance +optimization. ESMF will take advantage of the similarities of the +Fields within a FieldBundle to optimize collective communication, +I/O, and regridding. See Section 25.3 for a +description of features that are scheduled for future work. + +
+Examples of creating, accessing and destroying FieldBundles and their +constituent Fields are provided in this section, along with some +notes on FieldBundle methods. + +
+ +
+ +
+ +
+
+!------------------------------------------------------------------------- +! ! Create several Fields and add them to a new FieldBundle. + + grid = ESMF_GridCreateNoPeriDim(minIndex=(/1,1/), maxIndex=(/100,200/), & + regDecomp=(/2,2/), name="atmgrid", rc=rc) ++ +
+
+ call ESMF_ArraySpecSet(arrayspec, 2, ESMF_TYPEKIND_R8, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + field(1) = ESMF_FieldCreate(grid, arrayspec, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="temperature", rc=rc) ++ +
+
+ field(2) = ESMF_FieldCreate(grid, arrayspec, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="pressure", rc=rc) ++ +
+
+ field(3) = ESMF_FieldCreate(grid, arrayspec, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="heat flux", rc=rc) ++ +
+
+ bundle1 = ESMF_FieldBundleCreate(fieldList=field(1:3), & + name="atmosphere data", rc=rc) + + print *, "FieldBundle example 1 returned" ++ +
+ +
+
+!------------------------------------------------------------------------- +! ! Create an empty FieldBundle and then add a single field to it. + + + simplefield = ESMF_FieldCreate(grid, arrayspec, & + staggerloc=ESMF_STAGGERLOC_CENTER, name="rh", rc=rc) ++ +
+
+ bundle2 = ESMF_FieldBundleCreate(name="time step 1", rc=rc) ++ +
+
+ call ESMF_FieldBundleAdd(bundle2, (/simplefield/), rc=rc) ++ +
+
+ call ESMF_FieldBundleGet(bundle2, fieldCount=fieldcount, rc=rc) + + print *, "FieldBundle example 2 returned, fieldcount =", fieldcount ++ +
+ +
+
+!------------------------------------------------------------------------- +! ! Create an empty FieldBundle and then add multiple fields to it. + + bundle3 = ESMF_FieldBundleCreate(name="southern hemisphere", rc=rc) ++ +
+
+ call ESMF_FieldBundleAdd(bundle3, field(1:3), rc=rc) ++ +
+
+ call ESMF_FieldBundleGet(bundle3, fieldCount=fieldcount, rc=rc) + + print *, "FieldBundle example 3 returned, fieldcount =", fieldcount ++ +
+ +
+
+!------------------------------------------------------------------------- +! ! Get a Field back from a FieldBundle, first by name and then by index. +! ! Also get the FieldBundle name. + + call ESMF_FieldBundleGet(bundle1, "pressure", field=returnedfield1, rc=rc) ++ +
+
+ call ESMF_FieldGet(returnedfield1, name=fname1, rc=rc) ++ +
+
+ call ESMF_FieldBundleGet(bundle1, 2, returnedfield2, rc=rc) ++ +
+
+ call ESMF_FieldGet(returnedfield2, name=fname2, rc=rc) ++ +
+
+ call ESMF_FieldBundleGet(bundle1, name=bname1, rc=rc) + + print *, "FieldBundle example 4 returned, field names = ", & + trim(fname1), ", ", trim(fname2) + print *, "FieldBundle name = ", trim(bname1) ++ +
+ +
+
+ call ESMF_FieldBundleGet(bundle1, fieldList=r_fields, rc=rc) ++ +
+
+ do i = 1, 3 + call ESMF_FieldGet(r_fields(i), name=fname1, rc=rc) ++ +
+
+ print *, fname1 + enddo ++ +
+
+ call ESMF_FieldBundleGet(bundle1, fieldList=r_fields, & + itemorderflag=ESMF_ITEMORDER_ADDORDER, rc=rc) ++ +
+
+ do i = 1, 3 + call ESMF_FieldGet(r_fields(i), name=fname1, rc=rc) ++ +
+
+ print *, fname1 + enddo ++ +
+ +
+Create a 2D grid of 4x1 regular decomposition on 4 PETs, each PET has 10x50 elements. + The index space of the entire Grid is 40x50. +
+
+ gridxy = ESMF_GridCreateNoPeriDim(maxIndex=(/40,50/), regDecomp=(/4,1/), rc=rc) ++ +
+Allocate a packed Fortran array pointer containing 10 packed fields, each field has + 3 time slices and uses the 2D grid created. Note that gridToFieldMap uses the position + of the grid dimension as elements, 3rd element of the packedPtr is 10, 4th element + of the packedPtr is 50. +
+
+ allocate(packedPtr(10, 3, 10, 50)) ! fieldDim, time, y, x + fieldDim = 1 + packedFB = ESMF_FieldBundleCreate(fieldNameList, packedPtr, gridxy, fieldDim, & + gridToFieldMap=(/3,4/), staggerloc=ESMF_Staggerloc_Center, rc=rc) ++ +
+ +
+Due to the verbosity of the MeshCreate process, the code for MeshCreate is + not shown below, user can either refer to the MeshCreate section + 33.3.1 + or examine the FieldBundleCreate example source code contained + in the ESMF source distribution directly. + A ESMF Mesh on 4 PETs with one mesh element on each PET is created. + +
+Allocate the packed Fortran array pointer, the first dimension + is fieldDim; second dimension is the data associated with mesh element, + since there is only one mesh element on each processor in this example, + the allocation is 1; last dimension is the time dimension which contains + 3 time slices. +
+
+ allocate(packedPtr3D(10, 1, 3)) + fieldDim = 1 + packedFB = ESMF_FieldBundleCreate(fieldNameList, packedPtr3D, meshEx, fieldDim, & + gridToFieldMap=(/2/), meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) ++ +
+ +
+The user must call ESMF_FieldBundleDestroy() before + deleting any of the Fields it contains. Because Fields + can be shared by multiple FieldBundles and States, they are + not deleted by this call. +
+
+!------------------------------------------------------------------------- + + call ESMF_FieldBundleDestroy(bundle1, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+The ESMF_FieldBundleRedist interface can be used to redistribute data from + source FieldBundle to destination FieldBundle. This interface is overloaded by type and kind; + In the version of ESMF_FieldBundleRedist without factor argument, a default value + of factor 1 is used. + +
+In this example, we first create two FieldBundles, a source FieldBundle and a destination + FieldBundle. Then we use ESMF_FieldBundleRedist to + redistribute data from source FieldBundle to destination FieldBundle. +
+
+ ! perform redist + call ESMF_FieldBundleRedistStore(srcFieldBundle, dstFieldBundle, & + routehandle, rc=rc) ++ +
+
+ call ESMF_FieldBundleRedist(srcFieldBundle, dstFieldBundle, & + routehandle, rc=rc) ++ +
+ +
+The ESMF_FieldBundleRedist interface can be used to redistribute data from + source FieldBundle to destination FieldBundle when both Bundles are packed with same + number of fields. + +
+In this example, we first create two packed FieldBundles, a source FieldBundle and a destination + FieldBundle. Then we use ESMF_FieldBundleRedist to + redistribute data from source FieldBundle to destination FieldBundle. + +
+The same Grid is used where the source and destination packed FieldBundle are built upon. Source + and destination Bundle have different memory layout. +
+
+ allocate(srcfptr(3,5,10), dstfptr(10,5,3)) + srcfptr = lpe + srcFieldBundle = ESMF_FieldBundleCreate((/'field01', 'field02', 'field03'/), & + srcfptr, grid, 1, gridToFieldMap=(/2,3/), rc=rc) ++ +
+
+ dstFieldBundle = ESMF_FieldBundleCreate((/'field01', 'field02', 'field03'/), & + dstfptr, grid, 3, gridToFieldMap=(/2,1/), rc=rc) ++ +
+
+ ! perform redist + call ESMF_FieldBundleRedistStore(srcFieldBundle, dstFieldBundle, & + routehandle, rc=rc) ++ +
+
+ call ESMF_FieldBundleRedist(srcFieldBundle, dstFieldBundle, & + routehandle, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+The ESMF_FieldBundleSMM interface can be used to perform SMM from + source FieldBundle to destination FieldBundle. This interface is overloaded by type and kind; + +
+In this example, we first create two FieldBundles, a source FieldBundle and a destination + FieldBundle. Then we use ESMF_FieldBundleSMM to + perform sparse matrix multiplication from source FieldBundle to destination FieldBundle. + +
+The operation performed in this example is better illustrated in + section 26.3.33. + +
+Section 28.2.18 provides a detailed discussion of the + sparse matrix multiplication operation implemented in ESMF. +
+
+ call ESMF_VMGetCurrent(vm, rc=rc) ++ +
+
+ call ESMF_VMGet(vm, localPet=lpe, rc=rc) ++ +
+
+ ! create distgrid and grid + distgrid = ESMF_DistGridCreate(minIndex=(/1/), maxIndex=(/16/), & + regDecomp=(/4/), & + rc=rc) ++ +
+
+ grid = ESMF_GridCreate(distgrid=distgrid, & + gridEdgeLWidth=(/0/), gridEdgeUWidth=(/0/), & + name="grid", rc=rc) ++ +
+
+ call ESMF_ArraySpecSet(arrayspec, 1, ESMF_TYPEKIND_I4, rc=rc) ++ +
+
+ ! create field bundles and fields + srcFieldBundle = ESMF_FieldBundleCreate(rc=rc) ++ +
+
+ dstFieldBundle = ESMF_FieldBundleCreate(rc=rc) ++ +
+
+ do i = 1, 3 + srcField(i) = ESMF_FieldCreate(grid, arrayspec, & + totalLWidth=(/1/), totalUWidth=(/2/), & + rc=rc) ++ +
+
+ call ESMF_FieldGet(srcField(i), localDe=0, farrayPtr=srcfptr, rc=rc) ++ +
+
+ srcfptr = 1 + + call ESMF_FieldBundleAdd(srcFieldBundle, (/srcField(i)/), rc=rc) ++ +
+
+ dstField(i) = ESMF_FieldCreate(grid, arrayspec, & + totalLWidth=(/1/), totalUWidth=(/2/), & + rc=rc) ++ +
+
+ call ESMF_FieldGet(dstField(i), localDe=0, farrayPtr=dstfptr, rc=rc) ++ +
+
+ dstfptr = 0 + + call ESMF_FieldBundleAdd(dstFieldBundle, (/dstField(i)/), rc=rc) ++ +
+
+ enddo + + ! initialize factorList and factorIndexList + allocate(factorList(4)) + allocate(factorIndexList(2,4)) + factorList = (/1,2,3,4/) + factorIndexList(1,:) = (/lpe*4+1,lpe*4+2,lpe*4+3,lpe*4+4/) + factorIndexList(2,:) = (/lpe*4+1,lpe*4+2,lpe*4+3,lpe*4+4/) + call ESMF_FieldBundleSMMStore(srcFieldBundle, dstFieldBundle, & + routehandle, factorList, factorIndexList, rc=rc) ++ +
+
+ ! perform smm + call ESMF_FieldBundleSMM(srcFieldBundle, dstFieldBundle, routehandle, & + rc=rc) ++ +
+
+ ! release SMM route handle + call ESMF_FieldBundleSMMRelease(routehandle, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+ + ESMF_FieldBundleHalo interface can be used to perform halo updates + for all the Fields contained in the ESMF_FieldBundle. + +
+In this example, we will set up a FieldBundle for a 2D inviscid and compressible + flow problem. We will illustrate the FieldBundle halo update operation but we will + not solve the non-linear PDEs. The emphasis here is to demonstrate + how to set up halo regions, how a numerical scheme updates + the exclusive regions, and how a halo update communicates data in the halo regions. Here + are the governing equations: + +
+ + (conservation of momentum in x-direction) + +
+ + (conservation of momentum in y-direction) + +
+ + (conservation of mass) + +
+ + (conservation of energy) + +
+The four unknowns are pressure , density , velocity (, ). The grids + are set up using Arakawa D stagger ( on corner, at center, and on edges). + , , , and are bounded by necessary boundary conditions and initial conditions. + +
+Section 28.2.15 provides a detailed discussion of the + halo operation implemented in ESMF. +
+
+ ! create distgrid and grid according to the following decomposition + ! and stagger pattern, r is density. + ! + ! p--------u-------+p+-------u--------p + ! ! | | + ! ! | | + ! ! | | + ! v r v r v + ! ! PET 0 | PET 1 | + ! ! | | + ! ! | | + ! p--------u-------+p+-------u--------p + ! ! | | + ! ! | | + ! ! | | + ! v r v r v + ! ! PET 2 | PET 3 | + ! ! | | + ! ! | | + ! p--------u-------+p+-------u--------p + ! + distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/256,256/), & + regDecomp=(/2,2/), & + rc=rc) ++ +
+
+ grid = ESMF_GridCreate(distgrid=distgrid, name="grid", rc=rc) ++ +
+
+ call ESMF_ArraySpecSet(arrayspec, 2, ESMF_TYPEKIND_R4, rc=rc) ++ +
+
+ ! create field bundles and fields + fieldBundle = ESMF_FieldBundleCreate(rc=rc) ++ +
+
+ ! set up exclusive/total region for the fields + ! + ! halo: L/U, nDim, nField, nPet + ! halo configuration for pressure, and similarly for density, u, and v + halo(1,1,1,1) = 0 + halo(2,1,1,1) = 0 + halo(1,2,1,1) = 0 + halo(2,2,1,1) = 0 + halo(1,1,1,2) = 1 ! halo in x direction on left hand side of pet 1 + halo(2,1,1,2) = 0 + halo(1,2,1,2) = 0 + halo(2,2,1,2) = 0 + halo(1,1,1,3) = 0 + halo(2,1,1,3) = 1 ! halo in y direction on upper side of pet 2 + halo(1,2,1,3) = 0 + halo(2,2,1,3) = 0 + halo(1,1,1,4) = 1 ! halo in x direction on left hand side of pet 3 + halo(2,1,1,4) = 1 ! halo in y direction on upper side of pet 3 + halo(1,2,1,4) = 0 + halo(2,2,1,4) = 0 ++ +
+
+ ! names and staggers of the 4 unknown fields + names(1) = "pressure" + names(2) = "density" + names(3) = "u" + names(4) = "v" + staggers(1) = ESMF_STAGGERLOC_CORNER + staggers(2) = ESMF_STAGGERLOC_CENTER + staggers(3) = ESMF_STAGGERLOC_EDGE2 + staggers(4) = ESMF_STAGGERLOC_EDGE1 + + ! create a FieldBundle + lpe = lpe + 1 + do i = 1, 4 + field(i) = ESMF_FieldCreate(grid, arrayspec, & + totalLWidth=(/halo(1,1,i,lpe), halo(1,2,i,lpe)/), & + totalUWidth=(/halo(2,1,i,lpe), halo(2,2,i,lpe)/), & + staggerloc=staggers(i), name=names(i), & + rc=rc) ++ +
+
+ call ESMF_FieldBundleAdd(fieldBundle, (/field(i)/), rc=rc) ++ +
+
+ enddo + + ! compute the routehandle + call ESMF_FieldBundleHaloStore(fieldBundle, routehandle=routehandle, & + rc=rc) ++ +
+
+ do iter = 1, 10 + do i = 1, 4 + call ESMF_FieldGet(field(i), farrayPtr=fptr, & + exclusiveLBound=excllb, exclusiveUBound=exclub, rc=rc) ++ +
+
+ sizes = exclub - excllb + ! fill the total region with 0. + fptr = 0. + ! only update the exclusive region on local PET + do j = excllb(1), exclub(1) + do k = excllb(2), exclub(2) + fptr(j,k) = iter * cos(2.*PI*j/sizes(1))*sin(2.*PI*k/sizes(2)) + enddo + enddo + enddo + ! call halo execution to update the data in the halo region, + ! it can be verified that the halo regions change from 0. + ! to non zero values. + call ESMF_FieldBundleHalo(fieldbundle, routehandle=routehandle, rc=rc) ++ +
+
+ enddo + ! release halo route handle + call ESMF_FieldBundleHaloRelease(routehandle, rc=rc) ++ +
+ + +
+ +
+
+
+
+CAUTION: For communication methods, the undistributed dimension representing +the number of fields must have identical size between source and destination packed +data. Communication methods do not permute the order of fields in the source +and destination packed FieldBundle. + +
+
+
+ +
+ +
+
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + fieldbundle1 = fieldbundle2 +ARGUMENTS: +
type(ESMF_FieldBundle) :: fieldbundle1 + type(ESMF_FieldBundle) :: fieldbundle2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign fieldbundle1 as an alias to the same ESMF fieldbundle object in memory + as fieldbundle2. If fieldbundle2 is invalid, then fieldbundle1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (fieldbundle1 == fieldbundle2) then ... endif + OR + result = (fieldbundle1 == fieldbundle2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: fieldbundle1 + type(ESMF_FieldBundle), intent(in) :: fieldbundle2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether fieldbundle1 and fieldbundle2 are valid aliases to the same ESMF + fieldbundle object in memory. For a more general comparison of two ESMF FieldBundles, + going beyond the simple alias test, the ESMF_FieldBundleMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (fieldbundle1 /= fieldbundle2) then ... endif + OR + result = (fieldbundle1 /= fieldbundle2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: fieldbundle1 + type(ESMF_FieldBundle), intent(in) :: fieldbundle2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether fieldbundle1 and fieldbundle2 are not valid aliases to the + same ESMF fieldbundle object in memory. For a more general comparison of two ESMF + FieldBundles, going beyond the simple alias test, the ESMF_FieldBundleMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleAdd() + subroutine ESMF_FieldBundleAddList(fieldbundle, fieldList, & + multiflag, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + type(ESMF_Field), intent(in) :: fieldList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: multiflag + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Add Field(s) to a FieldBundle. It is an error if fieldList contains + Fields that match by name Fields already contained in + fieldbundle when multiflag + is set to .false. and relaxedflag is set to .false.. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleAddReplace(fieldbundle, fieldList, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + type(ESMF_Field), intent(in) :: fieldList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Fields in fieldList that do not match any Fields by name in + fieldbundle are added to the FieldBundle. Fields in fieldList + that match any Fields by name in fieldbundle replace those Fields. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleCreate() + function ESMF_FieldBundleCreateDefault(fieldList, & + multiflag, relaxedflag, name, rc) +RETURN VALUE: +
type(ESMF_FieldBundle) :: ESMF_FieldBundleCreateDefault +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Field), intent(in), optional :: fieldList(:) + logical, intent(in), optional :: multiflag + logical, intent(in), optional :: relaxedflag + character (len=*),intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_FieldBundle object from a list of existing Fields. + +
+The creation of a FieldBundle leaves the bundled Fields unchanged, they + remain valid individual objects. a FieldBundle is a light weight container + of Field references. The actual data remains in place, there are no + data movements or duplications associated with the creation of an + FieldBundle. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleCreate() + function ESMF_FieldBundleCreateGrid<rank><type><kind>(fieldNameList, & + farrayPtr, grid, fieldDim, & + indexflag, staggerLoc, & + gridToFieldMap, & + totalLWidth, totalUWidth, name, rc) +RETURN VALUE: +
type(ESMF_FieldBundle) :: ESMF_FieldBundleCreateGridDataPtr<rank><type><kind> +ARGUMENTS: +
character(len=*), intent(in) :: fieldNameList(:) + <type> (ESMF_KIND_<kind>), dimension(<rank>), pointer :: farrayPtr + type(ESMF_Grid), intent(in) :: grid + integer, intent(in) :: fieldDim + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_StaggerLoc), intent(in), optional :: staggerloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a packed FieldBundle from user supplied list of field names, pre-allocated + Fortran array pointer, and ESMF_Grid object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleCreate() + function ESMF_FieldBundleCreateMesh<rank><type><kind>(fieldNameList, & + farrayPtr, Mesh, fieldDim, & + meshLoc, gridToFieldMap, name, rc) +RETURN VALUE: +
type(ESMF_FieldBundle) :: ESMF_FieldBundleCreateMeshDataPtr<rank><type><kind> +ARGUMENTS: +
character(len=*), intent(in) :: fieldNameList(:) + <type> (ESMF_KIND_<kind>), dimension(<rank>), pointer :: farrayPtr + type(ESMF_Mesh), intent(in) :: mesh + integer, intent(in) :: fieldDim + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_MeshLoc), intent(in), optional:: meshloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a packed FieldBundle from user supplied list of field names, pre-allocated + Fortran array pointer, and ESMF_Mesh object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleDestroy(fieldbundle, noGarbage, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroy an ESMF_FieldBundle object. The member Fields are not + touched by this operation and remain valid objects that need to be + destroyed individually if necessary. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleGet() + subroutine ESMF_FieldBundleGetListAll(fieldbundle, & + itemorderflag, geomtype, grid, locstream, mesh, xgrid, & + fieldCount, fieldList, fieldNameList, isPacked, name, vm, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: fieldbundle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_ItemOrder_Flag), intent(in), optional :: itemorderflag + type(ESMF_GeomType_Flag), intent(out), optional :: geomtype + type(ESMF_Grid), intent(out), optional :: grid + type(ESMF_LocStream), intent(out), optional :: locstream + type(ESMF_Mesh), intent(out), optional :: mesh + type(ESMF_XGrid), intent(out), optional :: xgrid + integer, intent(out), optional :: fieldCount + type(ESMF_Field), intent(out), optional :: fieldList(:) + character(len=*), intent(out), optional :: fieldNameList(:) + logical, intent(out), optional :: isPacked + character(len=*), intent(out), optional :: name + type(ESMF_VM), intent(out), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get the list of all Fields and field names bundled in a FieldBundle. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleGet() + subroutine ESMF_FieldBundleGetItem(fieldbundle, fieldName, & + field, fieldCount, isPresent, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: fieldbundle + character(len=*), intent(in) :: fieldName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Field), intent(out), optional :: field + integer, intent(out), optional :: fieldCount + logical, intent(out), optional :: isPresent + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get information about items that match fieldName in FieldBundle. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleGet() + subroutine ESMF_FieldBundleGetList(fieldbundle, fieldName, fieldList, & + itemorderflag, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: fieldbundle + character(len=*), intent(in) :: fieldName + type(ESMF_Field), intent(out) :: fieldList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_ItemOrder_Flag), intent(in), optional :: itemorderflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get the list of Fields from fieldbundle that match fieldName. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleGet() + function ESMF_FieldBundleGetDataPtr<rank><type><kind>(fieldBundle, & + localDe, farrayPtr, & + rc) +RETURN VALUE: +
type(ESMF_FieldBundle) :: ESMF_FieldBundleGetDataPtr<rank><type><kind> +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: fieldBundle + integer, intent(in), optional :: localDe + <type> (ESMF_KIND_<kind>), dimension(<rank>), pointer :: farrayPtr + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get a Fortran pointer to DE-local memory allocation within packed FieldBundle. + It's erroneous to perform this call on a FieldBundle that's not packed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleHalo(fieldbundle, routehandle, & + checkflag, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed halo operation for the Fields in fieldbundle. + The FieldBundle must match the respective FieldBundle used during + ESMF_FieldBundleHaloStore() in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+See ESMF_FieldBundleHaloStore() on how to precompute + routehandle. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleHaloRelease(routehandle, & + noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with a FieldBundle halo operation. After this call + routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleHaloStore(fieldbundle, routehandle, & + rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store a FieldBundle halo operation over the data in fieldbundle. + By definition, all elements in the total Field regions that lie + outside the exclusive regions will be considered potential destination + elements for the halo operation. However, only those elements that have a corresponding + halo source element, i.e. an exclusive element on one of the DEs, will be + updated under the halo operation. Elements that have no associated source + remain unchanged under halo. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldBundleHalo() on any pair of FieldBundles that matches + srcFieldBundle and dstFieldBundle in type, kind, + and memory layout of the gridded dimensions. However, the size, + number, and index order of ungridded dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_FieldBundleIsCreated(fieldbundle, rc) +RETURN VALUE: +
logical :: ESMF_FieldBundleIsCreated +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: fieldbundle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the fieldbundle has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundlePrint(fieldbundle, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: fieldbundle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Print internal information of the specified fieldbundle object. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleRead(fieldbundle, fileName, & + singleFile, timeslice, iofmt, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + character(*), intent(in) :: fileName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: singleFile + integer, intent(in), optional :: timeslice + type(ESMF_IOFmt_Flag), intent(in), optional :: iofmt + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Read field data to a FieldBundle object from file(s). + For this API to be functional, the environment variable ESMF_PIO + should be set to either "internal" or "external" when the ESMF library is built. + Please see the section on Data I/O, 38.2. + +
+Limitations: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleRedist(srcFieldBundle, dstFieldBundle, & + routehandle, checkflag, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in), optional :: srcFieldBundle + type(ESMF_FieldBundle), intent(inout), optional :: dstFieldBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed redistribution from srcFieldBundle + to dstFieldBundle. + Both srcFieldBundle and dstFieldBundle must match the + respective FieldBundles used during ESMF_FieldBundleRedistStore() + in type, kind, and memory layout of the gridded + dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+The srcFieldBundle and dstFieldBundle arguments are optional in support of + the situation where srcFieldBundle and/or dstFieldBundle are not defined on + all PETs. The srcFieldBundle and dstFieldBundle must be specified on those + PETs that hold source or destination DEs, respectively, but may be omitted + on all other PETs. PETs that hold neither source nor destination DEs may + omit both arguments. + +
+It is erroneous to specify the identical FieldBundle object for srcFieldBundle and + dstFieldBundle arguments. + +
+See ESMF_FieldBundleRedistStore() on how to precompute + routehandle. + +
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 25.2.9. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleRedistRelease(routehandle, & + noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with a FieldBundle redistribution. After this call + routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleRedistStore() + subroutine ESMF_FieldBundleRedistStore<type><kind>(srcFieldBundle, & + dstFieldBundle, routehandle, factor, & + ignoreUnmatchedIndicesFlag, srcToDstTransposeMap, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: srcFieldBundle + type(ESMF_FieldBundle), intent(inout) :: dstFieldBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + <type>(ESMF_KIND_<kind>), intent(in) :: factor + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndicesFlag(:) + integer, intent(in), optional :: srcToDstTransposeMap(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store a FieldBundle redistribution operation from srcFieldBundle to dstFieldBundle. + PETs that + specify a factor argument must use the <type><kind> overloaded interface. Other + PETs call into the interface without factor argument. If multiple PETs specify + the factor argument its type and kind as well as its value must match across + all PETs. If none of the PETs specifies a factor argument the default will be a + factor of 1. + +
+Both srcFieldBundle and dstFieldBundle are interpreted as sequentialized + vectors. The + sequence is defined by the order of DistGrid dimensions and the order of + tiles within the DistGrid or by user-supplied arbitrary sequence indices. See + section 28.2.18 for details on the definition of sequence indices. + Redistribution corresponds to an identity mapping of the source FieldBundle vector to + the destination FieldBundle vector. + +
+Source and destination FieldBundles may be of different <type><kind>. Further source + and destination FieldBundles may differ in shape, however, the number of elements + must match. + +
+It is erroneous to specify the identical FieldBundle object for srcFieldBundle + and dstFieldBundle arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldBundleRedist() on any pair of FieldBundles that matches + srcFieldBundle and dstFieldBundle in type, kind, + and memory layout of the gridded dimensions. However, the size, + number, and index order of ungridded dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 25.2.9. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleRedistStore() + subroutine ESMF_FieldBundleRedistStoreNF(srcFieldBundle, dstFieldBundle, & + routehandle, ignoreUnmatchedIndicesFlag, & + srcToDstTransposeMap, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: srcFieldBundle + type(ESMF_FieldBundle), intent(inout) :: dstFieldBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndicesFlag(:) + integer, intent(in), optional :: srcToDstTransposeMap(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store a FieldBundle redistribution operation from srcFieldBundle + to dstFieldBundle. PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+Both srcFieldBundle and dstFieldBundle are interpreted as sequentialized + vectors. The + sequence is defined by the order of DistGrid dimensions and the order of + tiles within the DistGrid or by user-supplied arbitrary sequence indices. See + section 28.2.18 for details on the definition of sequence indices. + Redistribution corresponds to an identity mapping of the source FieldBundle vector to + the destination FieldBundle vector. + +
+Source and destination Fields may be of different <type><kind>. Further source + and destination Fields may differ in shape, however, the number of elements + must match. + +
+It is erroneous to specify the identical FieldBundle object for srcFieldBundle and dstFieldBundle + arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldBundleRedist() on any pair of FieldBundles that matches + srcFieldBundle and dstFieldBundle in type, kind, + and memory layout of the gridded dimensions. However, the size, + number, and index order of ungridded dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 25.2.9. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleRegrid(srcFieldBundle, dstFieldBundle, & + routehandle, zeroregion, termorderflag, checkflag, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in), optional :: srcFieldBundle + type(ESMF_FieldBundle), intent(inout), optional :: dstFieldBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Region_Flag), intent(in), optional :: zeroregion + type(ESMF_TermOrder_Flag), intent(in), optional :: termorderflag(:) + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed regrid from srcFieldBundle + to dstFieldBundle. + Both srcFieldBundle and dstFieldBundle must match the + respective FieldBundles used during ESMF_FieldBundleRedistStore() + in type, kind, and memory layout of the gridded + dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+The srcFieldBundle and dstFieldBundle arguments are optional in support of + the situation where srcFieldBundle and/or dstFieldBundle are not defined on + all PETs. The srcFieldBundle and dstFieldBundle must be specified on those + PETs that hold source or destination DEs, respectively, but may be omitted + on all other PETs. PETs that hold neither source nor destination DEs may + omit both arguments. + +
+It is erroneous to specify the identical FieldBundle object for srcFieldBundle and + dstFieldBundle arguments. + +
+See ESMF_FieldBundleRegridStore() on how to precompute + routehandle. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleRegridRelease(routehandle, & + noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with a FieldBundle regrid operation. After this call + routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleRegridStore(srcFieldBundle, dstFieldBundle, & + srcMaskValues, dstMaskValues, regridmethod, polemethod, regridPoleNPnts, & + lineType, normType, extrapMethod, extrapNumSrcPnts, extrapDistExponent, & + extrapNumLevels, unmappedaction, ignoreDegenerate, srcTermProcessing, & + pipelineDepth, routehandle, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: srcFieldBundle + type(ESMF_FieldBundle), intent(inout) :: dstFieldBundle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), target, intent(in), optional :: srcMaskValues(:) + integer(ESMF_KIND_I4), target, intent(in), optional :: dstMaskValues(:) + type(ESMF_RegridMethod_Flag), intent(in), optional :: regridmethod + type(ESMF_PoleMethod_Flag), intent(in), optional :: polemethod + integer, intent(in), optional :: regridPoleNPnts + type(ESMF_LineType_Flag), intent(in), optional :: lineType + type(ESMF_NormType_Flag), intent(in), optional :: normType + type(ESMF_ExtrapMethod_Flag), intent(in), optional :: extrapMethod + integer, intent(in), optional :: extrapNumSrcPnts + real, intent(in), optional :: extrapDistExponent + integer, intent(in), optional :: extrapNumLevels + type(ESMF_UnmappedAction_Flag),intent(in), optional :: unmappedaction + logical, intent(in), optional :: ignoreDegenerate + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipelineDepth + type(ESMF_RouteHandle), intent(inout), optional :: routehandle + integer, intent(out), optional :: rc ++STATUS: + +
+Added arguments extrapMethod, extrapNumSrcPnts, and + extrapDistExponent. These three new extrapolation arguments allow the + user to extrapolate destination points not mapped by the regrid method. + extrapMethod allows the user to choose the extrapolation method. + extrapNumSrcPnts and extrapDistExponent are parameters that + allow the user to tune the behavior of the + ESMF_EXTRAPMETHOD_NEAREST_IDAVG method. + +
+DESCRIPTION:
+
+
+
+Store a FieldBundle regrid operation over the data in srcFieldBundle + and dstFieldBundle pair. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldBundleRegrid() on any pair of FieldBundles that matches + srcFieldBundle and dstFieldBundle in type, kind, + and memory layout of the gridded dimensions. However, the size, + number, and index order of ungridded dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This call is collective across the current VM. + +
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_FieldRegridStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_FieldRegridStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleRemove(fieldbundle, fieldNameList, & + multiflag, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + character(len=*), intent(in) :: fieldNameList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: multiflag + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Remove field(s) by name from FieldBundle. In the relaxed setting it is + not an error if fieldNameList contains names that are not + found in fieldbundle. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleReplace(fieldbundle, fieldList, & + multiflag, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + type(ESMF_Field), intent(in) :: fieldList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: multiflag + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Replace field(s) by name in FieldBundle. In the relaxed setting it is not + an error if fieldList contains Fields that do not match by name any + item in fieldbundle. These Fields are simply ignored in this case. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleSet() + subroutine ESMF_FieldBundleSetGrid(fieldbundle, grid, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + type(ESMF_Grid), intent(in) :: grid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets the grid for a fieldbundle. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleSet() + subroutine ESMF_FieldBundleSetMesh(fieldbundle, mesh, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + type(ESMF_Mesh), intent(in) :: mesh + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets the mesh for a fieldbundle. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleSet() + subroutine ESMF_FieldBundleSetLS(fieldbundle, locstream, & + rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + type(ESMF_LocStream), intent(in) :: locstream + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets the locstream for a fieldbundle. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleSet() + subroutine ESMF_FieldBundleSetXGrid(fieldbundle, xgrid, & + rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(inout) :: fieldbundle + type(ESMF_XGrid), intent(in) :: xgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets the xgrid for a fieldbundle + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleSMM(srcFieldBundle, dstFieldBundle, & + routehandle, & + zeroregion, & ! DEPRECATED ARGUMENT + zeroregionflag, termorderflag, checkflag, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in), optional :: srcFieldBundle + type(ESMF_FieldBundle), intent(inout), optional :: dstFieldBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Region_Flag), intent(in), optional :: zeroregion ! DEPRECATED ARGUMENT + type(ESMF_Region_Flag), intent(in), target, optional :: zeroregionflag(:) + type(ESMF_TermOrder_Flag), intent(in), optional :: termorderflag(:) + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed sparse matrix multiplication from srcFieldBundle + to dstFieldBundle. + Both srcFieldBundle and dstFieldBundle must match the + respective FieldBundles used during ESMF_FieldBundleRedistStore() + in type, kind, and memory layout of the gridded + dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+The srcFieldBundle and dstFieldBundle arguments are optional in support of + the situation where srcFieldBundle and/or dstFieldBundle are not defined on + all PETs. The srcFieldBundle and dstFieldBundle must be specified on those + PETs that hold source or destination DEs, respectively, but may be omitted + on all other PETs. PETs that hold neither source nor destination DEs may + omit both arguments. + +
+It is erroneous to specify the identical FieldBundle object for srcFieldBundle and + dstFieldBundle arguments. + +
+See ESMF_FieldBundleSMMStore() on how to precompute + routehandle. + +
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 25.2.11. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleSMMRelease(routehandle, & + noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with a FieldBundle sparse matrix multiplication. After this call + routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleSMMStore() + subroutine ESMF_FieldBundleSMMStore<type><kind>(srcFieldBundle, & + dstFieldBundle, routehandle, factorList, factorIndexList, & + ignoreUnmatchedIndicesFlag, srcTermProcessing, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: srcFieldBundle + type(ESMF_FieldBundle), intent(inout) :: dstFieldBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + <type>(ESMF_KIND_<kind>), intent(in) :: factorList(:) + integer, intent(in), :: factorIndexList(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndicesFlag(:) + integer, intent(inout), optional :: srcTermProcessing(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store a FieldBundle sparse matrix multiplication operation from srcFieldBundle + to dstFieldBundle. PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with + size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+Both srcFieldBundle and dstFieldBundle are interpreted as sequentialized + vectors. The + sequence is defined by the order of DistGrid dimensions and the order of + tiles within the DistGrid or by user-supplied arbitrary sequence indices. See + section 28.2.18 for details on the definition of sequence indices. + SMM corresponds to an identity mapping of the source FieldBundle vector to + the destination FieldBundle vector. + +
+Source and destination Fields may be of different <type><kind>. Further source + and destination Fields may differ in shape, however, the number of elements + must match. + +
+It is erroneous to specify the identical FieldBundle object for srcFieldBundle + and dstFieldBundle arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldBundleSMM() on any pair of FieldBundles that matches + srcFieldBundle and dstFieldBundle in type, kind, + and memory layout of the gridded dimensions. However, the size, + number, and index order of ungridded dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 25.2.11. + +
+The arguments are: +
+The second dimension of factorIndexList steps through the list of + pairs, i.e. size(factorIndexList,2) == size(factorList). The first + dimension of factorIndexList is either of size 2 or size 4. + +
+In the size 2 format factorIndexList(1,:) specifies the + sequence index of the source element in the srcFieldBundle while + factorIndexList(2,:) specifies the sequence index of the + destination element in dstFieldBundle. For this format to be a valid + option source and destination FieldBundles must have matching number of + tensor elements (the product of the sizes of all Field tensor dimensions). + Under this condition an identity matrix can be applied within the space of + tensor elements for each sparse matrix factor. + +
+The size 4 format is more general and does not require a matching + tensor element count. Here the + +
+factorIndexList(1,:) specifies the + sequence index while factorIndexList(2,:) specifies the tensor + sequence index of the source element in the srcFieldBundle. Further + factorIndexList(3,:) specifies the sequence index and + factorIndexList(4,:) specifies the tensor sequence index of the + destination element in the dstFieldBundle. + +
+See section 28.2.18 for details on the definition of + sequence indices and tensor sequence indices. + +
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleSMMStore() + subroutine ESMF_FieldBundleSMMStoreNF(srcFieldBundle, dstFieldBundle, & + routehandle, ignoreUnmatchedIndicesFlag, & + srcTermProcessing, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: srcFieldBundle + type(ESMF_FieldBundle), intent(inout) :: dstFieldBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndicesFlag(:) + integer, intent(inout), optional :: srcTermProcessing(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store a FieldBundle sparse matrix multiplication operation from srcFieldBundle + to dstFieldBundle. PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+Both srcFieldBundle and dstFieldBundle are interpreted as sequentialized + vectors. The + sequence is defined by the order of DistGrid dimensions and the order of + tiles within the DistGrid or by user-supplied arbitrary sequence indices. See + section 28.2.18 for details on the definition of sequence indices. + SMM corresponds to an identity mapping of the source FieldBundle vector to + the destination FieldBundle vector. + +
+Source and destination Fields may be of different <type><kind>. Further source + and destination Fields may differ in shape, however, the number of elements + must match. + +
+It is erroneous to specify the identical FieldBundle object for srcFieldBundle and dstFieldBundle + arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldBundleSMM() on any pair of FieldBundles that matches + srcFieldBundle and dstFieldBundle in type, kind, + and memory layout of the gridded dimensions. However, the size, + number, and index order of ungridded dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This method is overloaded for + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8. + +
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 25.2.11. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldBundleSMMStore() + subroutine ESMF_FieldBundleSMMStoreFromFile(srcFieldBundle, dstFieldBundle, & + filename, routehandle, ignoreUnmatchedIndicesFlag, & + srcTermProcessing, rc) + ! ARGUMENTS: + type(ESMF_FieldBundle), intent(in) :: srcFieldBundle + type(ESMF_FieldBundle), intent(inout) :: dstFieldBundle + character(len=*), intent(in) :: filename + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndicesFlag(:) + integer, intent(inout), optional :: srcTermProcessing(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Compute an ESMF_RouteHandle using factors read from file. + +
+The arguments are: + +
+
+
+
+
+
+
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleValidate(fieldbundle, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: fieldbundle + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Validates that the fieldbundle is internally consistent. + The method returns an error code if problems are found. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldBundleWrite(fieldbundle, fileName, & + convention, purpose, singleFile, overwrite, status, timeslice, iofmt, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: fieldbundle + character(*), intent(in) :: fileName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(*), intent(in), optional :: convention + character(*), intent(in), optional :: purpose + logical, intent(in), optional :: singleFile + logical , intent(in), optional :: overwrite + type(ESMF_FileStatus_Flag), intent(in), optional :: status + integer, intent(in), optional :: timeslice + type(ESMF_IOFmt_Flag), intent(in), optional :: iofmt + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write the Fields into a file. For this API to be functional, + the environment variable ESMF_PIO should be set to either "internal" or "external" + when the ESMF library is built. Please see the section on + Data I/O, 38.2. + +
+When convention and purpose arguments are specified, NetCDF dimension + labels and variable attributes are written from each Field in the FieldBundle + from the corresponding Attribute package. Additionally, Attributes may be + set on the FieldBundle level under the same Attribute package. This allows + the specification of global attributes within the file. + As with individual Fields, the value associated with each name may be either + a scalar character string, or a scalar or array of type integer, real, or + double precision. + +
+Limitations: + +
+The arguments are: +
+ + +
+An ESMF Field represents a physical field, such as temperature. +The motivation for including Fields in ESMF is that bundles of +Fields are the entities that are normally exchanged when coupling +Components. + +
+The ESMF Field class contains distributed and discretized field data, a reference +to its associated grid, and metadata. The Field class stores the grid staggering +for that physical field. +This is the relationship of how the data array of a field maps onto a grid +(e.g. one item per +cell located at the cell center, one item per cell located at the NW +corner, one item per cell vertex, etc.). This means that different Fields +which are on the same underlying ESMF Grid but have different +staggerings can share the same Grid object without needing to replicate +it multiple times. + +
+Fields can be added to States for use in inter-Component +data communications. Fields can also be added to FieldBundles, +which are groups of Fields on the same underlying Grid. +One motivation for packing Fields into FieldBundles is convenience; +another is the ability to perform optimized collective data transfers. + +
+Field communication capabilities include: data redistribution, regridding, scatter, +gather, sparse-matrix multiplication, and halo update. These are discussed +in more detail in the documentation for the specific method calls. +ESMF does not currently support vector fields, so the components of +a vector field must be stored as separate Field objects. + +
+ +
+The Field class allows the user to easily perform a number of operations on +the data stored in a Field. This section gives a brief summary of the different types of operations +and the range of their capabilities. The operations covered here are: redistribution (ESMF_FieldRedistStore()), sparse matrix multiply (ESMF_FieldSMMStore()), and regridding (ESMF_FieldRegridStore()). + +
+The redistribution operation (ESMF_FieldRedistStore()) allows the user to move data between two Fields with the same size, but different +distribution. This operation is useful, for example, to move data between two components with different distributions. +Please see Section 26.3.30 for an example of the redistribution capability. + +
+The sparse matrix multiplication operation (ESMF_FieldSMMStore()) allows the user to multiply the data in a Field by a sparse matrix. This operation is useful, for example, if the user has an interpolation matrix and wants to apply it to the data in a Field. Please see Section 26.3.33 +for an example of the sparse matrix multiply capability. + +
+The regridding operation (ESMF_FieldRegridStore()) allows the user to move data from one grid to another while maintaining certain properties +of the data. Regridding is also called interpolation or remapping. In the Field regridding operation the grids the data is being moved between +are the grids associated with the Fields storing the data. The regridding operation works on Fields built on Meshes, Grids, or Location Streams. +There are six regridding methods available: bilinear, higher-order patch, two types of nearest neighbor, first-order conservative, and second-order conservative. +Please see section 24.2 for a more indepth description of regridding including in which situations each method is supported. +Please see section 26.3.25 for a description of the regridding capability as it applies to Fields. Several sections following section 26.3.25 +contain examples of using regridding. + +
+ +
+ +
+DESCRIPTION:
+
+
+An ESMF_Field can be in different status after initialization. Field status can be queried using ESMF_FieldGet() method.
+
+
+The type of this flag is: + +
+type(ESMF_FieldStatus_Flag) + +
+The valid values are: +
+A Field serves as an annotator of data, since it carries +a description of the grid it is associated with and metadata +such as name and units. Fields can be used in this capacity +alone, as convenient, descriptive containers into which arrays +can be placed and retrieved. However, for most codes the primary +use of Fields is in the context of import and export States, +which are the objects that carry coupling information between +Components. Fields enable data to be self-describing, and a +State holding ESMF Fields contains data in a standard format +that can be queried and manipulated. + +
+The sections below go into more detail about Field usage. + +
+ +
+Fields can be created and destroyed at any time during +application execution. However, these Field methods require +some time to complete. We do not recommend that the user +create or destroy Fields inside performance-critical +computational loops. + +
+All versions of the ESMF_FieldCreate() +routines require a Grid object as input, or require a Grid +be added before most operations involving Fields can be performed. +The Grid contains the information needed to know which +Decomposition Elements (DEs) are participating in +the processing of this Field, and which subsets of the data +are local to a particular DE. + +
+The details of how the create process happens depend +on which of the variants of the ESMF_FieldCreate() +call is used. Some of the variants are discussed below. + +
+There are versions of the ESMF_FieldCreate() interface +which create the Field based on the input Grid. The ESMF +can allocate the proper amount of +space but not assign initial values. The user code +can then get the pointer to the uninitialized buffer and +set the initial data values. + +
+Other versions of the ESMF_FieldCreate() interface +allow user code to attach arrays that have already been +allocated by the user. Empty Fields can also be created in +which case the data can be added at some later time. + +
+For versions of Create which do not specify data values, +user code can create an ArraySpec object, which +contains information about the typekind and rank of the +data values in the array. Then at Field create time, the +appropriate amount of memory is allocated to contain the +data which is local to each DE. + +
+When finished with a ESMF_Field, the ESMF_FieldDestroy method +removes it. However, the objects inside the ESMF_Field +created externally should be destroyed separately, +since objects can be added to +more than one ESMF_Field. For example, the same ESMF_Grid +can be referenced by multiple ESMF_Fields. In this case the +internal Grid is not deleted by the ESMF_FieldDestroy call. + +
+ +
+ +
+ +
+A user can get bounds and counts information from an ESMF_Field + through the ESMF_FieldGet() interface. Also available through this interface + is the intrinsic + Fortran data pointer contained in the internal ESMF_Array object + of an ESMF_Field. The bounds and counts information are DE specific + for the associated Fortran data pointer. + +
+For a better discussion of the terminologies, bounds and widths in ESMF + e.g. exclusive, computational, total bounds + for the lower and upper corner of data region, etc.., user can refer to + the explanation of these concepts for Grid and Array in their respective sections + in the Reference Manual, e.g. Section 28.2.6 on Array + and Section 31.3.19 on Grid. + +
+In this example, we first create a 3D Field based on a 3D Grid and Array. + Then we use the ESMF_FieldGet() interface to retrieve the data pointer, + potentially updating or verifying its values. We also retrieve the bounds and counts + information of the 3D Field to assist in data element iteration. + +
+
+ xdim = 180 + ydim = 90 + zdim = 50 + + ! create a 3D data Field from a Grid and Array. + ! first create a Grid + grid3d = ESMF_GridCreateNoPeriDim(minIndex=(/1,1,1/), & + maxIndex=(/xdim,ydim,zdim/), & + regDecomp=(/2,2,1/), name="grid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_GridGet(grid=grid3d, staggerloc=ESMF_STAGGERLOC_CENTER, & + distgrid=distgrid3d, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_GridGetFieldBounds(grid=grid3d, localDe=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, totalCount=fa_shape, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + allocate(farray(fa_shape(1), fa_shape(2), fa_shape(3)) ) + + ! create an Array + array3d = ESMF_ArrayCreate(distgrid3d, farray, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create a Field + field = ESMF_FieldCreate(grid=grid3d, array=array3d, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! retrieve the Fortran data pointer from the Field + call ESMF_FieldGet(field=field, localDe=0, farrayPtr=farray1, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! retrieve the Fortran data pointer from the Field and bounds + call ESMF_FieldGet(field=field, localDe=0, farrayPtr=farray1, & + computationalLBound=compLBnd, computationalUBound=compUBnd, & + exclusiveLBound=exclLBnd, exclusiveUBound=exclUBnd, & + totalLBound=totalLBnd, totalUBound=totalUBnd, & + computationalCount=comp_count, & + exclusiveCount=excl_count, & + totalCount=total_count, & + rc=rc) + + + ! iterate through the total bounds of the field data pointer + do k = totalLBnd(3), totalUBnd(3) + do j = totalLBnd(2), totalUBnd(2) + do i = totalLBnd(1), totalUBnd(1) + farray1(i, j, k) = sin(2*i/total_count(1)*PI) + & + sin(4*j/total_count(2)*PI) + & + sin(8*k/total_count(2)*PI) + enddo + enddo + enddo ++ +
+ +
+A user can get the internal ESMF_Grid and ESMF_Array + from a ESMF_Field. Note that the user should not issue any destroy command + on the retrieved grid or array object since they are referenced + from within the ESMF_Field. The retrieved objects should be used + in a read-only fashion to query additional information not directly + available through the ESMF_FieldGet() interface. + +
+
+ call ESMF_FieldGet(field, grid=grid, array=array, & + typekind=typekind, dimCount=dimCount, staggerloc=staggerloc, & + gridToFieldMap=gridToFieldMap, & + ungriddedLBound=ungriddedLBound, ungriddedUBound=ungriddedUBound, & + totalLWidth=totalLWidth, totalUWidth=totalUWidth, & + name=name, & + rc=rc) ++ +
+ +
+A user can create an ESMF_Field from an ESMF_Grid and + typekind/rank. + This create method associates the two objects. + +
+We first create a Grid with a regular distribution that is + 10x20 index in 2x2 DEs. This version of Field create simply + associates the data with the Grid. The data is referenced + explicitly on a regular 2x2 uniform grid. + Finally we create a Field from + the Grid, typekind, rank, and a user specified StaggerLoc. + +
+This example also illustrates a typical use of this Field creation + method. By creating a Field from a Grid and typekind/rank, the + user allows the ESMF library to create a internal Array in the Field. + Then the user can use ESMF_FieldGet() to retrieve the Fortran + data array + and necessary bounds information to assign initial values to it. +
+
+ ! create a grid + grid = ESMF_GridCreateNoPeriDim(minIndex=(/1,1/), maxIndex=(/10,20/), & + regDecomp=(/2,2/), name="atmgrid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create a Field from the Grid and arrayspec + field1 = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_R4, & + indexflag=ESMF_INDEX_DELOCAL, & + staggerloc=ESMF_STAGGERLOC_CENTER, name="pressure", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_FieldGet(field1, localDe=0, farrayPtr=farray2dd, & + totalLBound=ftlb, totalUBound=ftub, totalCount=ftc, rc=rc) + + do i = ftlb(1), ftub(1) + do j = ftlb(2), ftub(2) + farray2dd(i, j) = sin(i/ftc(1)*PI) * cos(j/ftc(2)*PI) + enddo + enddo + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+A user can create an ESMF_Field from an ESMF_Grid and a + ESMF_Arrayspec with corresponding rank and type. + This create method associates the two objects. + +
+We first create a Grid with a regular distribution that is + 10x20 index in 2x2 DEs. This version of Field create simply + associates the data with the Grid. The data is referenced + explicitly on a regular 2x2 uniform grid. + Then we create an ArraySpec. Finally we create a Field from + the Grid, ArraySpec, and a user specified StaggerLoc. + +
+This example also illustrates a typical use of this Field creation + method. By creating a Field from a Grid and an ArraySpec, the + user allows the ESMF library to create a internal Array in the Field. + Then the user can use ESMF_FieldGet() to retrieve the Fortran + data array + and necessary bounds information to assign initial values to it. +
+
+ ! create a grid + grid = ESMF_GridCreateNoPeriDim(minIndex=(/1,1/), maxIndex=(/10,20/), & + regDecomp=(/2,2/), name="atmgrid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! setup arrayspec + call ESMF_ArraySpecSet(arrayspec, 2, ESMF_TYPEKIND_R4, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create a Field from the Grid and arrayspec + field1 = ESMF_FieldCreate(grid, arrayspec, & + indexflag=ESMF_INDEX_DELOCAL, & + staggerloc=ESMF_STAGGERLOC_CENTER, name="pressure", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_FieldGet(field1, localDe=0, farrayPtr=farray2dd, & + totalLBound=ftlb, totalUBound=ftub, totalCount=ftc, rc=rc) + + do i = ftlb(1), ftub(1) + do j = ftlb(2), ftub(2) + farray2dd(i, j) = sin(i/ftc(1)*PI) * cos(j/ftc(2)*PI) + enddo + enddo + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+A user can also create an ArraySpec that has a different rank + from the Grid, For example, the following code shows creation of + of 3D Field from a 2D Grid using a 3D ArraySpec. + +
+This example also demonstrates the technique to create a typical + 3D data Field that has 2 gridded dimensions and 1 ungridded + dimension. + +
+First we create a 2D grid with an index space of 180x360 equivalent to + 180x360 Grid cells (note that for a distributed memory computer, this + means each + grid cell will be on a separate PE!). In the FieldCreate call, we use gridToFieldMap + to indicate the mapping between Grid dimension and Field dimension. + For the ungridded dimension (typically the altitude), we use + ungriddedLBound and ungriddedUBound to describe its bounds. Internally + the ungridded dimension has a stride of 1, so the number of elements + of the ungridded dimension is ungriddedUBound - ungriddedLBound + 1. + +
+Note that gridToFieldMap in this specific example is (/1,2/) which + is the default value + so the user can neglect this argument for the FieldCreate call. +
+
+ grid2d = ESMF_GridCreateNoPeriDim(minIndex=(/1,1/), & + maxIndex=(/180,360/), regDecomp=(/2,2/), name="atmgrid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_ArraySpecSet(arrayspec, 3, ESMF_TYPEKIND_R4, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + field1 = ESMF_FieldCreate(grid2d, arrayspec, & + indexflag=ESMF_INDEX_DELOCAL, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + gridToFieldMap=(/1,2/), & + ungriddedLBound=(/1/), ungriddedUBound=(/50/), & + name="pressure", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+A user can create an ESMF_Field from an ESMF_Grid and a + ESMF_Array. The Grid was created in the previous example. + +
+This example creates a 2D ESMF_Field from a 2D ESMF_Grid + and a 2D ESMF_Array. +
+
+ ! Get necessary information from the Grid + call ESMF_GridGet(grid, staggerloc=ESMF_STAGGERLOC_CENTER, & + distgrid=distgrid, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Create a 2D ESMF_TYPEKIND_R4 arrayspec + call ESMF_ArraySpecSet(arrayspec, 2, ESMF_TYPEKIND_R4, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Create a ESMF_Array from the arrayspec and distgrid + array2d = ESMF_ArrayCreate(arrayspec=arrayspec, & + distgrid=distgrid, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Create a ESMF_Field from the grid and array + field4 = ESMF_FieldCreate(grid, array2d, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+A user can create an ESMF_Field in three steps: first create an empty + ESMF_Field; then set a ESMF_Grid on the empty ESMF_Field; + and finally complete the ESMF_Field by calling ESMF_FieldEmptyComplete. + +
+
+ ! create an empty Field + field3 = ESMF_FieldEmptyCreate(name="precip", rc=rc) ++ +
+
+ ! use FieldGet to retrieve the Field Status + call ESMF_FieldGet(field3, status=fstatus, rc=rc) ++ +
+Once the Field is created, we can verify that the status of the Field + is ESMF_FIELDSTATUS_EMPTY. +
+
+ ! Test the status of the Field + if (fstatus /= ESMF_FIELDSTATUS_EMPTY) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif ++ +
+Next we set a Grid on the empty Field. We use the 2D grid created in + a previous example simply to demonstrate the method. The Field data points + will be on east edge of the Grid cells with the specified + ESMF_STAGGERLOC_EDGE1. +
+
+ ! Set a grid on the Field + call ESMF_FieldEmptySet(field3, grid2d, & + staggerloc=ESMF_STAGGERLOC_EDGE1, rc=rc) ++ +
+
+ ! use FieldGet to retrieve the Field Status again + call ESMF_FieldGet(field3, status=fstatus, rc=rc) ++ +
+
+ ! Test the status of the Field + if (fstatus /= ESMF_FIELDSTATUS_GRIDSET) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif ++ +
+The partially created Field is completed by specifying the typekind of its + data storage. This method is overloaded with one of the + following parameters, arrayspec, typekind, Fortran array, or Fortran array pointer. + Additional optional arguments can be used to specify ungridded dimensions and + halo regions similar to the other Field creation methods. +
+
+ ! Complete the Field by specifying the data typekind + ! to be allocated internally. + call ESMF_FieldEmptyComplete(field3, typekind=ESMF_TYPEKIND_R8, & + ungriddedLBound=(/1/), ungriddedUBound=(/5/), rc=rc) ++ +
+
+ ! use FieldGet to retrieve the Field Status again + call ESMF_FieldGet(field3, status=fstatus, rc=rc) ++ +
+
+ ! Test the status of the Field + if (fstatus /= ESMF_FIELDSTATUS_COMPLETE) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif ++ +
+ +
+A user can create an empty ESMF_Field. + Then the user can finalize the empty ESMF_Field from a ESMF_Grid + and an intrinsic + Fortran data array. This interface is overloaded for typekind and rank + of the Fortran data array. + +
+In this example, both the grid and the Fortran array pointer are 2 dimensional + and each dimension of the grid is mapped to the corresponding dimension of the + Fortran array pointer, i.e. 1st dimension of grid maps to 1st dimension of + Fortran array pointer, 2nd dimension of grid maps to 2nd dimension of + Fortran array pointer, so on and so forth. + +
+In order to create or complete a Field from a Grid and a Fortran array pointer, + certain rules of the Fortran array bounds must be obeyed. We will discuss these + rules as we progress in Field creation examples. We will make + frequent reference to the terminologies for bounds and widths in ESMF. + For a better discussion of + these terminologies and concepts behind them, + e.g. exclusive, computational, total bounds + for the lower and upper corner of data region, etc.., users can refer to + the explanation of these concepts for Grid and Array in their respective sections + in the Reference Manual, e.g. Section 28.2.6 on Array + and Section 31.3.19 on Grid. + The examples here are designed to help a user to get up to speed with + creating Fields for typical use. + +
+This example introduces a helper method, the ESMF_GridGetFieldBounds + interface that facilitates the computation of Fortran data array bounds + and shape to assist ESMF_FieldEmptyComplete finalizing a Field from an + intrinsic Fortran data array and a Grid. + +
+
+ ! create an empty Field + field3 = ESMF_FieldEmptyCreate(name="precip", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! use FieldGet to retrieve total counts + call ESMF_GridGetFieldBounds(grid2d, localDe=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, totalCount=ftc, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! allocate the 2d Fortran array based on retrieved total counts + allocate(farray2d(ftc(1), ftc(2))) + + ! finalize the Field + call ESMF_FieldEmptyComplete(field3, grid2d, farray2d, rc=rc) ++ +
+ +
+In this example, we will show how to create a 7D Field from a 5D ESMF_Grid and 2D ungridded bounds with arbitrary halo widths and + gridToFieldMap. + +
+We first create a 5D DistGrid and a 5D Grid based on the DistGrid; then + ESMF_GridGetFieldBounds computes the shape of a 7D array in fsize. We can then + create a 7D Field from the 5D Grid and the 7D Fortran data array with + other assimilating parameters. +
+
+ ! create a 5d distgrid + distgrid5d = ESMF_DistGridCreate(minIndex=(/1,1,1,1,1/), & + maxIndex=(/10,4,10,4,6/), regDecomp=(/2,1,2,1,1/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Create a 5d Grid + grid5d = ESMF_GridCreate(distgrid=distgrid5d, name="grid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! use FieldGet to retrieve total counts + call ESMF_GridGetFieldBounds(grid5d, localDe=0, ungriddedLBound=(/1,2/), & + ungriddedUBound=(/4,5/), & + totalLWidth=(/1,1,1,2,2/), totalUWidth=(/1,2,3,4,5/), & + gridToFieldMap=(/3,2,5,4,1/), & + totalCount=fsize, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! allocate the 7d Fortran array based on retrieved total counts + allocate(farray7d(fsize(1), fsize(2), fsize(3), fsize(4), fsize(5), & + fsize(6), fsize(7))) + + ! create the Field + field7d = ESMF_FieldCreate(grid5d, farray7d, ESMF_INDEX_DELOCAL, & + ungriddedLBound=(/1,2/), ungriddedUBound=(/4,5/), & + totalLWidth=(/1,1,1,2,2/), totalUWidth=(/1,2,3,4,5/), & + gridToFieldMap=(/3,2,5,4,1/), & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+A user can allocate the Fortran array in a different manner using the lower and + upper bounds returned from FieldGet through the optional totalLBound and totalUBound + arguments. In the following example, we create another 7D Field by retrieving the bounds + and allocate the Fortran array with this approach. In this scheme, indexing the + Fortran array is sometimes more convenient than using the shape directly. +
+
+ call ESMF_GridGetFieldBounds(grid5d, localDe=0, ungriddedLBound=(/1,2/), & + ungriddedUBound=(/4,5/), & + totalLWidth=(/1,1,1,2,2/), totalUWidth=(/1,2,3,4,5/), & + gridToFieldMap=(/3,2,5,4,1/), & + totalLBound=flbound, totalUBound=fubound, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + allocate(farray7d2(flbound(1):fubound(1), flbound(2):fubound(2), & + flbound(3):fubound(3), flbound(4):fubound(4), & + flbound(5):fubound(5), flbound(6):fubound(6), & + flbound(7):fubound(7)) ) + + field7d2 = ESMF_FieldCreate(grid5d, farray7d2, ESMF_INDEX_DELOCAL, & + ungriddedLBound=(/1,2/), ungriddedUBound=(/4,5/), & + totalLWidth=(/1,1,1,2,2/), totalUWidth=(/1,2,3,4,5/), & + gridToFieldMap=(/3,2,5,4,1/), & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+See 28.2.13 for a introduction of the DE pinning feature. + Here we focus on demonstrating the use of the DE pinning feature in the context of + ESMF Field. + +
+When an ESMF Field object is created, the specified underlying DistGrid indicates how + many Decomposition Elements (DEs) are created. Each DE has its own memory + allocation to hold user data. The DELayout, referenced by the DistGrid, + determines which PET is considered the owner of each of the DEs. Queried + for the local DEs, the Field object returns the list of DEs that are owned by + the local PET making the query. + +
+By default DEs are pinned to the PETs under which they were created. + The memory allocation associated with a specific DE is only defined in the + VAS of the PET to which the DE is pinned. As a consequence, only the PET + owning a DE has access to its memory allocation. + +
+On shared memory systems, however, ESMF allows DEs to be pinned to SSIs + instead of PETs. In this case the PET under which a DE was created is still + consider the owner, but now all PETs under the same SSI have access to + the DE. For this the memory allocation associated with the DE is mapped into + the VAS of all the PETs under the SSI. + +
+To create an Field with each DE pinned to SSI instead of PET, first query the + VM for the available level of support. +
+
+ call ESMF_VMGet(vm, ssiSharedMemoryEnabledFlag=ssiSharedMemoryEnabled, rc=rc) ++ +
+
+ if (ssiSharedMemoryEnabled) then ++ +
+Knowing that the SSI shared memory feature is available, it is now possible + to create an Field object with DE to SSI pinning. +
+
+ grid = ESMF_GridCreateNoPeriDim(maxIndex=(/40,10/), regDecomp=(/4,1/), & + coordSys = ESMF_COORDSYS_CART, & + rc=rc) ++ +
+
+ field = ESMF_FieldCreate(typekind=ESMF_TYPEKIND_R8, grid=grid, & + pinflag=ESMF_PIN_DE_TO_SSI, rc=rc) ++ +
+Just as in the cases discussed before, where the same Grid was used, a + default DELayout with as many DEs as PETs in the VM is constructed. Setting + the pinflag to ESMF_PIN_DE_TO_SSI does not change the + fact that each PET owns exactly one of the DEs. However, assuming that this + code is run on a set of PETs that are all located under the same SSI, every + PET now has access to all of the DEs. The situation can be observed by + querying for both the localDeCount, and the ssiLocalDeCount. +
+
+ call ESMF_FieldGet(field, localDeCount=localDeCount, & + ssiLocalDeCount=ssiLocalDeCount, rc=rc) ++ +
+Assuming execution on 4 PETs, all located on the same SSI, the values of the + returned variable are localDeCount==1 and ssiLocalDeCount==4 on + all of the PETs. The mapping between each PET's local DE, and the global DE + index is provided through the localDeToDeMap array argument. The amount + of mapping information returned is dependent on how large localDeToDeMap + has been sized by the user. For size(localDeToDeMap)==localDeCount, + only mapping information for those DEs owned by the local PET is filled + in. However for size(localDeToDeMap)==ssiLocalDeCount, mapping + information for all locally accessible DEs is returned, including + those owned by other PETs on the same SSI. + +
+
+ allocate(localDeToDeMap(0:ssiLocalDeCount-1)) + call ESMF_FieldGet(field, localDeToDeMap=localDeToDeMap, rc=rc) ++ +
+The first localDeCount entries of localDeToDeMap are always the + global DE indices of the DEs owned by the local PET. The remaining + ssiLocalDeCount-localDeCount entries are the global DE indices of + DEs shared by other PETs. The ordering of the shared DEs is from + smallest to greatest, excluding the locally owned DEs, which were already + listed at the beginning of localDeToDeMap. For the current case, again + assuming execution on 4 PETs all located on the same SSI, we expect the + following situation: + +
+PET 0: localDeToDeMap==(/0,1,2,3/)
+
+PET 1: localDeToDeMap==(/1,0,2,3/)
+
+PET 2: localDeToDeMap==(/2,0,1,3/)
+
+PET 3: localDeToDeMap==(/3,0,1,2/)
+
+
+
+Each PET can access the memory allocations associated with all of the + DEs listed in the localDeToDeMap returned by the Field object. Direct + access to the Fortran array pointer of a specific memory allocation is + available through ESMF_FieldGet(). Here each PET queries for the + farrayPtr of localDe==2, i.e. the 2nd shared DE. +
+
+ call ESMF_FieldGet(field, farrayPtr=myFarray, localDe=2, rc=rc) ++ +
+Now variable myFarray on PETs 0 and 1 both point to the same + memory allocation for global DE 2. Both PETs have access to the same + piece of shared memory! The same is true for PETs 2 and 3, pointing to the + shared memory allocation of global DE 1. + +
+It is important to note that all of the typical considerations surrounding + shared memory programming apply when accessing shared DEs! Proper + synchronization between PETs accessing shared DEs is critical to avoid + race conditions. Also performance issues like false sharing + need to be considered for optimal use. + +
+For a simple demonstration, PETs 0 and 2 fill the entire memory allocation of + DE 2 and 1, respectively, to a unique value. +
+
+ if (localPet==0) then + myFarray = 12345.6789d0 + else if (localPet==2) then + myFarray = 6789.12345d0 + endif ++ +
+Here synchronization is needed before any PETs that share access to the same + DEs can safely access the data without race condition. The Field class provides + a simple synchronization method that can be used. +
+
+ call ESMF_FieldSync(field, rc=rc) ! prevent race condition ++ +
+Now it is safe for PETs 1 and 3 to access the shared DEs. We expect to find + the data that was set above. For simplicity of the code only the first + array element is inspected here. +
+
+ if (localPet==1) then + if (abs(myFarray(1,1)-12345.6789d0)>1.d10) print *, "bad data detected" + else if (localPet==3) then + if (abs(myFarray(1,1)-6789.12345d0)>1.d10) print *, "bad data detected" + endif ++ +
+
+ endif ! ending the ssiSharedMemoryEnabled conditional ++ +
+ + +
+ +
+ +
+ +
+A user can create an ESMF_Field directly from an ESMF_Grid and an intrinsic + Fortran data array. This interface is overloaded for typekind and rank + of the Fortran data array. + +
+In the following example, each dimension size of the Fortran array is equal to the + exclusive bounds of its corresponding + Grid dimension queried from the Grid through ESMF_GridGet() public interface. + +
+Formally let fa_shape(i) be the shape of i-th dimension of user supplied Fortran array, + then rule 1 states: +
+ + (1) fa_shape(i) = exclusiveCount(i) + i = 1...GridDimCount ++ +
+fa_shape(i) defines the shape of i-th dimension of the Fortran array. + ExclusiveCount are the number of data elements of i-th dimension in the exclusive region queried + from ESMF_GridGet interface. Rule 1 assumes that the Grid and the Fortran intrinsic + array have same number of dimensions; and optional arguments + of FieldCreate from Fortran array are left unspecified using default setup. These assumptions + are true for most typical uses of FieldCreate from Fortran data array. This is the easiest way + to create a Field from a Grid and a Fortran intrinsic data array. + +
+Fortran array dimension sizes (called shape in most Fortran language books) are equivalent + to the bounds and counts used in this manual. The following equation holds: +
+ + fa_shape(i) = shape(i) = counts(i) = upper_bound(i) - lower_bound(i) + 1 ++ +
+These typically mean the same concept unless specifically explained to mean something else. + For example, ESMF uses DimCount very often to mean number of dimensions instead of its meaning + implied in the above equation. We'll clarify the meaning of a word when ambiguity could occur. + +
+Rule 1 is most useful for a user working with Field creation from a Grid and a Fortran + data array in most scenarios. It extends to higher dimension count, 3D, 4D, etc... + Typically, as the code example demonstrates, a user first creates a Grid, + then uses ESMF_GridGet() + to retrieve the exclusive counts. Next the user calculates the shape + of each Fortran array dimension according to rule 1. The Fortran data array is allocated + and initialized based on the computed shape. A Field can either be created in one shot or + created empty and finished using ESMF_FieldEmptyComplete. + +
+There are important details that can be skipped but are good to know for ESMF_FieldEmptyComplete + and ESMF_FieldCreate from a Fortran data array. 1) these methods require each PET contains + exactly one DE. This implies that a code using FieldCreate from a data array or FieldEmptyComplete must + have the same number of DEs and PETs, formally +. Violation of this condition + will cause run time failures. 2) the bounds and counts retrieved from GridGet are DE specific + or equivalently PET specific, which means that the Fortran array shape could be different from one + PET to another. + + +
+
+ grid = ESMF_GridCreateNoPeriDim(minIndex=(/1,1/), maxIndex=(/10,20/), & + regDecomp=(/2,2/), name="atmgrid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_GridGet(grid, localDE=0, staggerloc=ESMF_STAGGERLOC_CENTER, & + exclusiveCount=gec, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + allocate(farray(gec(1), gec(2)) ) + + field = ESMF_FieldCreate(grid, farray, ESMF_INDEX_DELOCAL, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+The setup of this example is similar to the previous section except + that the Field is created from a data pointer instead of a data array. + We highlight the ability to deallocate the internal Fortran data + pointer queried from the Field. This gives a user more flexibility with + memory management. + +
+
+ allocate(farrayPtr(gec(1), gec(2)) ) + + field = ESMF_FieldCreate(grid, farrayPtr, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + call ESMF_FieldGet(field, farrayPtr=farrayPtr2, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + ! deallocate the retrieved Fortran array pointer + deallocate(farrayPtr2) ++ +
+ +
+This example demonstrates a typical use of ESMF_Field combining + a 2D grid and a 3D Fortran native data array. One immediate problem follows: + how does one define the bounds of the ungridded dimension? This is + solved by the optional arguments ungriddedLBound and ungriddedUBound + of the ESMF_FieldCreate interface. By definition, ungriddedLBound + and ungriddedUBound + are both 1 dimensional integer Fortran arrays. + +
+Formally, let fa_shape(j=1...FieldDimCount-GridDimCount) be the shape of the + ungridded dimensions of a Field relative to the Grid used in Field creation. + The Field dimension count is equal to the number of dimensions of the Fortran array, which + equals the number of dimensions of the resultant Field. GridDimCount is + the number of dimensions of the Grid. + +
+fa_shape(j) is computed as: +
+ + fa_shape(j) = ungriddedUBound(j) - ungriddedLBound(j) + 1 ++ +
+fa_shape is easy to compute when the gridded and ungridded dimensions do not + mix. However, it's conceivable that at higher dimension count, gridded and ungridded + dimensions can interleave. To aid the computation of ungridded dimension shape + we formally introduce the mapping concept. + +
+Let +, and +. is the number + of elements in set A, is the number of elements in set B. defines + a mapping from i-th element of set A to -th element in set B. + indicates there does not exist a mapping from i-th element of set A to set B. + +
+Suppose we have a mapping from dimension index of ungriddedLBound (or + ungriddedUBound) to Fortran array dimension index, called ugb2fa. + By definition, equals to the dimension count of + ungriddedLBound (or ungriddedUBound), equals to the dimension count of + the Fortran array. We can now formulate the computation of ungridded + dimension shape as rule 2: +
+ + (2) fa_shape(ugb2fa(j)) = ungriddedUBound(j) - ungriddedLBound(j) + 1 + j = 1..FortranArrayDimCount - GridDimCount ++ +
+The mapping can be computed in linear time proportional to the + Fortran array dimension count (or rank) using the following algorithm in pseudocode: +
+ + map_index = 1 + do i = 1, farray_rank + if i-th dimension of farray is ungridded + ugb2fa(map_index) = i + map_index = map_index + 1 + endif + enddo ++ +
+Here we use rank and dimension count interchangeably. These 2 terminologies are typically + equivalent. But there are subtle differences + under certain conditions. Rank is the total number of dimensions of a tensor object. + Dimension count allows a finer description of the heterogeneous dimensions in that object. + For example, a Field of rank 5 can have 3 gridded dimensions and 2 ungridded dimensions. + Rank is precisely the summation of dimension count of all types of dimensions. + +
+For example, if a 5D array is used with a 3D Grid, there are 2 ungridded dimensions: + ungriddedLBound=(/1,2/) and ungriddedUBound=(/5,7/). + Suppose the distribution of dimensions looks like (O, X, O, X, O), O means gridded, + X means ungridded. Then the mapping from ungridded bounds to Fortran array is + ugb2fa=(/2, 4/). The shape of 2nd and 4th dimension of Fortran array should equal + (5, 8). + +
+Back to our 3D Field created from a 2D Grid and 3D Fortran array example, suppose the 3rd + Field dimension is ungridded, ungriddedLBound=(/3/), ungriddedUBound=(/9/). + First we use rule 1 to compute shapes of the gridded Fortran array dimension, + then we use rule 2 to compute shapes of the ungridded Fortran array dimension. + In this example, we used the exclusive bounds obtained in the previous + example. +
+
+ fa_shape(1) = gec(1) ! rule 1 + fa_shape(2) = gec(2) + fa_shape(3) = 7 ! rule 2 9-3+1 + allocate(farray3d(fa_shape(1), fa_shape(2), fa_shape(3))) + field = ESMF_FieldCreate(grid, farray3d, ESMF_INDEX_DELOCAL, & + ungriddedLBound=(/3/), ungriddedUBound=(/9/), & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+Building upon the previous example, we will create a 3D Field from + a 2D grid and 3D array but with a slight twist. In this example, we + introduce the gridToFieldMap argument that allows a user to map Grid + dimension index to Field dimension index. + +
+In this example, both dimensions of the Grid are distributed and the + mapping from DistGrid to Grid is (/1,2/). We will introduce rule 3 + assuming distgridToGridMap=(/1,2,3...gridDimCount/), and distgridDimCount equals + to gridDimCount. This is a reasonable assumption in typical Field use. + +
+We apply the mapping gridToFieldMap on rule 1 to create rule 3: +
+ + (3) fa_shape(gridToFieldMap(i)) = exclusiveCount(i) + i = 1,..GridDimCount. ++ +
+Back to our example, suppose the 2nd + Field dimension is ungridded, ungriddedLBound=(/3/), ungriddedUBound=(/9/). + gridToFieldMap=(/3,1/), meaning the 1st Grid dimension maps to 3rd Field dimension, + and 2nd Grid dimension maps to 1st Field dimension. + +
+First we use rule 3 to compute shapes of the gridded Fortran array dimension, + then we use rule 2 to compute shapes of the ungridded Fortran array dimension. + In this example, we use the exclusive bounds obtained in the previous + example. +
+
+ gridToFieldMap2d(1) = 3 + gridToFieldMap2d(2) = 1 + do i = 1, 2 + fa_shape(gridToFieldMap2d(i)) = gec(i) + end do + fa_shape(2) = 7 + allocate(farray3d(fa_shape(1), fa_shape(2), fa_shape(3))) + field = ESMF_FieldCreate(grid, farray3d, ESMF_INDEX_DELOCAL, & + ungriddedLBound=(/3/), ungriddedUBound=(/9/), & + gridToFieldMap=gridToFieldMap2d, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+This example is similar to example 26.3.14. + In addition, here we will show how + a user can associate different halo widths to a Fortran array to create + a Field through the totalLWidth and totalUWidth optional arguments. + A diagram of the dimension configuration from Grid, halos, and Fortran data array + is shown here. +
+The ESMF_FieldCreate() interface supports creating a Field from a Grid and a + Fortran array padded with halos on the distributed dimensions of the Fortran + array. Using this technique one can avoid passing non-contiguous Fortran array + slice to FieldCreate. It guarantees the same exclusive region, + and by using halos, it also defines a bigger total region to contain + the entire contiguous memory block of the Fortran array. + +
+The elements of totalLWidth and totalUWidth are applied in the order + distributed dimensions appear in the Fortran array. By definition, + totalLWidth and totalUWidth are 1 dimensional arrays of non-negative + integer values. The size of haloWidth arrays is equal to the number of distributed + dimensions of the Fortran array, which is also equal to the number of + distributed dimensions of the Grid used in the Field creation. + +
+Because the order of totalWidth (representing both totalLWidth and + totalUWidth) element is applied to the order distributed dimensions + appear in the Fortran array dimensions, it's quite simple to compute + the shape of distributed dimensions of the Fortran array. They are done + in a similar manner when applying ungriddedLBound and ungriddedUBound + to ungridded dimensions of the Fortran array defined by rule 2. + +
+Assume we have the mapping from the dimension index of totalWidth + to the dimension index of Fortran array, called mhw2fa; and we also + have the mapping from dimension index of Fortran array to dimension + index of the Grid, called fa2g. The shape of + distributed dimensions of a Fortran array can be computed by rule 4: + +
+
+ + (4) fa_shape(mhw2fa(k)) = exclusiveCount(fa2g(mhw2fa(k)) + + totalUWidth(k) + totalLWidth(k) + k = 1...size(totalWidth) ++ +
+This rule may seem confusing but algorithmically the computation + can be done by the following pseudocode: + +
+
+ + fa_index = 1 + do i = 1, farray_rank + if i-th dimension of Fortran array is distributed + fa_shape(i) = exclusiveCount(fa2g(i)) + + totalUWidth(fa_index) + totalLWidth(fa_index) + fa_index = fa_index + 1 + endif + enddo ++ +
+The only complication then is to figure out the mapping from Fortran + array dimension index to Grid dimension index. This process can + be done by computing the reverse mapping from Field to Grid. + +
+Typically, we don't have to consider these complications if the following + conditions are met: 1) All Grid dimensions are distributed. 2) DistGrid + in the Grid has a dimension index mapping to the Grid in the form of + natural order (/1,2,3,.../). This natural order mapping is the + default mapping between various objects throughout ESMF. 3) Grid to Field + mapping is in the form of natural order, i.e. default mapping. These + seem like a lot of conditions but they are the default case in the interaction + among DistGrid, Grid, and Field. When these conditions are met, which + is typically true, the shape of distributed dimensions of Fortran array + follows rule 5 in a simple form: + +
+
+ + (5) fa_shape(k) = exclusiveCount(k) + + totalUWidth(k) + totalLWidth(k) + k = 1...size(totalWidth) ++ +
+Let's examine an example on how to apply rule 5. Suppose we have a + 5D array and a 3D Grid that has its first 3 dimensions mapped to the first + 3 dimensions of the Fortran array. totalLWidth=(/1,2,3/), + totalUWidth=(/7,9,10/), then by rule 5, the following pseudo code + can be used to compute the shape of the first 3 dimensions of the Fortran + array. The shape of the remaining two ungridded dimensions can be + computed according to rule 2. + +
+
+ + do k = 1, 3 + fa_shape(k) = exclusiveCount(k) + + totalUWidth(k) + totalLWidth(k)) + enddo ++ +
+Suppose now gridToFieldMap=(/2,3,4/) instead which says + the first dimension of Grid maps to the 2nd dimension of Field (or + Fortran array) and so on and so forth, we can obtain a more general form + of rule 5 by introducing first_distdim_index shift when Grid to Field + map (gridToFieldMap) is in the form of (/a,a+1,a+2.../). + +
+
+ + (6) fa_shape(k+first_distdim_index-1) = exclusiveCount(k) + + totalUWidth(k) + totalLWidth(k) + k = 1...size(totalWidth) ++ +
+It's obvious that first_distdim_index=a. If the first dimension of the Fortran + array is distributed, then rule 6 degenerates into rule 5, which is + the typical case. + +
+Back to our example creating a 3D Field from a 2D Grid and a 3D intrinsic + Fortran array, we will use the Grid created from previous example + that satisfies condition 1 and 2. We'll also use a simple gridToFieldMap + (1,2) which is the default mapping that satisfies condition 3. + First we use rule 5 to compute + the shape of distributed dimensions then we use rule 2 to compute the shape + of the ungridded dimensions. +
+
+ gridToFieldMap2d(1) = 1 + gridToFieldMap2d(2) = 2 + totalLWidth2d(1) = 3 + totalLWidth2d(2) = 4 + totalUWidth2d(1) = 3 + totalUWidth2d(2) = 5 + do k = 1, 2 + fa_shape(k) = gec(k) + totalLWidth2d(k) + totalUWidth2d(k) + end do + fa_shape(3) = 7 ! 9-3+1 + allocate(farray3d(fa_shape(1), fa_shape(2), fa_shape(3))) + field = ESMF_FieldCreate(grid, farray3d, ESMF_INDEX_DELOCAL, & + ungriddedLBound=(/3/), ungriddedUBound=(/9/), & + totalLWidth=totalLWidth2d, totalUWidth=totalUWidth2d, & + gridToFieldMap=gridToFieldMap2d, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+In this example, an ESMF_Field is created from an ESMF_LocStream + and typekind/rank. + The location stream object is uniformly distributed + in a 1 dimensional space on 4 DEs. The rank is 1 dimensional. + Please refer to LocStream examples section for more information on LocStream creation. + +
+
+ locs = ESMF_LocStreamCreate(minIndex=1, maxIndex=16, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + field = ESMF_FieldCreate(locs, typekind=ESMF_TYPEKIND_I4, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+In this example, an ESMF_Field is created from an ESMF_LocStream + and an ESMF_Arrayspec. + The location stream object is uniformly distributed + in a 1 dimensional space on 4 DEs. The arrayspec is 1 dimensional. + Please refer to LocStream examples section for more information on LocStream creation. + +
+
+ locs = ESMF_LocStreamCreate(minIndex=1, maxIndex=16, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_ArraySpecSet(arrayspec, 1, ESMF_TYPEKIND_I4, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + field = ESMF_FieldCreate(locs, arrayspec, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+In this example, an ESMF_Field is created from an ESMF_Mesh + and typekind/rank. + The mesh object is on a Euclidean surface that is partitioned to a 2x2 rectangular + space with 4 elements and 9 nodes. The nodal space is represented by + a distgrid with 9 indices. A Field is created on locally owned nodes on each PET. + Therefore, the created Field has 9 data points globally. + The mesh object can be represented by the picture + below. For more information on Mesh creation, please see Section 33.3.1. +
+ Mesh Ids + + 2.0 7 ------- 8 -------- 9 + | | | + | 3 | 4 | + | | | + 1.0 4 ------- 5 -------- 6 + | | | + | 1 | 2 | + | | | + 0.0 1 ------- 2 -------- 3 + + 0.0 1.0 2.0 + + Node Ids at corners + Element Ids in centers + + + Mesh Owners + + 2.0 2 ------- 2 -------- 3 + | | | + | 2 | 3 | + | | | + 1.0 0 ------- 0 -------- 1 + | | | + | 0 | 1 | + | | | + 0.0 0 ------- 0 -------- 1 + + 0.0 1.0 2.0 + + Node Owners at corners + Element Owners in centers ++ +
+
+ ! Create Mesh structure in 1 step + mesh=ESMF_MeshCreate(parametricDim=2,spatialDim=2, & + nodeIds=nodeIds, nodeCoords=nodeCoords, & + nodeOwners=nodeOwners, elementIds=elemIds,& + elementTypes=elemTypes, elementConn=elemConn, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Field is created on the 1 dimensional nodal distgrid. On + ! each PET, Field is created on the locally owned nodes. + field = ESMF_FieldCreate(mesh, typekind=ESMF_TYPEKIND_I4, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+In this example, an ESMF_Field is created from an ESMF_Mesh + and an ESMF_Arrayspec. + The mesh object is on a Euclidean surface that is partitioned to a 2x2 rectangular + space with 4 elements and 9 nodes. The nodal space is represented by + a distgrid with 9 indices. Field is created on locally owned nodes on each PET. + Therefore, the created Field has 9 data points globally. + The mesh object can be represented by the picture + below. For more information on Mesh creation, please see Section 33.3.1. + +
+
+ ! Create Mesh structure in 1 step + mesh=ESMF_MeshCreate(parametricDim=2,spatialDim=2, & + nodeIds=nodeIds, nodeCoords=nodeCoords, & + nodeOwners=nodeOwners, elementIds=elemIds,& + elementTypes=elemTypes, elementConn=elemConn, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_ArraySpecSet(arrayspec, 1, ESMF_TYPEKIND_I4, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Field is created on the 1 dimensional nodal distgrid. On + ! each PET, Field is created on the locally owned nodes. + field = ESMF_FieldCreate(mesh, arrayspec, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+In this example, an ESMF_Field is created from an ESMF_Mesh + and an ESMF_Array. The mesh object is created in the previous example and + the array object is retrieved from the field created in the previous example too. + +
+
+ call ESMF_MeshGet(mesh, nodalDistgrid=distgrid, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + array = ESMF_ArrayCreate(distgrid=distgrid, arrayspec=arrayspec, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + ! query the array from the previous example + call ESMF_FieldGet(field, array=array, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + ! create a Field from a mesh and an array + field1 = ESMF_FieldCreate(mesh, array, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+In this example, an ESMF_Field is created from an ESMF_Mesh + and an ESMF_ArraySpec. The mesh object is created in the previous example. + The Field is also created with optional arguments such as ungridded dimensions + and dimension mapping. + +
+In this example, the mesh is mapped to the 2nd dimension of the + ESMF_Field, with its first dimension being the ungridded dimension with bounds 1,3. + +
+
+ call ESMF_ArraySpecSet(arrayspec, 2, ESMF_TYPEKIND_I4, rc=rc) + field = ESMF_FieldCreate(mesh, arrayspec=arrayspec, gridToFieldMap=(/2/), & + ungriddedLBound=(/1/), ungriddedUBound=(/3/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ + +
+ +
+ +
+ +
+In this example an ESMF_Field with replicated dimension is created from an ESMF_Grid and + an ESMF_Arrayspec. A user can also use other ESMF_FieldCreate() methods to create replicated + dimension Field, this example illustrates the key concepts and use of a replicated dimension Field. + +
+Normally gridToFieldMap argument in ESMF_FieldCreate() should not contain + 0 value entries. However, for a Field with replicated dimension, a 0 entry in gridToFieldMap + indicates the corresponding Grid dimension is replicated in the Field. In such a Field, + the rank of the Field is no longer necessarily greater than its Grid rank. + An example will make this clear. We will start by creating Distgrid and Grid. + +
+
+ ! create 4D distgrid + distgrid = ESMF_DistGridCreate(minIndex=(/1,1,1,1/), & + maxIndex=(/6,4,6,4/), regDecomp=(/2,1,2,1/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create 4D grid on top of the 4D distgrid + grid = ESMF_GridCreate(distgrid=distgrid, name="grid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create 3D arrayspec + call ESMF_ArraySpecSet(arrayspec, 3, ESMF_TYPEKIND_R8, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+In this example, a user creates a 3D Field with replicated dimension + replicated along the 2nd and 4th dimension of its underlying 4D Grid. + In addition, the 2nd dimension of the Field is ungridded (why?). The 1st and + 3rd dimensions of the Field have halos. +
+
+ ! create field, 2nd and 4th dimensions of the Grid are replicated + field = ESMF_FieldCreate(grid, arrayspec, indexflag=ESMF_INDEX_DELOCAL, & + gridToFieldMap=(/1,0,2,0/), & + ungriddedLBound=(/1/), ungriddedUBound=(/4/), & + totalLWidth=(/1,1/), totalUWidth=(/4,5/), & + staggerloc=ESMF_STAGGERLOC_CORNER, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! get basic information from the field + call ESMF_FieldGet(field, grid=grid1, array=array, typekind=typekind, & + dimCount=dimCount, staggerloc=lstaggerloc, & + gridToFieldMap=lgridToFieldMap, ungriddedLBound=lungriddedLBound, & + ungriddedUBound=lungriddedUBound, totalLWidth=ltotalLWidth, & + totalUWidth=ltotalUWidth, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! get bounds information from the field + call ESMF_FieldGet(field, localDe=0, farrayPtr=farray, & + exclusiveLBound=felb, exclusiveUBound=feub, exclusiveCount=fec, & + computationalLBound=fclb, computationalUBound=fcub, & + computationalCount=fcc, totalLBound=ftlb, totalUBound=ftub, & + totalCount=ftc, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+Next we verify that the field and array bounds agree with each other +
+ call ESMF_ArrayGet(array, rank=arank, dimCount=adimCount, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + gridrank_repdim = 0 + do i = 1, size(gridToFieldMap) + if(gridToFieldMap(i) == 0) gridrank_repdim = gridrank_repdim + 1 + enddo ++ +
+Number of undistributed dimension of the array X is computed from + total rank of the array A, the dimension count of its underlying distgrid + B and number of replicated dimension in the distgrid C. + We have the following formula: X = A - (B - C) +
+
+ allocate(audlb(arank-adimCount+gridrank_repdim), & + audub(arank-adimCount+gridrank_repdim)) + call ESMF_ArrayGet(array, exclusiveLBound=aelb, exclusiveUBound=aeub, & + computationalLBound=aclb, computationalUBound=acub, & + totalLBound=atlb, totalUBound=atub, & + undistLBound=audlb, undistUBound=audub, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! verify the ungridded bounds from field match + ! undistributed bounds from its underlying array + do i = 1, arank-adimCount + if(lungriddedLBound(i) .ne. audlb(i) ) & + rc = ESMF_FAILURE + enddo + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + do i = 1, arank-adimCount + if(lungriddedUBound(i) .ne. audub(i) ) & + rc = ESMF_FAILURE + enddo + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+We then verify the data in the replicated dimension Field can be updated and accessed. +
+
+ do ik = ftlb(3), ftub(3) + do ij = ftlb(2), ftub(2) + do ii = ftlb(1), ftub(1) + farray(ii,ij,ik) = ii+ij*2+ik + enddo + enddo + enddo + ! access and verify + call ESMF_FieldGet(field, localDe=0, farrayPtr=farray1, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + do ik = ftlb(3), ftub(3) + do ij = ftlb(2), ftub(2) + do ii = ftlb(1), ftub(1) + n = ii+ij*2+ik + if(farray1(ii,ij,ik) .ne. n ) rc = ESMF_FAILURE + enddo + enddo + enddo + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! release resources + call ESMF_FieldDestroy(field) + call ESMF_GridDestroy(grid) + call ESMF_DistGridDestroy(distgrid) ++ +
+ + +
+ +
+ +
+ +
+With the introduction of Field on arbitrarily distributed Grid, Field has two kinds of dimension + count: one associated geometrical (or physical) dimensionality, the other one associated with its + memory index space representation. Field and Grid dimCount reflect the physical index + space of the objects. A new type of dimCount rank should be added to both of these entities. + The rank gives the number of dimensions of the memory index space of the objects. + This would be the dimension of the pointer pulled out of Field and the + size of the bounds vector, for example. + +
+For non-arbitrary Grids rank=dimCount, but for grids and fields with + arbitrary dimensions rank = dimCount - (number of Arb dims) + 1 + (Internally Field can use the Arb info from the grid to create the mapping + from the Field Array to the DistGrid) + +
+When creating a Field size(GridToFieldMap)=dimCount for both Arb and Non-arb grids + This array specifies the mapping of Field to Grid identically for both Arb and Nonarb grids + If a zero occurs in an entry corresponding to any arbitrary dimension, then + a zero must occur in every entry corresponding to an arbitrary dimension (i.e. + all arbitrary dimensions must either be all replicated or all not replicated, + they can't be broken apart). + +
+In this example an ESMF_Field is created from an arbitrarily distributed ESMF_Grid and + an ESMF_Arrayspec. A user can also use other ESMF_FieldCreate() methods to create + such a Field, this example illustrates the key concepts and use of Field on arbitrary distributed Grid. + +
+The Grid is 3 dimensional in physics index space but the first two dimension are collapsed into + a single memory index space. Thus the resulting Field is 3D in physics index space and 2D in memory index + space. This is made obvious with the 2D arrayspec used to create this Field. + +
+
+ ! create a 3D grid with the first 2 dimensions collapsed + ! and arbitrarily distributed + grid3d = ESMF_GridCreateNoPeriDim(coordTypeKind=ESMF_TYPEKIND_R8, & + minIndex=(/1,1,1/), maxIndex=(/xdim, ydim,zdim/), & + arbIndexList=localArbIndex,arbIndexCount=localArbIndexCount, & + name="arb3dgrid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create a 2D arrayspec + call ESMF_ArraySpecSet(arrayspec2D, rank=2, typekind=ESMF_TYPEKIND_R4, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create a 2D Field using the Grid and the arrayspec + field = ESMF_FieldCreate(grid3d, arrayspec2D, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_FieldGet(field, rank=rank, dimCount=dimCount, & + rc=rc) + if (myPet .eq. 0) print *, 'Field rank, dimCount', & + rank, dimCount + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! verify that the dimension counts are correct + if (rank .ne. 2) correct = .false. + if (dimCount .ne. 3) correct = .false. ++ +
+ +
+The next example is slightly more complicated in + that the Field also contains one ungridded dimension and its gridded dimension + is replicated on the arbitrarily distributed dimension of the Grid. + +
+The same 3D Grid and 2D arrayspec in the previous example + are used but a gridToFieldMap argument + is supplied to the ESMF_FieldCreate() call. The first 2 entries of + the map are 0, the last (3rd) entry is 1. The 3rd dimension of the Grid is + mapped to the first dimension of the Field, this dimension is then replicated + on the arbitrarily distributed dimensions of the Grid. In addition, the + Field also has one ungridded dimension. Thus the final dimension count of the + Field is 2 in both physics and memory index space. + +
+
+ field = ESMF_FieldCreate(grid3d, arrayspec2D,gridToFieldMap=(/0,0,1/), & + ungriddedLBound=(/1/), ungriddedUBound=(/10/),rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_FieldGet(field, rank=rank, dimCount=dimCount, & + rc=rc) + if (myPet .eq. 0) print *, 'Field rank, dimCount', & + rank, dimCount + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + if (rank .ne. 2) correct = .false. + if (dimCount .ne. 2) correct = .false. ++ +
+ + +
+ +
+ +
+ +
+This section describes the Field regrid methods. For an in depth description of ESMF regridding and the options available + please see Section 24.2. + +
+The basic flow of ESMF Field regridding is as follows. First a source and destination geometry object are created, depending on + the regrid method they can be either a Grid, a Mesh, an XGrid, or a LocStream. + Next Fields are built on the source and destination grid objects. These Fields are then passed into ESMF_FieldRegridStore(). The user can either get a + sparse matrix from this call and/or a routeHandle. If the user gets the sparse matrix then they are responsible for deallocating it, but other than that + can use it as they wish. The routeHandle can be used in the ESMF_FieldRegrid() call to perform the actual interpolation of data from the source + to the destination field. This interpolation can be repeated for the same set of Fields as long as the coordinates at the staggerloc involved in the + regridding in the associated grid object don't change. The same routeHandle can also be used between any pair of Fields that matches the original + pari in type, kind, and memory layout of the gridded dimensions. However, the size, number, and index order of ungridded dimensions + may be different. See section 37.2.5 for a more detailed discussion of RouteHandle reusability. + However, if you want + the routehandle to be the same interpolation between the grid objects upon which the Fields are built as was calculated + with the original ESMF_FieldRegridStore() call, then there + are additional constraints on the grid objects. To be the same interpolation, the grid objects upon which the + Fields are build must contain the same coordinates at the stagger locations involved in the regridding as + the original source and destination Fields used in the ESMF_FieldRegridStore() call. + The routehandle represents the interpolation between the grid objects as they were during the ESMF_FieldRegridStore() call. + So if the coordinates at the stagger location in the grid objects change, a new call to ESMF_FieldRegridStore() + is necessary to compute the interpolation between that new set of coordinates. When finished with the routeHandle + ESMF_FieldRegridRelease() should be used to + free the associated memory. + +
+The following example demonstrates doing a regrid operation between two Fields. + +
+
+ ! (Create source Grid, Mesh, XGrid, or LocStream.) + ! (Create srcField on the above.) + + ! (Create destination Grid, Mesh, XGrid, or LocStream.) + ! (Create dstField on the above.) + + ! Create the routeHandle which encodes the communication and + ! information necessary for the regrid sparse matrix multiply. + call ESMF_FieldRegridStore(srcField=srcField, dstField=dstField, & + routeHandle=routeHandle, rc=localrc) ++ +
+
+ + ! Can loop here regridding from srcField to dstField + ! do i=1,.... + + ! (Put data into srcField) + + ! Use the routeHandle to regrid data from srcField to dstField. + ! As described above, the same routeHandle can be used to + ! regrid a large class of different source and destination Fields. + call ESMF_FieldRegrid(srcField, dstField, routeHandle, rc=localrc) ++ +
+
+ ! (Use data in dstField) + + ! enddo + + + ! Free the buffers and data associated with the routeHandle. + call ESMF_FieldRegridRelease(routeHandle, rc=localrc) ++ +
+ + +
+ +
+ +
+ +
+
+ call ESMF_FieldRegridStore(srcField=srcField, srcMaskValues=(/1/), & + dstField=dstField, dstMaskValues=(/1/), & + unmappedaction=ESMF_UNMAPPEDACTION_IGNORE, & + routeHandle=routeHandle, & + regridmethod=ESMF_REGRIDMETHOD_BILINEAR, & + rc=localrc) ++ +
+The ESMF_FieldRegrid and ESMF_FieldRegridRelease calls + may then be applied as in the previous example. + + +
+ +
+ +
+ +
+
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ! Create Source Mesh + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ! Create the Mesh structure. + ! For brevity's sake, the code to fill the Mesh creation + ! arrays is omitted from this example. However, here + ! is a brief description of the arrays: + ! srcNodeIds - the global ids for the src nodes + ! srcNodeCoords - the coordinates for the src nodes + ! srcNodeOwners - which PET owns each src node + ! srcElemIds - the global ids of the src elements + ! srcElemTypes - the topological shape of each src element + ! srcElemConn - how to connect the nodes to form the elements + ! in the source mesh + ! Several examples of setting up these arrays can be seen in + ! the Mesh Section "Mesh Creation". + srcMesh=ESMF_MeshCreate(parametricDim=2,spatialDim=2, & + nodeIds=srcNodeIds, nodeCoords=srcNodeCoords, & + nodeOwners=srcNodeOwners, elementIds=srcElemIds,& + elementTypes=srcElemTypes, elementConn=srcElemConn, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ! Create and Fill Source Field + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ! Set description of source Field + call ESMF_ArraySpecSet(arrayspec, 1, ESMF_TYPEKIND_R8, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Create source Field + srcField = ESMF_FieldCreate(srcMesh, arrayspec, & + name="source", rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Get source Field data pointer to put data into + call ESMF_FieldGet(srcField, 0, fptr1D, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Get number of local nodes to allocate space + ! to hold local node coordinates + call ESMF_MeshGet(srcMesh, & + numOwnedNodes=numOwnedNodes, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Allocate space to hold local node coordinates + ! (spatial dimension of Mesh*number of local nodes) + allocate(ownedNodeCoords(2*numOwnedNodes)) + + ! Get local node coordinates + call ESMF_MeshGet(srcMesh, & + ownedNodeCoords=ownedNodeCoords, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Set the source Field to the function 20.0+x+y + do i=1,numOwnedNodes + ! Get coordinates + x=ownedNodeCoords(2*i-1) + y=ownedNodeCoords(2*i) + + ! Set source function + fptr1D(i) = 20.0+x+y + enddo + + ! Deallocate local node coordinates + deallocate(ownedNodeCoords) + + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ! Create Destination Mesh + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ! Create the Mesh structure. + ! For brevity's sake, the code to fill the Mesh creation + ! arrays is omitted from this example. However, here + ! is a brief description of the arrays: + ! dstNodeIds - the global ids for the dst nodes + ! dstNodeCoords - the coordinates for the dst nodes + ! dstNodeOwners - which PET owns each dst node + ! dstElemIds - the global ids of the dst elements + ! dstElemTypes - the topological shape of each dst element + ! dstElemConn - how to connect the nodes to form the elements + ! in the destination mesh + ! Several examples of setting up these arrays can be seen in + ! the Mesh Section "Mesh Creation". + dstMesh=ESMF_MeshCreate(parametricDim=2,spatialDim=2, & + nodeIds=dstNodeIds, nodeCoords=dstNodeCoords, & + nodeOwners=dstNodeOwners, elementIds=dstElemIds,& + elementTypes=dstElemTypes, elementConn=dstElemConn, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ! Create Destination Field + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ! Set description of source Field + call ESMF_ArraySpecSet(arrayspec, 1, ESMF_TYPEKIND_R8, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Create destination Field + dstField = ESMF_FieldCreate(dstMesh, arrayspec, & + name="destination", rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ! Do Regrid + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ! Compute RouteHandle which contains the regrid operation + call ESMF_FieldRegridStore( & + srcField, & + dstField=dstField, & + routeHandle=routeHandle, & + regridmethod=ESMF_REGRIDMETHOD_BILINEAR, & + rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Perform Regrid operation moving data from srcField to dstField + call ESMF_FieldRegrid(srcField, dstField, routeHandle, rc=rc) + + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ! dstField now contains the interpolated data. + ! If the Meshes don't change, then routeHandle + ! may be used repeatedly to interpolate from + ! srcField to dstField. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + + ! User code to use the routeHandle, Fields, and + ! Meshes goes here before they are freed below. + + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ! Free the objects created in the example. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ! Free the RouteHandle + call ESMF_FieldRegridRelease(routeHandle, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Free the Fields + call ESMF_FieldDestroy(srcField, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_FieldDestroy(dstField, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Free the Meshes + call ESMF_MeshDestroy(dstMesh, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_MeshDestroy(srcMesh, rc=rc) + + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ + +
+ +
+ +
+ +
+User can use ESMF_FieldGather interface to gather Field data from multiple + PETs onto a single root PET. This interface is overloaded by type, kind, and rank. + +
+Note that the implementation of Scatter and Gather is not sequence index based. + If the Field is built on arbitrarily distributed Grid, Mesh, LocStream or XGrid, + Gather will not gather data to rootPet + from source data points corresponding to the sequence index on the rootPet. + Instead Gather will gather a contiguous memory range from source PET to + rootPet. The size of the memory range is equal to the number of + data elements on the source PET. Vice versa for the Scatter operation. + In this case, the user should use ESMF_FieldRedist to achieve + the same data operation result. For examples how to use ESMF_FieldRedist + to perform Gather and Scatter, please refer to + 26.3.32 and + 26.3.31. + +
+In this example, we first create a 2D Field, then use ESMF_FieldGather to + collect all the data in this Field into a data pointer on PET 0. +
+
+ ! Get current VM and pet number + call ESMF_VMGetCurrent(vm, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_VMGet(vm, localPet=lpe, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Create a 2D Grid and use this grid to create a Field + ! farray is the Fortran data array that contains data on each PET. + grid = ESMF_GridCreateNoPeriDim(minIndex=(/1,1/), maxIndex=(/10,20/), & + regDecomp=(/2,2/), & + name="grid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + field = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_I4, rc=localrc) + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + + call ESMF_FieldGet(field, farrayPtr=fptr, rc=localrc) + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + !---------Initialize pet specific field data---------------- + ! 1 5 10 + ! 1 +--------+---------+ + ! | | | + ! | 0 | 1 | + ! | | | + ! 10 +--------+---------+ + ! | | | + ! | 2 | 3 | + ! | | | + ! 20 +--------+---------+ + fptr = lpe + + ! allocate the Fortran data array on PET 0 to store gathered data + if(lpe .eq. 0) then + allocate (farrayDst(10,20)) + else + allocate (farrayDst(0,0)) + end if + call ESMF_FieldGather(field, farrayDst, rootPet=0, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! check that the values gathered on rootPet are correct + if(lpe .eq. 0) then + do i = 1, 5 + do j = 1, 10 + if(farrayDst(i, j) .ne. 0) localrc=ESMF_FAILURE + enddo + enddo + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + do i = 6, 10 + do j = 1, 10 + if(farrayDst(i, j) .ne. 1) localrc=ESMF_FAILURE + enddo + enddo + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + do i = 1, 5 + do j = 11, 20 + if(farrayDst(i, j) .ne. 2) localrc=ESMF_FAILURE + enddo + enddo + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + do i = 6, 10 + do j = 11, 20 + if(farrayDst(i, j) .ne. 3) localrc=ESMF_FAILURE + enddo + enddo + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + + ! destroy all objects created in this example to prevent memory leak + call ESMF_FieldDestroy(field, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + call ESMF_GridDestroy(grid, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + if(lpe .eq. 0) deallocate(farrayDst) ++ +
+ +
+User can use ESMF_FieldScatter interface to scatter Field data from root + PET onto its set of joint PETs. This interface is overloaded by type, kind, and rank. + +
+In this example, we first create a 2D Field, then use ESMF_FieldScatter to + scatter the data from a data array located on PET 0 onto this Field. +
+
+ ! Create a 2D Grid and use this grid to create a Field + ! farray is the Fortran data array that contains data on each PET. + grid = ESMF_GridCreateNoPeriDim(minIndex=(/1,1/), maxIndex=(/10,20/), & + regDecomp=(/2,2/), & + name="grid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + field = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_I4, rc=localrc) + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! initialize values to be scattered + ! 1 5 10 + ! 1 +--------+---------+ + ! | | | + ! | 0 | 1 | + ! | | | + ! 10 +--------+---------+ + ! | | | + ! | 2 | 3 | + ! | | | + ! 20 +--------+---------+ + if(lpe .eq. 0) then + allocate(farraySrc(10,20)) + farraySrc(1:5,1:10) = 0 + farraySrc(6:10,1:10) = 1 + farraySrc(1:5,11:20) = 2 + farraySrc(6:10,11:20) = 3 + else + allocate (farraySrc(0,0)) + endif + + ! scatter the data onto individual PETs of the Field + call ESMF_FieldScatter(field, farraySrc, rootPet=0, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_FieldGet(field, localDe=0, farrayPtr=fptr, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! verify that the scattered data is properly distributed + do i = lbound(fptr, 1), ubound(fptr, 1) + do j = lbound(fptr, 2), ubound(fptr, 2) + if(fptr(i, j) .ne. lpe) localrc = ESMF_FAILURE + enddo + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + enddo + + ! destroy all objects created in this example to prevent memory leak + call ESMF_FieldDestroy(field, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + call ESMF_GridDestroy(grid, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + if(lpe .eq. 0) deallocate(farraySrc) ++ +
+ + +
+ +
+ +
+ +
+User can use ESMF_FieldRedist interface to redistribute data from + source Field to destination Field. This interface is overloaded by type and kind; + In the version of ESMF_FieldRedist without factor argument, a default value + of 1 is used. + +
+In this example, we first create two 1D Fields, a source Field and a destination + Field. Then we use ESMF_FieldRedist to + redistribute data from source Field to destination Field. + +
+
+ ! Get current VM and pet number + call ESMF_VMGetCurrent(vm, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_VMGet(vm, localPet=localPet, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create grid + distgrid = ESMF_DistGridCreate(minIndex=(/1/), maxIndex=(/16/), & + regDecomp=(/4/), & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + grid = ESMF_GridCreate(distgrid=distgrid, & + name="grid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create srcField + ! +--------+--------+--------+--------+ + ! 0 1 2 3 ! value + ! 1 4 8 12 16 ! bounds + srcField = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_I4, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_FieldGet(srcField, farrayPtr=srcfptr, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + srcfptr(:) = localPet + + ! create dstField + ! +--------+--------+--------+--------+ + ! 0 0 0 0 ! value + ! 1 4 8 12 16 ! bounds + dstField = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_I4, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_FieldGet(dstField, farrayPtr=dstfptr, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + dstfptr(:) = 0 + + ! perform redist + ! 1. setup routehandle from source Field to destination Field + call ESMF_FieldRedistStore(srcField, dstField, routehandle, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! 2. use precomputed routehandle to redistribute data + call ESMF_FieldRedist(srcfield, dstField, routehandle, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! verify redist + call ESMF_FieldGet(dstField, localDe=0, farrayPtr=fptr, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Verify that the redistributed data in dstField is correct. + ! Before the redist op, the dst Field contains all 0. + ! The redist op reset the values to the PE value, verify this is the case. + do i = lbound(fptr, 1), ubound(fptr, 1) + if(fptr(i) .ne. localPet) localrc = ESMF_FAILURE + enddo + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+Field redistribution can also be performed between different Field pairs that + match the original Fields in type, kind, and memory layout of the + gridded dimensions. However, the size, number, and index order of + ungridded dimensions may be different. See section 37.2.5 + for a more detailed discussion of RouteHandle reusability. +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_I4, rank=2, rc=rc) ++ +
+Create two fields with ungridded dimensions using the Grid created previously. + The new Field pair has matching number of elements. The ungridded dimension + is mapped to the first dimension of either Field. +
+
+ srcFieldA = ESMF_FieldCreate(grid, arrayspec, gridToFieldMap=(/2/), & + ungriddedLBound=(/1/), ungriddedUBound=(/10/), rc=rc) ++ +
+
+ dstFieldA = ESMF_FieldCreate(grid, arrayspec, gridToFieldMap=(/2/), & + ungriddedLBound=(/1/), ungriddedUBound=(/10/), rc=rc) ++ +
+Using the previously computed routehandle, the Fields can be redistributed. +
+
+ call ESMF_FieldRedist(srcfieldA, dstFieldA, routehandle, rc=rc) ++ +
+
+ call ESMF_FieldRedistRelease(routehandle, rc=rc) ++ +
+ +
+User can use ESMF_FieldRedist interface to redistribute data from + source Field to destination Field, where the destination Field is built on + an arbitrarily distributed structure, e.g. ESMF_Mesh. The underlying mechanism is explained + in section 28.2.19. + +
+In this example, we will create 2 one dimensional Fields, the src Field has a regular decomposition + and holds all its data on a single PET, in this case PET 0. The destination Field is built on a Mesh + which is itself built on an arbitrarily distributed distgrid. Then we use ESMF_FieldRedist to + redistribute data from source Field to destination Field, similar to a traditional scatter operation. + +
+The src Field only has data on PET 0 where it is sequentially initialized, i.e. 1,2,3...This data + will be redistributed (or scattered) from PET 0 to the destination Field arbitrarily distributed on + all the PETs. +
+
+ ! a one dimensional grid whose elements are all located on PET 0 + distgrid = ESMF_DistGridCreate(minIndex=(/1/), maxIndex=(/9/), & + regDecomp=(/1/), & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + grid = ESMF_GridCreate(distgrid=distgrid, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + srcField = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_I4, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! initialize the source data + if (localPet == 0) then + call ESMF_FieldGet(srcField, farrayPtr=srcfptr, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + do i = 1, 9 + srcfptr(i) = i + enddo + endif ++ +
+For more information on Mesh creation, user can refer to Mesh examples section or Field creation + on Mesh example for more details. +
+
+ ! Create Mesh structure + mesh=ESMF_MeshCreate(parametricDim=2,spatialDim=2, & + nodeIds=nodeIds, nodeCoords=nodeCoords, & + nodeOwners=nodeOwners, elementIds=elemIds,& + elementTypes=elemTypes, elementConn=elemConn, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+Create the destination Field on the Mesh that is arbitrarily distributed on + all the PETs. +
+
+ dstField = ESMF_FieldCreate(mesh, typekind=ESMF_TYPEKIND_I4, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+Perform the redistribution from source Field to destination Field. +
+
+ call ESMF_FieldRedistStore(srcField, dstField, & + routehandle=routehandle, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + call ESMF_FieldRedist(srcField, dstField, routehandle=routehandle, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+We can now verify that the sequentially initialized source data is scattered + on to the destination Field. The data has been scattered onto the destination + Field with the following distribution. +
+ + 4 elements on PET 0: 1 2 4 5 + 2 elements on PET 1: 3 6 + 2 elements on PET 2: 7 8 + 1 element on PET 3: 9 ++ Because the redistribution is index based, the elements also corresponds to the + index space of Mesh in the destination Field. +
+
+ call ESMF_FieldGet(dstField, farrayPtr=dstfptr, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+The scatter operation is successful. Since the routehandle computed with + ESMF_FieldRedistStore can be reused, user can use the same routehandle + to scatter multiple source Fields from a single PET to multiple destination + Fields distributed on all PETs. The gathering operation is just the + opposite of the demonstrated scattering operation, where a user would + redist from a source Field distributed on multiple PETs to a destination Field + that only has data storage on a single PET. + +
+Now it's time to release all the resources. +
+
+ call ESMF_FieldRedistRelease(routehandle=routehandle, rc=rc) ++ +
+ +
+Similarly, one can use the same approach to gather the data from an arbitrary distribution + to a non-arbitrary distribution. This concept is demonstrated by using the previous Fields but + the data operation is reversed. This time data is gathered from the Field built on the mesh to the Field + that has only data allocation on rootPet. + +
+First a FieldRedist routehandle is created from the Field built on Mesh to the Field + that has only data allocation on rootPet. +
+
+ call ESMF_FieldRedistStore(dstField, srcField, routehandle=routehandle, & + rc=rc) ++ +
+Perform FieldRedist, this will gather the data points from the Field built on mesh to + the data pointer on the rootPet (default to 0) stored in the srcField. +
+
+ call ESMF_FieldRedist(dstField, srcField, routehandle=routehandle, rc=rc) ++ +
+Release the routehandle used for the gather operation. +
+
+ call ESMF_FieldRedistRelease(routehandle=routehandle, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+The ESMF_FieldSMM() interface can be used to perform sparse matrix multiplication + from + source Field to destination Field. This interface is overloaded by type and kind; + +
+In this example, we first create two 1D Fields, a source Field and a destination + Field. Then we use ESMF_FieldSMM to + perform sparse matrix multiplication from source Field to destination Field. + +
+The source and destination Field data are arranged such that each of the 4 PETs has 4
+ data elements. Moreover, the source Field has all its data elements initialized to a linear
+ function based on local PET number.
+ Then collectively on each PET, a SMM according to the following formula
+ is preformed:
+
+
+
+
+
+Because source Field data are initialized to a linear function based on local PET number, + the formula predicts that + the result destination Field data on each PET is 1,2,3,4. This is verified in the + example. + +
+Section 28.2.18 provides a detailed discussion of the + sparse matrix multiplication operation implemented in ESMF. + +
+
+ ! Get current VM and pet number + call ESMF_VMGetCurrent(vm, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_VMGet(vm, localPet=lpe, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create distgrid and grid + distgrid = ESMF_DistGridCreate(minIndex=(/1/), maxIndex=(/16/), & + regDecomp=(/4/), & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + grid = ESMF_GridCreate(distgrid=distgrid, & + name="grid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_GridGetFieldBounds(grid, localDe=0, totalCount=fa_shape, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create src\_farray, srcArray, and srcField + ! +--------+--------+--------+--------+ + ! 1 2 3 4 ! value + ! 1 4 8 12 16 ! bounds + allocate(src_farray(fa_shape(1)) ) + src_farray = lpe+1 + srcArray = ESMF_ArrayCreate(distgrid, src_farray, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + srcField = ESMF_FieldCreate(grid, srcArray, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! create dst_farray, dstArray, and dstField + ! +--------+--------+--------+--------+ + ! 0 0 0 0 ! value + ! 1 4 8 12 16 ! bounds + allocate(dst_farray(fa_shape(1)) ) + dst_farray = 0 + dstArray = ESMF_ArrayCreate(distgrid, dst_farray, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + dstField = ESMF_FieldCreate(grid, dstArray, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! perform sparse matrix multiplication + ! 1. setup routehandle from source Field to destination Field + ! initialize factorList and factorIndexList + allocate(factorList(4)) + allocate(factorIndexList(2,4)) + factorList = (/1,2,3,4/) + factorIndexList(1,:) = (/lpe*4+1,lpe*4+2,lpe*4+3,lpe*4+4/) + factorIndexList(2,:) = (/lpe*4+1,lpe*4+2,lpe*4+3,lpe*4+4/) + + call ESMF_FieldSMMStore(srcField, dstField, routehandle, & + factorList, factorIndexList, rc=localrc) + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! 2. use precomputed routehandle to perform SMM + call ESMF_FieldSMM(srcfield, dstField, routehandle, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! verify sparse matrix multiplication + call ESMF_FieldGet(dstField, localDe=0, farrayPtr=fptr, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! Verify that the result data in dstField is correct. + ! Before the SMM op, the dst Field contains all 0. + ! The SMM op reset the values to the index value, verify this is the case. + ! +--------+--------+--------+--------+ + ! 1 2 3 4 2 4 6 8 3 6 9 12 4 8 12 16 ! value + ! 1 4 8 12 16 ! bounds + do i = lbound(fptr, 1), ubound(fptr, 1) + if(fptr(i) /= i*(lpe+1)) rc = ESMF_FAILURE + enddo ++ +
+Field sparse matrix multiplication can also be applied between Fields + that matche the original Fields in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability +
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_I4, rank=2, rc=rc) ++ +
+Create two fields with ungridded dimensions using the Grid created previously. + The new Field pair has matching number of elements. The ungridded dimension + is mapped to the first dimension of either Field. +
+
+ srcFieldA = ESMF_FieldCreate(grid, arrayspec, gridToFieldMap=(/2/), & + ungriddedLBound=(/1/), ungriddedUBound=(/10/), rc=rc) ++ +
+
+ dstFieldA = ESMF_FieldCreate(grid, arrayspec, gridToFieldMap=(/2/), & + ungriddedLBound=(/1/), ungriddedUBound=(/10/), rc=rc) ++ +
+Using the previously computed routehandle, the sparse matrix multiplication + can be performed between the Fields. +
+
+ call ESMF_FieldSMM(srcfieldA, dstFieldA, routehandle, rc=rc) ++ +
+
+ ! release route handle + call ESMF_FieldSMMRelease(routehandle, rc=rc) ++ +
+In the following discussion, we demonstrate how to set up a SMM routehandle + between a pair of Fields that are different in number of gridded dimensions + and the size of those gridded dimensions. The source Field has a 1D decomposition + with 16 total elements; the destination Field has a 2D decomposition with + 12 total elements. For ease of understanding of the actual matrix calculation, + a global indexing scheme is used. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1/), maxIndex=(/16/), & + indexflag=ESMF_INDEX_GLOBAL, & + regDecomp=(/4/), & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + grid = ESMF_GridCreate(distgrid=distgrid, & + indexflag=ESMF_INDEX_GLOBAL, & + name="grid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + call ESMF_GridGetFieldBounds(grid, localDe=0, totalLBound=tlb, & + totalUBound=tub, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+create 1D src_farray, srcArray, and srcField +
+ + PET0 + PET1 + PET2 + PET3 + + +--------+--------+--------+--------+ + 1 2 3 4 ! value + 1 4 8 12 16 ! bounds of seq indices ++
+
+ allocate(src_farray2(tlb(1):tub(1)) ) + src_farray2 = lpe+1 + srcArray = ESMF_ArrayCreate(distgrid, src_farray2, & + indexflag=ESMF_INDEX_GLOBAL, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + !print *, lpe, '+', tlb, tub, '+', src_farray2 + + srcField = ESMF_FieldCreate(grid, srcArray, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+Create 2D dstField on the following distribution + (numbers are the sequence indices): +
+ + PET0 + PET1 + PET2 + PET3 + + +--------+--------+--------+--------+ + | | | | | + | 1 | 4 | 7 | 10 | + | | | | | + +--------+--------+--------+--------+ + | | | | | + | 2 | 5 | 8 | 11 | + | | | | | + +--------+--------+--------+--------+ + | | | | | + | 3 | 6 | 9 | 12 | + | | | | | + +--------+--------+--------+--------+ ++
+
+ ! Create the destination Grid + dstGrid = ESMF_GridCreateNoPeriDim(minIndex=(/1,1/), maxIndex=(/3,4/), & + indexflag = ESMF_INDEX_GLOBAL, & + regDecomp = (/1,4/), & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + dstField = ESMF_FieldCreate(dstGrid, typekind=ESMF_TYPEKIND_R4, & + indexflag=ESMF_INDEX_GLOBAL, & + rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+Perform sparse matrix multiplication = * + First setup routehandle from source Field to destination Field + with prescribed factorList and factorIndexList. + +
+The sparse matrix is of size 12x16, however only the following entries + are filled: +
+ M(3,1) = 0.1 + M(3,10) = 0.4 + M(8,2) = 0.25 + M(8,16) = 0.5 + M(12,1) = 0.3 + M(12,16) = 0.7 ++ +
+By the definition of matrix calculation, the 8th element on PET2 in the + dstField equals to 0.25*srcField(2) + 0.5*srcField(16) = 0.25*1+0.5*4=2.25 + For simplicity, we will load the factorList and factorIndexList on + PET 0 and 1, the SMMStore engine will load balance the parameters on all 4 + PETs internally for optimal performance. +
+
+ if(lpe == 0) then + allocate(factorList(3), factorIndexList(2,3)) + factorList=(/0.1,0.4,0.25/) + factorIndexList(1,:)=(/1,10,2/) + factorIndexList(2,:)=(/3,3,8/) + call ESMF_FieldSMMStore(srcField, dstField, routehandle=routehandle, & + factorList=factorList, factorIndexList=factorIndexList, rc=localrc) + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + else if(lpe == 1) then + allocate(factorList(3), factorIndexList(2,3)) + factorList=(/0.5,0.3,0.7/) + factorIndexList(1,:)=(/16,1,16/) + factorIndexList(2,:)=(/8,12,12/) + call ESMF_FieldSMMStore(srcField, dstField, routehandle=routehandle, & + factorList=factorList, factorIndexList=factorIndexList, rc=localrc) + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + else + call ESMF_FieldSMMStore(srcField, dstField, routehandle=routehandle, & + rc=localrc) + if (localrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + + ! 2. use precomputed routehandle to perform SMM + call ESMF_FieldSMM(srcfield, dstField, routehandle=routehandle, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ + +
+ +
+ +
+ +
+The ESMF_FieldHalo() interface can be used to perform halo updates for a Field. This + eases communication programming from a user perspective. By definition, the user + program only needs to update locally owned exclusive region in each domain, then call + FieldHalo to communicate the values in the halo region from/to neighboring domain elements. + In this example, we solve a 1D heat transfer problem: + with the + initial condition and boundary conditions +. + The temperature field + is represented by a ESMF_Field. A finite difference explicit time stepping scheme is employed. + During each time step, FieldHalo update is called to communicate values in the halo region + to neighboring domain elements. The steady state (as +) solution + is a linear temperature profile along . The numerical solution is an approximation of + the steady state solution. It can be verified to represent a linear temperature profile. + +
+Section 28.2.15 provides a discussion of the + halo operation implemented in ESMF_Array. + +
+
+! create 1D distgrid and grid decomposed according to the following diagram: +! +------------+ +----------------+ +---------------+ +--------------+ +! | DE 0 | | | | DE 1 | | | | DE 2 | | | | DE 3 | +! | 1 x 16 | | | | 1 x 16 | | | | 1 x 16 | | | | 1 x 16 | +! | | 1|<->|1 | | 1|<->|1 | | 1|<->|1 | | +! | | | | | | | | | | | | | | +! +------------+ +----------------+ +---------------+ +--------------+ + distgrid = ESMF_DistGridCreate(minIndex=(/1/), maxIndex=(/npx/), & + regDecomp=(/4/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + grid = ESMF_GridCreate(distgrid=distgrid, name="grid", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + ! set up initial condition and boundary conditions of the + ! temperature Field + if(lpe == 0) then + allocate(fptr(17), tmp_farray(17)) + fptr = 20. + fptr(1) = 10. + tmp_farray(1) = 10. + startx = 2 + endx = 16 + + field = ESMF_FieldCreate(grid, fptr, totalUWidth=(/1/), & + name="temperature", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + else if(lpe == 3) then + allocate(fptr(17), tmp_farray(17)) + fptr = 20. + fptr(17) = 40. + tmp_farray(17) = 40. + startx = 2 + endx = 16 + + field = ESMF_FieldCreate(grid, fptr, totalLWidth=(/1/), & + name="temperature", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + else + allocate(fptr(18), tmp_farray(18)) + fptr = 20. + startx = 2 + endx = 17 + + field = ESMF_FieldCreate(grid, fptr, & + totalLWidth=(/1/), totalUWidth=(/1/), name="temperature", rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + + ! compute the halo update routehandle of the decomposed temperature Field + call ESMF_FieldHaloStore(field, routehandle=routehandle, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + dt = 0.01 + dx = 1./npx + alpha = 0.1 + + ! Employ explicit time stepping + ! Solution converges after about 9000 steps based on apriori knowledge. + ! The result is a linear temperature profile stored in field. + do iter = 1, 9000 + ! only elements in the exclusive region are updated locally + ! in each domain + do i = startx, endx + tmp_farray(i) = & + fptr(i)+alpha*alpha*dt/dx/dx*(fptr(i+1)-2.*fptr(i)+fptr(i-1)) + enddo + fptr = tmp_farray + ! call halo update to communicate the values in the halo region to + ! neighboring domains + call ESMF_FieldHalo(field, routehandle=routehandle, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + enddo + + ! release the halo routehandle + call ESMF_FieldHaloRelease(routehandle, rc=rc) ++ +
+ + +
+
+
+ +
+
+
+
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + field1 = field2 +ARGUMENTS: +
type(ESMF_Field) :: field1 + type(ESMF_Field) :: field2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign field1 as an alias to the same ESMF Field object in memory + as field2. If field2 is invalid, then field1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (field1 == field2) then ... endif + OR + result = (field1 == field2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field1 + type(ESMF_Field), intent(in) :: field2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether field1 and field2 are valid aliases to the same ESMF + Field object in memory. For a more general comparison of two ESMF Fields, + going beyond the simple alias test, the ESMF_FieldMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (field1 /= field2) then ... endif + OR + result = (field1 /= field2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field1 + type(ESMF_Field), intent(in) :: field2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether field1 and field2 are not valid aliases to the + same ESMF Field object in memory. For a more general comparison of two ESMF + Fields, going beyond the simple alias test, the ESMF_FieldMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldCopy(fieldOut, fieldIn, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: fieldOut + type(ESMF_Field), intent(in) :: fieldIn + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Copy data from one ESMF_Field object to another. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateGBTKR(geom, typekind, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, & + totalLWidth, totalUWidth, pinflag, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateGBTKR +ARGUMENTS: +
type(ESMF_Geom), intent(in) :: geom + type(ESMF_TypeKind_Flag),intent(in) :: typekind + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field and allocate space internally for an + ESMF_Array. Return a new ESMF_Field. For an example and + associated documentation using this method see section + 26.3.4. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateGBArraySpec(geom, arrayspec, gridToFieldMap, & + ungriddedLBound, ungriddedUBound, totalLWidth, totalUWidth, & + pinflag, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateGBArraySpec +ARGUMENTS: +
type(ESMF_Geom) :: geom + type(ESMF_ArraySpec), intent(in) :: arrayspec + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field and allocate space internally for an + ESMF_Array. Return a new ESMF_Field. For an example and + associated documentation using this method see section + 26.3.5. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateGBArray(geom, array, datacopyflag, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, & + totalLWidth, totalUWidth, name, vm, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateGBArray +ARGUMENTS: +
type(ESMF_Geom), intent(in) :: geom + type(ESMF_Array), intent(in) :: array + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + 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 + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field. This version of creation + assumes the data exists already and is being + passed in through an ESMF_Array. For an example and + associated documentation using this method see section + 26.3.6. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateGBData<rank><type><kind>(geom, & + farray, indexflag, datacopyflag, gridToFieldMap, ungriddedLBound, & + ungriddedUBound, totalLWidth, totalUWidth, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateGBData<rank><type><kind> +ARGUMENTS: +
type(ESMF_Geom) :: geom + <type> (ESMF_KIND_<kind>), dimension(<rank>), target :: farray + type(ESMF_Index_Flag), intent(in) :: indexflag + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + 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_Field from a Fortran data array and ESMF_Geom. + The Fortran data pointer inside ESMF_Field can be queried but deallocating + the retrieved data pointer is not allowed. + The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateGBDataPtr<rank><type><kind>(geom, & + farrayPtr, datacopyflag, gridToFieldMap, & + totalLWidth, totalUWidth, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateGBDataPtr<rank><type><kind> +ARGUMENTS: +
type(ESMF_Geom) :: geom + <type> (ESMF_KIND_<kind>), dimension(<rank>), pointer :: farrayPtr + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + 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_Field from a Fortran data pointer and ESMF_Geom. + The Fortran data pointer inside ESMF_Field can be queried and deallocated when + datacopyflag is ESMF_DATACOPY_REFERENCE. Note that the ESMF_FieldDestroy call does not + deallocate the Fortran data pointer in this case. This gives user more flexibility over memory management. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateGridTKR(grid, typekind, & + indexflag, staggerloc, gridToFieldMap, ungriddedLBound, ungriddedUBound, & + totalLWidth, totalUWidth, pinflag, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateGridTKR +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + type(ESMF_TypeKind_Flag),intent(in) :: typekind + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_StaggerLoc), intent(in), optional :: staggerloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Field and allocate space internally for an + ESMF_Array. Return a new ESMF_Field. For an example and + associated documentation using this method see section + 26.3.4. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateGridArraySpec(grid, arrayspec, & + indexflag, staggerloc, gridToFieldMap, ungriddedLBound, & + ungriddedUBound, totalLWidth, totalUWidth, pinflag, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateGridArraySpec +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + type(ESMF_ArraySpec), intent(in) :: arrayspec + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_StaggerLoc), intent(in), optional :: staggerloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Field and allocate space internally for an + ESMF_Array. Return a new ESMF_Field. For an example and + associated documentation using this method see section + 26.3.5. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateGridArray(grid, array, datacopyflag, & + staggerloc, gridToFieldMap, ungriddedLBound, ungriddedUBound, & + totalLWidth, totalUWidth, name, vm, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateGridArray +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_StaggerLoc), intent(in), optional :: staggerloc + integer, intent(in), optional :: gridToFieldMap(:) + 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 + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Field. This version of creation + assumes the data exists already and is being + passed in through an ESMF_Array. For an example and + associated documentation using this method see section + 26.3.6. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateGridData<rank><type><kind>(grid, & + farray, indexflag, datacopyflag, staggerloc, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, & + totalLWidth, totalUWidth, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateGridData<rank><type><kind> +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + <type> (ESMF_KIND_<kind>),intent(in), target :: farray(<rank>) + type(ESMF_Index_Flag), intent(in) :: indexflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_StaggerLoc), intent(in), optional :: staggerloc + integer, intent(in), optional :: gridToFieldMap(:) + 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 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Field from a Fortran data array and ESMF_Grid. + The Fortran data pointer inside ESMF_Field can be queried but deallocating + the retrieved data pointer is not allowed. + For examples and + associated documentation regarding this method see section + 26.3.11, + 26.3.13, + 26.3.14, + 26.3.15, and + 26.3.9. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateGridDataPtr<rank><type><kind>(grid, & + farrayPtr, datacopyflag, staggerloc, gridToFieldMap, & + totalLWidth, totalUWidth, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateGridDataPtr<rank><type><kind> +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_StaggerLoc), intent(in), optional :: staggerloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Field from a Fortran data pointer and ESMF_Grid. + The Fortran data pointer inside ESMF_Field can be queried and deallocated when + datacopyflag is ESMF_DATACOPY_REFERENCE. Note that the ESMF_FieldDestroy call does not + deallocate the Fortran data pointer in this case. This gives user more flexibility over memory management. + +
+For examples and + associated documentation regarding this method see section + 26.3.12, + 26.3.13, + 26.3.14, + 26.3.15, and + 26.3.9. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateLSTKR(locstream, typekind, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, pinflag, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateLSTKR +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + type(ESMF_TypeKind_Flag),intent(in) :: typekind + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field and allocate space internally for an + ESMF_Array. Return a new ESMF_Field. For an example and + associated documentation using this method see section + 26.3.16. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateLSArraySpec(locstream, arrayspec, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, pinflag, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateLSArraySpec +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + type(ESMF_ArraySpec), intent(in) :: arrayspec + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field and allocate space internally for an + ESMF_Array. Return a new ESMF_Field. For an example and + associated documentation using this method see section + 26.3.17. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateLSArray(locstream, array, & + datacopyflag, gridToFieldMap, ungriddedLBound, ungriddedUBound, & + name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateLSArray +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + character (len = *), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field. This version of creation + assumes the data exists already and is being + passed in through an ESMF_Array. For an example and + associated documentation using this method see section + 26.3.6. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateLSData<rank><type><kind>(locstream, farray, & + indexflag, datacopyflag, gridToFieldMap, ungriddedLBound, & + ungriddedUBound, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateLSData<rank><type><kind> +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + <type> (ESMF_KIND_<kind>),intent(in), target :: farray(<rank>) + type(ESMF_Index_Flag), intent(in) :: indexflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field from a Fortran data array and ESMF_LocStream. + The Fortran data pointer inside ESMF_Field can be queried but deallocating + the retrieved data pointer is not allowed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateLSDataPtr<rank><type><kind>(locstream, & + farrayPtr, datacopyflag, gridToFieldMap, & + name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateLSDataPtr<rank><type><kind> +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + <type> (ESMF_KIND_<kind>),pointer :: farrayPtr(<rank>) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field from a Fortran data pointer and ESMF_LocStream. + The Fortran data pointer inside ESMF_Field can be queried and deallocated when + datacopyflag is ESMF_DATACOPY_REFERENCE. Note that the ESMF_FieldDestroy call does not + deallocate the Fortran data pointer in this case. This gives user more flexibility over memory management. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateMeshTKR(mesh, typekind, indexflag, & + meshloc, gridToFieldMap, ungriddedLBound, ungriddedUBound, & + pinflag, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateMeshTKR +ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh + type(ESMF_TypeKind_Flag), intent(in) :: typekind + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_MeshLoc), intent(in), optional :: meshloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field and allocate space internally for an + ESMF_Array. Return a new ESMF_Field. For an example and + associated documentation using this method see section + 26.3.18. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateMeshArraySpec(mesh, arrayspec, & + indexflag, meshloc, gridToFieldMap, ungriddedLBound, ungriddedUBound, & + pinflag, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateMeshArraySpec +ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh + type(ESMF_ArraySpec), intent(in) :: arrayspec + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag),intent(in), optional :: indexflag + type(ESMF_MeshLoc), intent(in), optional :: meshloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field and allocate space internally for an + ESMF_Array. Return a new ESMF_Field. For an example and + associated documentation using this method see section + 26.3.19 and + 26.3.21. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateMeshArray(mesh, array, & + datacopyflag, meshloc, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, & + name, vm, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateMeshArray +ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh + type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_MeshLoc), intent(in), optional :: meshloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + character (len = *), intent(in), optional :: name + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field. This version of creation + assumes the data exists already and is being + passed in through an ESMF_Array. For an example and + associated documentation using this method see section + 26.3.20. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateMeshData<rank><type><kind>(mesh, & + farray, indexflag, datacopyflag, meshloc, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateMeshData<rank><type><kind> +ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh + <type> (ESMF_KIND_<kind>),intent(in), target :: farray(<rank>) + type(ESMF_Index_Flag), intent(in) :: indexflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_MeshLoc), intent(in), optional :: meshloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field from a Fortran data array and ESMF_Mesh. + The Fortran data pointer inside ESMF_Field can be queried but deallocating + the retrieved data pointer is not allowed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateMeshDataPtr<rank><type><kind>(mesh, & + farrayPtr, datacopyflag, meshloc, gridToFieldMap, & + name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateMeshDataPtr<rank><type><kind> +ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh + <type> (ESMF_KIND_<kind>),pointer :: farrayPtr(<rank>) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_MeshLoc), intent(in), optional :: meshloc + integer, intent(in), optional :: gridToFieldMap(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field from a Fortran data pointer and ESMF_Mesh. + The Fortran data pointer inside ESMF_Field can be queried and deallocated when + datacopyflag is ESMF_DATACOPY_REFERENCE. Note that the ESMF_FieldDestroy call does not + deallocate the Fortran data pointer in this case. This gives user more flexibility over memory management. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateXGTKR(xgrid, typekind, xgridside, & + gridindex, gridToFieldMap, ungriddedLBound, ungriddedUBound, & + pinflag, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateXGTKR +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid + type(ESMF_TypeKind_Flag), intent(in) :: typekind + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside + integer, intent(in), optional :: gridindex + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field and allocate space internally for an + ESMF_Array. Return a new ESMF_Field. For an example and + associated documentation using this method see section + 26.3.16. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateXGArraySpec(xgrid, arrayspec, & + xgridside, gridindex, gridToFieldMap, ungriddedLBound, ungriddedUBound, & + pinflag, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateXGArraySpec +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid + type(ESMF_ArraySpec), intent(in) :: arrayspec + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridSide + integer, intent(in), optional :: gridIndex + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field and allocate space internally for an + ESMF_Array. Return a new ESMF_Field. For an example and + associated documentation using this method see section + 26.3.17. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateXGArray(xgrid, array, & + datacopyflag, xgridside, gridindex, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, & + name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateXGArray +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid + type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside + integer, intent(in), optional :: gridindex + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + character (len = *), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field. This version of creation + assumes the data exists already and is being + passed in through an ESMF_Array. For an example and + associated documentation using this method see section + 26.3.6. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateXGData<rank><type><kind>(xgrid, & + farray, indexflag, datacopyflag, xgridside, gridindex, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, name,& + rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateXGData<rank><type><kind> +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid + <type> (ESMF_KIND_<kind>), intent(in), target :: farray(<rank>) + type(ESMF_Index_Flag), intent(in) :: indexflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside + integer, intent(in), optional :: gridindex + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field from a Fortran data array and ESMF_Xgrid. + The Fortran data pointer inside ESMF_Field can be queried but deallocating + the retrieved data pointer is not allowed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateXGDataPtr<rank><type><kind>(xgrid, farrayPtr, & + datacopyflag, xgridside, & + gridindex, gridToFieldMap, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateXGDataPtr<rank><type><kind> +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside + integer, intent(in), optional :: gridindex + integer, intent(in), optional :: gridToFieldMap(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field from a Fortran data pointer and ESMF_Xgrid. + The Fortran data pointer inside ESMF_Field can be queried and deallocated when + datacopyflag is ESMF_DATACOPY_REFERENCE. Note that the ESMF_FieldDestroy call does not + deallocate the Fortran data pointer in this case. This gives user more flexibility over memory management. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldCreate() + function ESMF_FieldCreateFromField(field, datacopyflag, & + trailingUngridSlice, name, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldCreateFromField +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: trailingUngridSlice(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Field object from an existing Field. + +
+The return value is the newly created ESMF_Field object. Supports array + slicing. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldDestroy(field, noGarbage, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroys the ESMF_Field, releasing the resources associated with + the object. + +
+If an ESMF_Grid is associated with field, it will not be + released. + +
+By default a small remnant of the object is kept in memory in order to + prevent problems with dangling aliases. The default garbage collection + mechanism can be overridden with the noGarbage argument. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompAS(field, arrayspec, indexflag, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, totalLWidth, totalUWidth, & + pinflag, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_ArraySpec), intent(in) :: arrayspec + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Complete an ESMF_Field and allocate space internally for an + ESMF_Array based on arrayspec. + The input ESMF_Field must have a status of + ESMF_FIELDSTATUS_GRIDSET. After this call the completed ESMF_Field + has a status of ESMF_FIELDSTATUS_COMPLETE. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompTK(field, typekind, indexflag, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, totalLWidth, totalUWidth, & + pinflag, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_TypeKind_Flag), intent(in) :: typekind + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Complete an ESMF_Field and allocate space internally for an + ESMF_Array based on typekind. + The input ESMF_Field must have a status of + ESMF_FIELDSTATUS_GRIDSET. After this call the completed ESMF_Field + has a status of ESMF_FIELDSTATUS_COMPLETE. + +
+For an example and + associated documentation using this method see section + 26.3.7. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyComp<rank><type><kind>(field, & + farray, indexflag, datacopyflag, gridToFieldMap, & + ungriddedLBound, ungriddedUBound, totalLWidth, totalUWidth, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + <type> (ESMF_KIND_<kind>),intent(in), target :: farray(<rank>) + type(ESMF_Index_Flag), intent(in) :: indexflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Complete an ESMF_Field and allocate space internally for an + ESMF_Array based on typekind. + The input ESMF_Field must have a status of + ESMF_FIELDSTATUS_GRIDSET. After this call the completed ESMF_Field + has a status of ESMF_FIELDSTATUS_COMPLETE. + +
+The Fortran data pointer inside ESMF_Field can be queried but deallocating + the retrieved data pointer is not allowed. + +
+For an example and + associated documentation using this method see section + 26.3.8. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompPtr<rank><type><kind>(field, & + farrayPtr, datacopyflag, gridToFieldMap, & + totalLWidth, totalUWidth, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Complete an ESMF_Field and allocate space internally for an + ESMF_Array based on typekind. + The input ESMF_Field must have a status of + ESMF_FIELDSTATUS_GRIDSET. After this call the completed ESMF_Field + has a status of ESMF_FIELDSTATUS_COMPLETE. + +
+The Fortran data pointer inside ESMF_Field can be queried and deallocated when + datacopyflag is ESMF_DATACOPY_REFERENCE. Note that the ESMF_FieldDestroy call does not deallocate + the Fortran data pointer in this case. This gives user more flexibility over memory management. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompGB<rank><type><kind>(field, geom, & + farray, indexflag, datacopyflag, gridToFieldMap, ungriddedLBound, & + ungriddedUBound, totalLWidth, totalUWidth, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_Geom), intent(in) :: geom + <type> (ESMF_KIND_<kind>), dimension(<rank>), target :: farray + type(ESMF_Index_Flag), intent(in) :: indexflag + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call completes an ESMF_Field allocated with the + ESMF_FieldEmptyCreate() call. For an example and + associated documentation using this method see section + 26.3.7. + +
+The Fortran data pointer inside ESMF_Field can be queried but deallocating + the retrieved data pointer is not allowed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompGBPtr<rank><type><kind>(field, geom, & + farrayPtr, datacopyflag, gridToFieldMap, & + totalLWidth, totalUWidth, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inou) :: field + type(ESMF_Geom), intent(in) :: geom + <type> (ESMF_KIND_<kind>), dimension(<rank>), pointer :: farrayPtr + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call completes an ESMF_Field allocated with the + ESMF_FieldEmptyCreate() call. For an example and + associated documentation using this method see section + 26.3.7. + +
+The Fortran data pointer inside ESMF_Field can be queried and deallocated when + datacopyflag is ESMF_DATACOPY_REFERENCE. Note that the ESMF_FieldDestroy call does not deallocate + the Fortran data pointer in this case. This gives user more flexibility over memory management. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompGrid<rank><type><kind>(field, grid, & + farray, indexflag, datacopyflag, staggerloc, gridToFieldMap, & + ungriddedLBound, ungriddedUBound, totalLWidth, totalUWidth, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_Grid), intent(in) :: grid + <type> (ESMF_KIND_<kind>),intent(in), target :: farray(<rank>) + type(ESMF_Index_Flag), intent(in) :: indexflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_STAGGERLOC), intent(in), optional :: staggerloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This call completes an ESMF_Field allocated with the + ESMF_FieldEmptyCreate() call. + +
+The Fortran data pointer inside ESMF_Field can be queried but deallocating + the retrieved data pointer is not allowed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompGridPtr<rank><type><kind>(field, grid, & + farrayPtr, datacopyflag, staggerloc, gridToFieldMap, & + totalLWidth, totalUWidth, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_Grid), intent(in) :: grid + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_STAGGERLOC), intent(in), optional :: staggerloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This call completes an ESMF_Field allocated with the + ESMF_FieldEmptyCreate() call. + +
+The Fortran data pointer inside ESMF_Field can be queried and deallocated when + datacopyflag is ESMF_DATACOPY_REFERENCE. Note that the ESMF_FieldDestroy call does not deallocate + the Fortran data pointer in this case. This gives user more flexibility over memory management. + + The Fortran data pointer inside ESMF_Field can be queried and deallocated when + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompLS<rank><type><kind>(field, locstream, & + farray, indexflag, datacopyflag, gridToFieldMap, & + ungriddedLBound, ungriddedUBound, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_LocStream), intent(in) :: locstream + <type> (ESMF_KIND_<kind>), intent(in), target :: farray(<rank>) + type(ESMF_Index_Flag), intent(in) :: indexflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call completes an ESMF_Field allocated with the + ESMF_FieldEmptyCreate() call. + +
+The Fortran data pointer inside ESMF_Field can be queried but deallocating + the retrieved data pointer is not allowed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompLSPtr<rank><type><kind>(field, locstream, & + farrayPtr, datacopyflag, gridToFieldMap, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_LocStream), intent(in) :: locstream + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call completes an ESMF_Field allocated with the + ESMF_FieldEmptyCreate() call. + +
+The Fortran data pointer inside ESMF_Field can be queried and deallocated when + datacopyflag is ESMF_DATACOPY_REFERENCE. Note that the ESMF_FieldDestroy call does not deallocate + the Fortran data pointer in this case. This gives user more flexibility over memory management. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompMesh<rank><type><kind>(field, mesh, & + farray, indexflag, datacopyflag, meshloc, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_Mesh), intent(in) :: mesh + <type> (ESMF_KIND_<kind>), intent(in), target :: farray(<rank>) + type(ESMF_Index_Flag), intent(in) :: indexflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_MeshLoc), intent(in), optional :: meshloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call completes an ESMF_Field allocated with the + ESMF_FieldEmptyCreate() call. + +
+The Fortran data pointer inside ESMF_Field can be queried but deallocating + the retrieved data pointer is not allowed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompMeshPtr<rank><type><kind>(field, mesh, & + farrayPtr, datacopyflag, meshloc, gridToFieldMap, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_Mesh), intent(in) :: mesh + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_MeshLoc), intent(in), optional :: meshloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call completes an ESMF_Field allocated with the + ESMF_FieldEmptyCreate() call. + +
+The Fortran data pointer inside ESMF_Field can be queried and deallocated when + datacopyflag is ESMF_DATACOPY_REFERENCE. Note that the ESMF_FieldDestroy call does not deallocate + the Fortran data pointer in this case. This gives user more flexibility over memory management. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompXG<rank><type><kind>(field, xgrid, & + farray, indexflag, datacopyflag, xgridside, gridindex, & + gridToFieldMap, & + ungriddedLBound, ungriddedUBound, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_XGrid), intent(in) :: xgrid + <type> (ESMF_KIND_<kind>), intent(in), target :: farray(<rank>) + type(ESMF_Index_Flag), intent(in) :: indexflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside + integer, intent(in), optional :: gridindex + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call completes an ESMF_Field allocated with the + ESMF_FieldEmptyCreate() call. + +
+The Fortran data pointer inside ESMF_Field can be queried but deallocating + the retrieved data pointer is not allowed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptyComplete() + subroutine ESMF_FieldEmptyCompXGPtr<rank><type><kind>(field, xgrid, & + farrayPtr, xgridside, gridindex, & + datacopyflag, gridToFieldMap, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_XGrid), intent(in) :: xgrid + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside + integer, intent(in), optional :: gridindex + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call completes an ESMF_Field allocated with the + ESMF_FieldEmptyCreate() call. + +
+The Fortran data pointer inside ESMF_Field can be queried and deallocated when + datacopyflag is ESMF_DATACOPY_REFERENCE. Note that the ESMF_FieldDestroy call does not deallocate + the Fortran data pointer in this case. This gives user more flexibility over memory management. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_FieldEmptyCreate(name, vm, rc) +RETURN VALUE: +
type(ESMF_Field) :: ESMF_FieldEmptyCreate +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len = *), intent(in), optional :: name + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This version of ESMF_FieldCreate builds an empty ESMF_Field + and depends on later calls to add an ESMF_Grid and ESMF_Array to + it. The empty ESMF_Field can be completed in one more step or two more steps by + the ESMF_FieldEmptySet and ESMF_FieldEmptyComplete methods. + Attributes can be added to an empty Field object. For an example and + associated documentation using this method see section + 26.3.8 and 26.3.7. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptySet() + subroutine ESMF_FieldEmptySetGeom(field, geom, vm, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_Geom), intent(in) :: geom + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set a geom in a non-completed ESMF_Field. The + ESMF_Field must not be completed for this to succeed. After this + operation, the ESMF_Field contains + the ESMF_Geom internally but holds no data. + The status of the field changes from + ESMF_FIELDSTATUS_EMPTY to ESMF_FIELDSTATUS_GRIDSET or + stays ESMF_FIELDSTATUS_GRIDSET. + +
+For an example and + associated documentation using this method see section + 26.3.7. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptySet() + subroutine ESMF_FieldEmptySetGrid(field, grid, StaggerLoc, & + vm, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_Grid), intent(in) :: grid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_STAGGERLOC), intent(in), optional :: StaggerLoc + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Set a grid and an optional staggerloc (default to center stagger + ESMF_STAGGERLOC_CENTER) in a non-completed ESMF_Field. The + ESMF_Field must not be completed for this to succeed. After this + operation, the ESMF_Field contains + the ESMF_Grid internally but holds no data. + The status of the field changes from + ESMF_FIELDSTATUS_EMPTY to ESMF_FIELDSTATUS_GRIDSET or + stays ESMF_FIELDSTATUS_GRIDSET. + +
+For an example and + associated documentation using this method see section + 26.3.7. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptySet() + subroutine ESMF_FieldEmptySetMesh(field, mesh, indexflag, meshloc, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_Mesh), intent(in) :: mesh + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag),intent(in), optional :: indexflag + type(ESMF_MeshLoc), intent(in), optional :: meshloc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set a mesh and an optional meshloc (default to center stagger + ESMF_MESHLOC_NODE) in a non-completed ESMF_Field. The + ESMF_Field must not be completed for this to succeed. After this + operation, the ESMF_Field contains + the ESMF_Mesh internally but holds no data. + The status of the field changes from + ESMF_FIELDSTATUS_EMPTY to ESMF_FIELDSTATUS_GRIDSET or + stays ESMF_FIELDSTATUS_GRIDSET. + +
+ +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptySet() + subroutine ESMF_FieldEmptySetLocStream(field, locstream, & + vm, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_LocStream), intent(in) :: locstream + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set a ESMF_LocStream in a non-completed ESMF_Field. The + ESMF_Field must not be completed for this to succeed. After this + operation, the ESMF_Field contains + the ESMF_LocStream internally but holds no data. + The status of the field changes from + ESMF_FIELDSTATUS_EMPTY to ESMF_FIELDSTATUS_GRIDSET or + stays ESMF_FIELDSTATUS_GRIDSET. + +
+ +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldEmptySet() + subroutine ESMF_FieldEmptySetXGrid(field, xgrid, xgridside, gridindex, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_XGrid), intent(in) :: xgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside + integer, intent(in), optional :: gridindex + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set a xgrid and optional xgridside (default to balanced side + ESMF_XGRIDSIDE_Balanced) and gridindex (default to 1) + in a non-complete ESMF_Field. The + ESMF_Field must not be completed for this to succeed. After this + operation, the ESMF_Field contains + the ESMF_XGrid internally but holds no data. + The status of the field changes from + ESMF_FIELDSTATUS_EMPTY to ESMF_FIELDSTATUS_GRIDSET + or stays ESMF_FIELDSTATUS_GRIDSET. + +
+ +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldFill(field, dataFillScheme, & + const1, member, step, & + param1I4, param2I4, param3I4, & + param1R4, param2R4, param3R4, & + param1R8, param2R8, param3R8, & + rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: dataFillScheme + real(ESMF_KIND_R8), intent(in), optional :: const1 + integer, intent(in), optional :: member + integer, intent(in), optional :: step + integer(ESMF_KIND_I4), intent(in), optional :: param1I4 + integer(ESMF_KIND_I4), intent(in), optional :: param2I4 + integer(ESMF_KIND_I4), intent(in), optional :: param3I4 + real(ESMF_KIND_R4), intent(in), optional :: param1R4 + real(ESMF_KIND_R4), intent(in), optional :: param2R4 + real(ESMF_KIND_R4), intent(in), optional :: param3R4 + real(ESMF_KIND_R8), intent(in), optional :: param1R8 + real(ESMF_KIND_R8), intent(in), optional :: param2R8 + real(ESMF_KIND_R8), intent(in), optional :: param3R8 + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Fill field with data according to dataFillScheme. Depending + on the chosen fill scheme, the member and step arguments are + used to provide differing fill data patterns. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldGather<rank><type><kind>(field, farray, & + rootPet, tile, vm, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + <type>(ESMF_KIND_<kind>), intent(out), target :: farray(<rank>) + integer, intent(in) :: rootPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: tile + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gather the data of an ESMF_Field object into the farray located on + rootPET. A single DistGrid tile of array must be + gathered into farray. The optional tile + argument allows selection of the tile. For Fields defined on a single + tile DistGrid the default selection (tile 1) will be correct. The + shape of farray must match the shape of the tile in Field. + +
+If the Field contains replicating DistGrid dimensions data will be + gathered from the numerically higher DEs. Replicated data elements in + numericaly lower DEs will be ignored. + +
+The implementation of Scatter and Gather is not sequence index based. + If the Field is built on arbitrarily distributed Grid, Mesh, LocStream or XGrid, + Gather will not gather data to rootPet + from source data points corresponding to the sequence index on rootPet. + Instead Gather will gather a contiguous memory range from source PET to + rootPet. The size of the memory range is equal to the number of + data elements on the source PET. Vice versa for the Scatter operation. + In this case, the user should use ESMF_FieldRedist to achieve + the same data operation result. For examples how to use ESMF_FieldRedist + to perform Gather and Scatter, please refer to + 26.3.32 and + 26.3.31. + +
+This version of the interface implements the PET-based blocking paradigm: + Each PET of the VM must issue this call exactly once for all of its + DEs. The call will block until all PET-local data objects are accessible. + +
+For examples and associated documentation regarding this method see Section + 26.3.28. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldGet() + subroutine ESMF_FieldGetDefault(field, arrayspec, status, & + geomtype, geom, grid, mesh, locstream, xgrid, array, localarrayList, & + typekind, rank, dimCount, geomDimCount, ungriddedDimCount, & + replicatedDimCount, staggerloc, meshloc, xgridside, gridindex, & + gridToFieldMap, ungriddedLBound, ungriddedUBound, & + totalLWidth, totalUWidth, localDeCount, ssiLocalDeCount, & + localDeToDeMap, minIndex, maxIndex, elementCount, & + localMinIndex, localMaxIndex, localElementCount, isESMFAllocated, & + name, vm, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_ArraySpec), intent(out), optional :: arrayspec + type(ESMF_FieldStatus_Flag),intent(out), optional :: status + type(ESMF_GeomType_Flag), intent(out), optional :: geomtype + type(ESMF_Geom), intent(out), optional :: geom + type(ESMF_Grid), intent(out), optional :: grid + type(ESMF_Mesh), intent(out), optional :: mesh + type(ESMF_LocStream), intent(out), optional :: locstream + type(ESMF_XGrid), intent(out), optional :: xgrid + type(ESMF_Array), intent(out), optional :: array + type(ESMF_LocalArray), target, intent(out), optional :: localarrayList(:) + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: rank + integer, intent(out), optional :: dimCount + integer, intent(out), optional :: geomDimCount + integer, intent(out), optional :: ungriddedDimCount + integer, intent(out), optional :: replicatedDimCount + type(ESMF_StaggerLoc), intent(out), optional :: staggerloc + type(ESMF_MeshLoc), intent(out), optional :: meshloc + type(ESMF_XGridSide_Flag), intent(out), optional :: xgridside + integer, intent(out), optional :: gridindex + integer, intent(out), optional :: gridToFieldMap(:) + integer, intent(out), optional :: ungriddedLBound(:) + integer, intent(out), optional :: ungriddedUBound(:) + integer, intent(out), optional :: totalLWidth(:,:) + integer, intent(out), optional :: totalUWidth(:,:) + integer, intent(out), optional :: localDeCount + integer, intent(out), optional :: ssiLocalDeCount + integer, intent(out), optional :: localDeToDeMap(:) + integer, intent(out), optional :: minIndex(:) + integer, intent(out), optional :: maxIndex(:) + integer, intent(out), optional :: elementCount(:) + integer, intent(out), optional :: localMinIndex(:) + integer, intent(out), optional :: localMaxIndex(:) + integer, intent(out), optional :: localElementCount(:) + logical, intent(out), optional :: isESMFAllocated + character(len=*), intent(out), optional :: name + type(ESMF_VM), intent(out), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Query an ESMF_Field object for various pieces of information. + All arguments after the field argument are optional. To select + individual items use the named_argument=value syntax. For an example + and associated documentation using this method see section + 26.3.3. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldGet() + subroutine ESMF_FieldGetDataPtr<rank><type><kind>(field, localDe, & + farrayPtr, exclusiveLBound, exclusiveUBound, exclusiveCount, & + computationalLBound, computationalUBound, computationalCount, & + totalLBound, totalUBound, totalCount, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: localDe + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + 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(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get a Fortran pointer to DE-local memory allocation within field. + For convenience DE-local bounds can be queried at the same time. + For an example and + associated documentation using this method see section + 26.3.2. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldGetBounds() + subroutine ESMF_FieldGetBounds(field, localDe, & + exclusiveLBound, exclusiveUBound, exclusiveCount, computationalLBound, & + computationalUBound, computationalCount, totalLBound, & + totalUBound, totalCount, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: localDe + 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(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This method returns the bounds information of a field that consists of a + internal grid and a internal array. The exclusive and computational bounds + are shared between the grid and the array but the total bounds are the array + bounds plus the halo width. The count is the number of elements between each + bound pair. + +
+The arguments are: +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldHalo(field, routehandle, & + routesyncflag, finishedflag, checkflag, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_RouteSync_Flag), intent(in), optional :: routesyncflag + logical, intent(out), optional :: finishedflag + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed Field halo operation for field. + The field argument must match the Field used during + ESMF_FieldHaloStore() in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+See ESMF_FieldHaloStore() on how to precompute routehandle. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldHaloRelease(routehandle, noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with a Field halo operation. + After this call routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldHaloStore(field, routehandle, & + startregion, haloLDepth, haloUDepth, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_StartRegion_Flag), intent(in), optional :: startregion + integer, intent(in), optional :: haloLDepth(:) + integer, intent(in), optional :: haloUDepth(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store a Field halo operation over the data in field. By default, + i.e. without specifying startregion, haloLDepth and + haloUDepth, all elements in the total Field region that lie outside + the exclusive region will be considered potential destination elements for + halo. However, only those elements that have a corresponding halo source + element, i.e. an exclusive element on one of the DEs, will be updated under + the halo operation. Elements that have no associated source remain + unchanged under halo. + +
+Specifying startregion allows to change the shape of the + effective halo region from the inside. Setting this flag to + ESMF_STARTREGION_COMPUTATIONAL means that only elements outside + the computational region of the Field are considered for potential + destination elements for the halo operation. The default is ESMF_STARTREGION_EXCLUSIVE. + +
+The haloLDepth and haloUDepth arguments allow to reduce + the extent of the effective halo region. Starting at the region specified + by startregion, the haloLDepth and haloUDepth + define a halo depth in each direction. Note that the maximum halo region is + limited by the total Field region, independent of the actual + haloLDepth and haloUDepth setting. The total Field region is + local DE specific. The haloLDepth and haloUDepth are interpreted + as the maximum desired extent, reducing the potentially larger region + available for the halo operation. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldHalo() on any Field that matches + field in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_FieldIsCreated(field, rc) +RETURN VALUE: +
logical :: ESMF_FieldIsCreated +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the field has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldLog(field, prefix, logMsgFlag, deepFlag, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: prefix + type(ESMF_LogMsg_Flag), intent(in), optional :: logMsgFlag + logical, intent(in), optional :: deepFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write information about field to the ESMF default Log. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldPrint(field, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Prints information about the field to stdout. + This subroutine goes through the internal data members of a field + data type and prints information of each data member. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldRead(field, fileName, & + variableName, timeslice, iofmt, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + character(*), intent(in) :: fileName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 ESMF_PIO + should be set to either "internal" or "external" when the ESMF library is built. + Please see the section on Data I/O, 38.2. + +
+Limitations: + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldRedist(srcField, dstField, routehandle, & + checkflag, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in),optional :: srcField + type(ESMF_Field), intent(inout),optional :: dstField + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed Field redistribution from srcField to + dstField. + Both srcField and dstField must match the respective Fields + used during ESMF_FieldRedistStore() in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+The srcField and dstField arguments are optional in support of + the situation where srcField and/or dstField are not defined on + all PETs. The srcField and dstField must be specified on those + PETs that hold source or destination DEs, respectively, but may be omitted + on all other PETs. PETs that hold neither source nor destination DEs may + omit both arguments. + +
+It is erroneous to specify the identical Field object for srcField and + dstField arguments. + +
+See ESMF_FieldRedistStore() on how to precompute + routehandle. + +
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 26.3.30. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldRedistRelease(routehandle, noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with a Field redistribution. After this call + routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldRedistStore() + subroutine ESMF_FieldRedistStore<type><kind>(srcField, dstField, & + routehandle, factor, srcToDstTransposeMap, & + ignoreUnmatchedIndices, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: srcField + type(ESMF_Field), intent(inout) :: dstField + type(ESMF_RouteHandle), intent(inout) :: routehandle + <type>(ESMF_KIND_<kind>), intent(in) :: factor + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: srcToDstTransposeMap(:) + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+ ESMF_FieldRedistStore() is a collective method across all PETs of the + current Component. The interface of the method is overloaded, allowing + - in principle - each PET to call into ESMF_FieldRedistStore() + through a different entry point. Restrictions apply as to which combinations + are sensible. All other combinations result in ESMF run time errors. The + complete semantics of the ESMF_FieldRedistStore() method, as provided + through the separate entry points shown in 26.6.66 and + 26.6.67, is described in the following paragraphs as a whole. + +
+Store a Field redistribution operation from srcField to dstField. + Interface 26.6.66 allows PETs to specify a factor + argument. PETs not specifying a factor argument call into interface + 26.6.67. If multiple PETs specify the factor argument, + its type and kind, as well as its value must match across all PETs. If none + of the PETs specify a factor argument the default will be a factor of + 1. The resulting factor is applied to all of the source data during + redistribution, allowing scaling of the data, e.g. for unit transformation. + +
+Both srcField and dstField are interpreted as sequentialized + vectors. The sequence is defined by the order of DistGrid dimensions and the + order of tiles within the DistGrid or by user-supplied arbitrary sequence + indices. See section 28.2.18 for details on the definition + of sequence indices. + +
+Source Field, destination Field, and the factor may be of different + <type><kind>. Further, source and destination Fields may differ in shape, + however, the number of elements must match. + +
+The default redistribution operation, when srcToDstTransposeMap is not + specified, corresponds to the identity mapping: each element of the + sequentialized source Field is copied to the sequentialized + destination Field element in order. + +
+If the srcToDstTransposeMap argument is provided it must be identical + across all PETs. The srcToDstTransposeMap allows source and destination + Field dimensions to be transposed during the redistribution. To support this + option, the number of source and destination Field dimensions must be equal + and the size of the associated dimensions must match. + See section 28.2.17 for more details about the + use of the srcToDstTransposeMap argument. + +
+It is erroneous to specify the identical Field object for srcField and + dstField arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldRedist() on any pair of Fields that matches + srcField and dstField in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 26.3.30. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldRedistStore() + subroutine ESMF_FieldRedistStoreNF(srcField, dstField, & + routehandle, srcToDstTransposeMap, & + ignoreUnmatchedIndices, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: srcField + type(ESMF_Field), intent(inout) :: dstField + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: srcToDstTransposeMap(:) + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+ ESMF_FieldRedistStore() is a collective method across all PETs of the + current Component. The interface of the method is overloaded, allowing + - in principle - each PET to call into ESMF_FieldRedistStore() + through a different entry point. Restrictions apply as to which combinations + are sensible. All other combinations result in ESMF run time errors. The + complete semantics of the ESMF_FieldRedistStore() method, as provided + through the separate entry points shown in 26.6.66 and + 26.6.67, is described in the following paragraphs as a whole. + +
+Store a Field redistribution operation from srcField to dstField. + Interface 26.6.66 allows PETs to specify a factor + argument. PETs not specifying a factor argument call into interface + 26.6.67. If multiple PETs specify the factor argument, + its type and kind, as well as its value must match across all PETs. If none + of the PETs specify a factor argument the default will be a factor of + 1. The resulting factor is applied to all of the source data during + redistribution, allowing scaling of the data, e.g. for unit transformation. + +
+Both srcField and dstField are interpreted as sequentialized + vectors. The sequence is defined by the order of DistGrid dimensions and the + order of tiles within the DistGrid or by user-supplied arbitrary sequence + indices. See section 28.2.18 for details on the definition + of sequence indices. + +
+Source Field, destination Field, and the factor may be of different + <type><kind>. Further, source and destination Fields may differ in shape, + however, the number of elements must match. + +
+The default redistribution operation, when srcToDstTransposeMap is not + specified, corresponds to the identity mapping: each element of the + sequentialized source Field is copied to the sequentialized + destination Field element in order. + +
+If the srcToDstTransposeMap argument is provided it must be identical + across all PETs. The srcToDstTransposeMap allows source and destination + Field dimensions to be transposed during the redistribution. To support this + option, the number of source and destination Field dimensions must be equal + and the size of the associated dimensions must match. + See section 28.2.17 for more details about the + use of the srcToDstTransposeMap argument. + +
+It is erroneous to specify the identical Field object for srcField and + dstField arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldRedist() on any pair of Fields that matches + srcField and dstField in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 26.3.30. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldRegrid(srcField, dstField, routehandle, & + zeroregion, termorderflag, checkflag, dynamicMask, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in), optional :: srcField + type(ESMF_Field), intent(inout), optional :: dstField + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Region_Flag), intent(in), optional :: zeroregion + type(ESMF_TermOrder_Flag), intent(in), optional :: termorderflag + logical, intent(in), optional :: checkflag + type(ESMF_DynamicMask), target, intent(in), optional :: dynamicMask + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute the precomputed regrid operation stored in routehandle to + interpolate from srcField to dstField. See ESMF_FieldRegridStore() on how to + precompute the routehandle. + +
+Both srcField and dstField must match the respective Fields + used during ESMF_FieldRegridStore() in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+The srcField and dstField arguments are optional in support of + the situation where srcField and/or dstField are not defined on + all PETs. The srcField and dstField must be specified on those + PETs that hold source or destination DEs, respectively, but may be omitted + on all other PETs. PETs that hold neither source nor destination DEs may + omit both arguments. + +
+It is erroneous to specify the identical Field object for srcField and + dstField arguments. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldRegridRelease(routehandle, & + noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with a regrid operation. After this call + routehandle becomes invalid. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldRegridStore() + subroutine ESMF_FieldRegridStoreNX(srcField, dstField, & + srcMaskValues, dstMaskValues, & + regridmethod, & + polemethod, regridPoleNPnts, & + lineType, & + normType, & + vectorRegrid, & + extrapMethod, & + extrapNumSrcPnts, & + extrapDistExponent, & + extrapNumLevels, & + unmappedaction, ignoreDegenerate, & + srcTermProcessing, & + pipeLineDepth, & + routehandle, & + factorList, factorIndexList, & + weights, indices, & ! DEPRECATED ARGUMENTS + transposeRoutehandle, & + srcFracField, dstFracField, & + dstStatusField, & + unmappedDstList, & + checkFlag, & + rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: srcField + type(ESMF_Field), intent(inout) :: dstField + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(in), optional :: srcMaskValues(:) + integer(ESMF_KIND_I4), intent(in), optional :: dstMaskValues(:) + type(ESMF_RegridMethod_Flag), intent(in), optional :: regridmethod + type(ESMF_PoleMethod_Flag), intent(in), optional :: polemethod + integer, intent(in), optional :: regridPoleNPnts + type(ESMF_LineType_Flag), intent(in), optional :: lineType + type(ESMF_NormType_Flag), intent(in), optional :: normType + logical, intent(in), optional :: vectorRegrid + type(ESMF_ExtrapMethod_Flag), intent(in), optional :: extrapMethod + integer, intent(in), optional :: extrapNumSrcPnts + real(ESMF_KIND_R4), intent(in), optional :: extrapDistExponent + integer, intent(in), optional :: extrapNumLevels + type(ESMF_UnmappedAction_Flag), intent(in), optional :: unmappedaction + logical, intent(in), optional :: ignoreDegenerate + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipeLineDepth + type(ESMF_RouteHandle), intent(inout), optional :: routehandle + real(ESMF_KIND_R8), pointer, optional :: factorList(:) + integer(ESMF_KIND_I4), pointer, optional :: factorIndexList(:,:) + real(ESMF_KIND_R8), pointer, optional :: weights(:) ! DEPRECATED ARG + integer(ESMF_KIND_I4), pointer, optional :: indices(:,:) ! DEPRECATED ARG + type(ESMF_RouteHandle), intent(inout), optional :: transposeRoutehandle + type(ESMF_Field), intent(inout), optional :: srcFracField + type(ESMF_Field), intent(inout), optional :: dstFracField + type(ESMF_Field), intent(inout), optional :: dstStatusField + integer(ESMF_KIND_I4), pointer, optional :: unmappedDstList(:) + logical, intent(in), optional :: checkFlag + integer, intent(out), optional :: rc ++STATUS: + +
+Added arguments extrapMethod, extrapNumSrcPnts, and + extrapDistExponent. These three new extrapolation arguments allow the + user to extrapolate destination points not mapped by the regrid method. + extrapMethod allows the user to choose the extrapolation method. + extrapNumSrcPnts and extrapDistExponent are parameters that + allow the user to tune the behavior of the ESMF_EXTRAPMETHOD_NEAREST_IDAVG + method. + +
+
+
+
+
+DESCRIPTION:
+
+
+
+Creates a sparse matrix operation (stored in routehandle) that + contains the calculations and communications necessary to interpolate + from srcField to dstField. The routehandle can then be + used in the call ESMF_FieldRegrid() to interpolate between the + Fields. The user may also get the interpolation matrix in sparse + matrix form via the optional arguments factorList and factorIndexList. + +
+The routehandle generated by this call is based just on the + coordinates in the spatial class (e.g. Grid) contained in the Fields. If those + coordinates don't change the routehandle can + be used repeatedly to interpolate from the source Field to the + destination Field. This is true even if the data in the Fields + changes. The routehandle may also be used to interpolate between any + source and destination Field which are created on the same location + in the same Grid, LocStream, XGrid, or Mesh as the original Fields. + +
+When it's no longer needed the routehandle should be destroyed by + using ESMF_FieldRegridRelease() to free the memory it's using. + +
+Note, as a side effect, that this call may change the data in dstField. If + this is undesirable, then an easy work around is to create a second temporary field + with the same structure as dstField and pass that in instead. + +
+The arguments are: +
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_FieldRegridStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_FieldRegridStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldRegridStore() + subroutine ESMF_FieldRegridStoreX(xgrid, srcField, dstField, & + regridmethod, & + srcTermProcessing, pipeLineDepth, & + routehandle, & + srcFracField, dstFracField, & + srcMergeFracField, dstMergeFracField, rc) +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid + type(ESMF_Field), intent(in) :: srcField + type(ESMF_Field), intent(inout) :: dstField + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_RegridMethod_Flag), intent(in), optional :: regridmethod + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipeLineDepth + type(ESMF_RouteHandle), intent(inout), optional :: routehandle + type(ESMF_Field), intent(inout), optional :: srcFracField + type(ESMF_Field), intent(inout), optional :: dstFracField + type(ESMF_Field), intent(inout), optional :: srcMergeFracField + type(ESMF_Field), intent(inout), optional :: dstMergeFracField + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This method creates a RouteHandle to do conservative interpolation specifically between a + Field built on an XGrid and a Field build on one of the Grids or Meshes used to create that XGrid. + (To do more general interpolation use the ESMF_FieldRegridStore() method + in section 26.6.70.) The RouteHandle produced by this method can then be used in the call + ESMF_FieldRegrid() to interpolate from the srcField to the dstField. + +
+The RouteHandle generated by this call is based just on the + coordinates in the Grids, XGrids, or Meshes contained in the Fields. If those + coordinates don't change the RouteHandle can + be used repeatedly to interpolate from the source Field to the + destination Field. This is true even if the data in the Fields + changes. The RouteHandle may also be used to interpolate between any + source and destination Field which are created + on the same Grid, XGrid, or Mesh as the original Fields. + +
+When it's no longer needed the RouteHandle should be destroyed by + using ESMF_FieldRegridRelease() to free the memory it's using. + +
+Note, as a side effect, that this call may change the data in dstField. If + this is undesirable, then an easy work around is to create a second temporary Field + with the same structure as dstField and pass that in instead. + +
+The arguments are: +
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_FieldRegridStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_FieldRegridStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldRegridGetArea(areaField, rc) +RETURN VALUE: +
+ARGUMENTS: +
type(ESMF_Field), intent(inout) :: areaField + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This subroutine gets the area of the cells used for conservative interpolation for the grid object + associated with areaField and puts them into areaField. If created on a 2D Grid, it must + be built on the ESMF_STAGGERLOC_CENTER stagger location. + If created on a 3D Grid, it must be built on the ESMF_STAGGERLOC_CENTER_VCENTER stagger + location. If created on a Mesh, it must be built on the ESMF_MESHLOC_ELEMENT mesh location. + +
+If the user has set the area in the Grid, Mesh, or XGrid under areaField, then that's the area that's + returned in the units that the user set it in. If the user hasn't set the area, then the area is + calculated and returned. If the Grid, Mesh, or XGrid is on the surface of a sphere, then the calculated area is in + units of square radians. If the Grid, Mesh, or XGrid is + Cartesian, then the calculated area is in square units of whatever unit the coordinates are in. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldScatter<rank><type><kind>(field, farray, & + rootPet, tile, vm, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + mtype (ESMF_KIND_mtypekind),intent(in), target :: farray(mdim) + integer, intent(in) :: rootPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: tile + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Scatter the data of farray located on rootPET + across an ESMF_Field object. A single farray must be + scattered across a single DistGrid tile in Field. The optional tile + argument allows selection of the tile. For Fields defined on a single + tile DistGrid the default selection (tile 1) will be correct. The + shape of farray must match the shape of the tile in Field. + +
+If the Field contains replicating DistGrid dimensions data will be + scattered across all of the replicated pieces. + +
+The implementation of Scatter and Gather is not sequence index based. + If the Field is built on arbitrarily distributed Grid, Mesh, LocStream or XGrid, + Scatter will not scatter data from rootPet + to the destination data points corresponding to the sequence index on the rootPet. + Instead Scatter will scatter a contiguous memory range from rootPet to + destination PET. The size of the memory range is equal to the number of + data elements on the destination PET. Vice versa for the Gather operation. + In this case, the user should use ESMF_FieldRedist to achieve + the same data operation result. For examples how to use ESMF_FieldRedist + to perform Gather and Scatter, please refer to + 26.3.32 and + 26.3.31. + +
+This version of the interface implements the PET-based blocking paradigm: + Each PET of the VM must issue this call exactly once for all of its + DEs. The call will block until all PET-local data objects are accessible. + +
+For examples and associated documentation regarding this method see Section + 26.3.29. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldSet(field, name, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len = *), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets adjustable settings in an ESMF_Field object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldSync(field, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Synchronizes access to DEs across field to make sure PETs correctly + access the data for read and write when DEs are shared. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldSMM(srcField, dstField, routehandle, & + zeroregion, termorderflag, checkflag, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in), optional :: srcField + type(ESMF_Field), intent(inout), optional :: dstField + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Region_Flag), intent(in), optional :: zeroregion + type(ESMF_TermOrder_Flag), intent(in), optional :: termorderflag + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed Field sparse matrix multiplication from srcField to + dstField. + Both srcField and dstField must match the respective Fields + used during ESMF_FieldSMMStore() in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+The srcField and dstField arguments are optional in support of + the situation where srcField and/or dstField are not defined on + all PETs. The srcField and dstField must be specified on those + PETs that hold source or destination DEs, respectively, but may be omitted + on all other PETs. PETs that hold neither source nor destination DEs may + omit both arguments. + +
+It is erroneous to specify the identical Field object for srcField and + dstField arguments. + +
+See ESMF_FieldSMMStore() on how to precompute + routehandle. + +
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 26.3.33. + +
+
+ +
+ +
+sparse matrix multiplication + +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldSMMRelease(routehandle, noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with a Field sparse matrix multiplication. After this call + routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldSMMStore() + subroutine ESMF_FieldSMMStore<type><kind>(srcField, dstField, & + routehandle, factorList, factorIndexList, & + ignoreUnmatchedIndices, srcTermProcessing, pipelineDepth, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: srcField + type(ESMF_Field), intent(inout) :: dstField + type(ESMF_RouteHandle), intent(inout) :: routehandle + <type>(ESMF_KIND_<kind>), intent(in) :: factorList(:) + integer, intent(in), :: factorIndexList(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipeLineDepth + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store a Field sparse matrix multiplication operation from srcField + to dstField. PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+Both srcField and dstField are interpreted as sequentialized + vectors. The + sequence is defined by the order of DistGrid dimensions and the order of + tiles within the DistGrid or by user-supplied arbitrary sequence indices. See + section 28.2.18 for details on the definition of sequence indices. + SMM corresponds to an identity mapping of the source Field vector to + the destination Field vector. + +
+Source and destination Fields may be of different <type><kind>. Further source + and destination Fields may differ in shape, however, the number of elements + must match. + +
+It is erroneous to specify the identical Field object for srcField and dstField + arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldSMM() on any pair of Fields that matches + srcField and dstField in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 26.3.33. + +
+The arguments are: + +
+
+
+
+
+
+The second dimension of factorIndexList steps through the list of + pairs, i.e. size(factorIndexList,2) == size(factorList). The first + dimension of factorIndexList is either of size 2 or size 4. + + The second dimension of factorIndexList steps through the list of + +
+In the size 2 format factorIndexList(1,:) specifies the + sequence index of the source element in the srcField while + factorIndexList(2,:) specifies the sequence index of the + destination element in dstField. For this format to be a valid + option source and destination Fields must have matching number of + tensor elements (the product of the sizes of all Field tensor dimensions). + Under this condition an identity matrix can be applied within the space of + tensor elements for each sparse matrix factor. + +
+The size 4 format is more general and does not require a matching + tensor element count. Here the factorIndexList(1,:) specifies the + sequence index while factorIndexList(2,:) specifies the tensor + sequence index of the source element in the srcField. Further + factorIndexList(3,:) specifies the sequence index and + factorIndexList(4,:) specifies the tensor sequence index of the + destination element in the dstField. + +
+See section 28.2.18 for details on the definition of + Field sequence indices and tensor sequence indices. + +
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldSMMStore() + subroutine ESMF_FieldSMMStore<type><kind>TR(srcField, dstField, & + routehandle, transposeRoutehandle, factorList, factorIndexList, & + ignoreUnmatchedIndices, srcTermProcessing, & + pipelineDepth, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: srcField + type(ESMF_Field), intent(inout) :: dstField + type(ESMF_RouteHandle), intent(inout) :: routehandle + type(ESMF_RouteHandle), intent(inout) :: transposeRoutehandle + <type>(ESMF_KIND_<kind>), intent(in) :: factorList(:) + integer, intent(in), :: factorIndexList(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipeLineDepth + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Store a Field sparse matrix multiplication operation from srcField + to dstField. PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+Both srcField and dstField are interpreted as sequentialized + vectors. The + sequence is defined by the order of DistGrid dimensions and the order of + tiles within the DistGrid or by user-supplied arbitrary sequence indices. See + section 28.2.18 for details on the definition of sequence indices. + SMM corresponds to an identity mapping of the source Field vector to + the destination Field vector. + +
+Source and destination Fields may be of different <type><kind>. Further source + and destination Fields may differ in shape, however, the number of elements + must match. + +
+It is erroneous to specify the identical Field object for srcField and dstField + arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldSMM() on any pair of Fields that matches + srcField and dstField in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 26.3.33. + +
+The arguments are: + +
+
+
+
+
+
+
+The second dimension of factorIndexList steps through the list of + pairs, i.e. size(factorIndexList,2) == size(factorList). The first + dimension of factorIndexList is either of size 2 or size 4. + + The second dimension of factorIndexList steps through the list of + +
+In the size 2 format factorIndexList(1,:) specifies the + sequence index of the source element in the srcField while + factorIndexList(2,:) specifies the sequence index of the + destination element in dstField. For this format to be a valid + option source and destination Fields must have matching number of + tensor elements (the product of the sizes of all Field tensor dimensions). + Under this condition an identity matrix can be applied within the space of + tensor elements for each sparse matrix factor. + +
+The size 4 format is more general and does not require a matching + tensor element count. Here the factorIndexList(1,:) specifies the + sequence index while factorIndexList(2,:) specifies the tensor + sequence index of the source element in the srcField. Further + factorIndexList(3,:) specifies the sequence index and + factorIndexList(4,:) specifies the tensor sequence index of the + destination element in the dstField. + +
+See section 28.2.18 for details on the definition of + Field sequence indices and tensor sequence indices. + +
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldSMMStore() + subroutine ESMF_FieldSMMStoreNF(srcField, dstField, & + routehandle, ignoreUnmatchedIndices, & + srcTermProcessing, pipelineDepth, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: srcField + type(ESMF_Field), intent(inout) :: dstField + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipeLineDepth + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store a Field sparse matrix multiplication operation from srcField + to dstField. PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+Both srcField and dstField are interpreted as sequentialized + vectors. The + sequence is defined by the order of DistGrid dimensions and the order of + tiles within the DistGrid or by user-supplied arbitrary sequence indices. See + section 28.2.18 for details on the definition of sequence indices. + SMM corresponds to an identity mapping of the source Field vector to + the destination Field vector. + +
+Source and destination Fields may be of different <type><kind>. Further source + and destination Fields may differ in shape, however, the number of elements + must match. + +
+It is erroneous to specify the identical Field object for srcField and dstField + arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldSMM() on any pair of Fields that matches + srcField and dstField in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 26.3.33. + +
+The arguments are: + +
+
+
+
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldSMMStore() + subroutine ESMF_FieldSMMStoreNFTR(srcField, dstField, & + routehandle, transposeRoutehandle, ignoreUnmatchedIndices, & + srcTermProcessing, pipelineDepth, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: srcField + type(ESMF_Field), intent(inout) :: dstField + type(ESMF_RouteHandle), intent(inout) :: routehandle + type(ESMF_RouteHandle), intent(inout) :: transposeRoutehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipeLineDepth + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Store a Field sparse matrix multiplication operation from srcField + to dstField. PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+Both srcField and dstField are interpreted as sequentialized + vectors. The + sequence is defined by the order of DistGrid dimensions and the order of + tiles within the DistGrid or by user-supplied arbitrary sequence indices. See + section 28.2.18 for details on the definition of sequence indices. + SMM corresponds to an identity mapping of the source Field vector to + the destination Field vector. + +
+Source and destination Fields may be of different <type><kind>. Further source + and destination Fields may differ in shape, however, the number of elements + must match. + +
+It is erroneous to specify the identical Field object for srcField and dstField + arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_FieldSMM() on any pair of Fields that matches + srcField and dstField in type, kind, and + memory layout of the gridded dimensions. However, the size, number, + and index order of ungridded dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+
+This call is collective across the current VM. + +
+For examples and associated documentation regarding this method see Section + 26.3.33. + +
+The arguments are: + +
+
+
+
+
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldSMMStore() + subroutine ESMF_FieldSMMStoreFromFile(srcField, dstField, filename, & + routehandle, ignoreUnmatchedIndices, & + srcTermProcessing, pipelineDepth, rc) + + ! ARGUMENTS: + type(ESMF_Field), intent(in) :: srcField + type(ESMF_Field), intent(inout) :: dstField + character(len=*), intent(in) :: filename + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipeLineDepth + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Compute an ESMF_RouteHandle using factors read from file. + +
+The arguments are: + +
+
+
+
+
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_FieldSMMStore() + subroutine ESMF_FieldSMMStoreFromFileTR(srcField, dstField, filename, & + routehandle, transposeRoutehandle, & + ignoreUnmatchedIndices, srcTermProcessing, pipelineDepth, rc) + + ! ARGUMENTS: + type(ESMF_Field), intent(inout) :: srcField + type(ESMF_Field), intent(inout) :: dstField + character(len=*), intent(in) :: filename + type(ESMF_RouteHandle), intent(inout) :: routehandle + type(ESMF_RouteHandle), intent(inout) :: transposeRoutehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipeLineDepth + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Compute an ESMF_RouteHandle using factors read from file. + +
+The arguments are: + +
+
+
+
+
+
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + The ESMF_FieldSMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldValidate(field, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Validates that the field is internally consistent. + Currently this method determines if the field is uninitialized + or already destroyed. It validates the contained array and grid objects. + The code also checks if the array and grid sizes agree. + This check compares the distgrid contained in array and grid; + then it proceeds to compare the computational bounds contained + in array and grid. + +
+The method returns an error code if problems are found. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_FieldWrite(field, fileName, & + variableName, convention, purpose, overwrite, status, timeslice, iofmt, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + character(*), intent(in) :: fileName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(*), intent(in), optional :: variableName + character(*), intent(in), optional :: convention + character(*), intent(in), optional :: purpose + logical, intent(in), optional :: overwrite + type(ESMF_FileStatus_Flag), intent(in), optional :: status + integer, intent(in), optional :: timeslice + type(ESMF_IOFmt_Flag), intent(in), optional :: iofmt + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write Field data into a file. For this API to be functional, the + environment variable ESMF_PIO should be set to either "internal" or "external" when + the ESMF library is built. Please see the section on + Data I/O, 38.2. + +
+When convention and purpose arguments are specified, + a NetCDF variable can be created with user-specified dimension labels and + attributes. Dimension labels may be defined for both gridded and + ungridded dimensions. Dimension labels for gridded dimensions are specified + at the Grid level by attaching an ESMF Attribute package to it. The Attribute + package must contain an attribute named by the pre-defined ESMF parameter + ESMF_ATT_GRIDDED_DIM_LABELS. The corresponding value is an array of + character strings specifying the desired names of the dimensions. Likewise, + for ungridded dimensions, an Attribute package is attached at the Field level. + The name of the name must be ESMF_ATT_UNGRIDDED_DIM_LABELS. + +
+NetCDF attributes for the variable can also be specified. As with dimension labels, + an Attribute package is added to the Field with the desired names and values. + A value may be either a scalar character string, or a scalar or array of type + integer, real, or double precision. Dimension label attributes can co-exist with + variable attributes within a common Attribute package. + +
+Limitations: + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridGetFieldBounds(grid, & + localDe, staggerloc, gridToFieldMap, & + ungriddedLBound, ungriddedUBound, & + totalLWidth, totalUWidth, & + totalLBound, totalUBound, totalCount, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: localDe + type(ESMF_StaggerLoc), intent(in), optional :: staggerloc + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(out), optional :: totalLBound(:) + integer, intent(out), optional :: totalUBound(:) + integer, intent(out), optional :: totalCount(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Compute the lower and upper bounds of Fortran data array that can later + be used in FieldCreate interface to create a ESMF_Field from a + ESMF_Grid and the Fortran data array. For an example and + associated documentation using this method see section + 26.3.9. + +
+The arguments are: +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LocStreamGetFieldBounds(locstream, & + localDe, gridToFieldMap, & + ungriddedLBound, ungriddedUBound, & + totalLBound, totalUBound, totalCount, rc) +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: localDe + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(out), optional :: totalLBound(:) + integer, intent(out), optional :: totalUBound(:) + integer, intent(out), optional :: totalCount(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Compute the lower and upper bounds of Fortran data array that can later + be used in FieldCreate interface to create a ESMF_Field from a + ESMF_LocStream and the Fortran data array. For an example and + associated documentation using this method see section + 26.3.9. + +
+The arguments are: +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_MeshGetFieldBounds(mesh, & + meshloc, & + localDe, gridToFieldMap, & + ungriddedLBound, ungriddedUBound, & + totalLBound, totalUBound, totalCount, rc) +ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_MeshLoc),intent(in),optional :: meshloc + integer, intent(in), optional :: localDe + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(out), optional :: totalLBound(:) + integer, intent(out), optional :: totalUBound(:) + integer, intent(out), optional :: totalCount(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Compute the lower and upper bounds of Fortran data array that can later + be used in FieldCreate interface to create a ESMF_Field from a + ESMF_Mesh and the Fortran data array. For an example and + associated documentation using this method see section + 26.3.9. + +
+The arguments are: +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_XGridGetFieldBounds(xgrid, & + xgridside, gridindex, localDe, gridToFieldMap, & + ungriddedLBound, ungriddedUBound, & + totalLBound, totalUBound, totalCount, rc) +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridside + integer, intent(in), optional :: gridindex + integer, intent(in), optional :: localDe + integer, intent(in), optional :: gridToFieldMap(:) + integer, intent(in), optional :: ungriddedLBound(:) + integer, intent(in), optional :: ungriddedUBound(:) + integer, intent(out), optional :: totalLBound(:) + integer, intent(out), optional :: totalUBound(:) + integer, intent(out), optional :: totalCount(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Compute the lower and upper bounds of Fortran data array that can later + be used in FieldCreate interface to create a ESMF_Field from a + ESMF_XGrid and the Fortran data array. For an example and + associated documentation using this method see section + 26.3.9. + +
+The arguments are: +
+
+The ESMF_ArrayBundle class allows a set of Arrays to be bundled into a +single object. The Arrays in an ArrayBundle may be of different type, kind, +rank and distribution. Besides ease of use resulting from bundling, the +ArrayBundle class offers the opportunity for performance optimization when +operating on a bundle of Arrays as a single entity. Communication methods are +especially good candidates for performance optimization. Best optimization +results are expected for ArrayBundles that contain Arrays that share a common +distribution, i.e. DistGrid, and are of same type, kind and rank. + +
+ArrayBundles are one of the data objects that can be added to States, +which are used for providing to or receiving data from other Components. + +
+Examples of creating, destroying and accessing ArrayBundles and their +constituent Arrays are provided in this section, along with some +notes on ArrayBundle methods. + +
+ +
+ +
+ +
+An ArrayBundle is created from a list of ESMF_Array objects. +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=2, rc=rc) ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + regDecomp=(/2,3/), rc=rc) ++ +
+
+ allocate(arrayList(2)) + arrayList(1) = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, & + rc=rc) ++ +
+
+ arrayList(2) = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, & + rc=rc) ++ +
+Now arrayList is used to create an ArrayBundle object. +
+
+ arraybundle = ESMF_ArrayBundleCreate(arrayList=arrayList, & + name="MyArrayBundle", rc=rc) ++ +
+Here the temporary arrayList can be deallocated. This will not affect + the ESMF Array objects inside the ArrayBundle. However, the Array objects + must not be deallocated while the ArrayBundle references them. +
+
+ deallocate(arrayList) ++ +
+ +
+Individual Arrays can be added using the Fortran array constructor syntax + (/ ... /). Here an ESMF_Array is created on the fly and immediately + added to the ArrayBundle. +
+
+ call ESMF_ArrayBundleAdd(arraybundle, arrayList=(/ & + ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, name="AonFly")/), & + rc=rc) ++ +
+Items in the ArrayBundle can be replaced by items with the same name. +
+
+ call ESMF_ArraySpecSet(arrayspec2, typekind=ESMF_TYPEKIND_R4, rank=2, rc=rc) ++ +
+
+ call ESMF_ArrayBundleReplace(arraybundle, arrayList=(/ & + ESMF_ArrayCreate(arrayspec=arrayspec2, distgrid=distgrid, name="AonFly")/), & + rc=rc) ++ +
+Items can be removed from the ArrayBundle by providing their name. +
+
+ call ESMF_ArrayBundleRemove(arraybundle, arrayNameList=(/"AonFly"/), rc=rc) ++ +
+The ArrayBundle AddReplace() method can be used to conveniently add an + item to the ArrayBundle, or replacing an existing item of the same name. +
+
+ call ESMF_ArrayBundleAddReplace(arraybundle, arrayList=(/ & + ESMF_ArrayCreate(arrayspec=arrayspec2, distgrid=distgrid, name="AonFly")/), & + rc=rc) ++ +
+The ArrayBundle object can be printed at any time to list its contents by name. +
+
+ call ESMF_ArrayBundlePrint(arraybundle, rc=rc) ++ +
+ +
+Individual items in the ArrayBundle can be accessed directly by their + name. +
+
+ call ESMF_ArrayBundleGet(arraybundle, arrayName="AonFly", array=arrayOut, & + rc=rc) ++ +
+A list containing all of the Arrays in the ArrayBundle can also be requested + in a single call. + This requires that a large enough list argument is passed into the + ESMF_ArrayBundleGet() method. The exact number of items in the + ArrayBundle can be queried using the arrayCount argument first. +
+
+ call ESMF_ArrayBundleGet(arraybundle, arrayCount=arrayCount, rc=rc) ++ +
+Then use arrayCount to correctly allocate the arrayList + variable for a second call to ESMF_ArrayBundleGet(). + +
+
+ allocate(arrayList(arrayCount)) + call ESMF_ArrayBundleGet(arraybundle, arrayList=arrayList, rc=rc) ++ +
+Now the arrayList variable can be used to access the individual Arrays, + e.g. to print them. +
+
+ do i=1, arrayCount + call ESMF_ArrayPrint(arrayList(i), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + enddo ++ +
+By default the arrayList returned by ESMF_ArrayBundleGet() + contains the items in alphabetical order. To instead return the items in the + same order in which they were added to the ArrayBundle, the + itemorderflag argument is passed with a value of + ESMF_ITEMORDER_ADDORDER. + +
+ +
+
+ call ESMF_ArrayBundleGet(arraybundle, arrayList=arrayList, & + itemorderflag=ESMF_ITEMORDER_ADDORDER, rc=rc) ++ +
+ +
+Destroying an ArrayBundle does not destroy the Arrays. In fact, it leaves the + Arrays totally unchanged. +
+
+ call ESMF_ArrayBundleDestroy(arraybundle, rc=rc) ++ +
+The Arrays must be destroyed separately. +
+
+ call ESMF_ArrayDestroy(arrayList(1), rc=rc) ++ +
+
+ call ESMF_ArrayDestroy(arrayList(2), rc=rc) ++ +
+
+ deallocate(arrayList) + + call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+One of the most fundamental communication pattern in domain decomposition + codes is the halo operation. The ESMF Array class supports halos + by allowing memory for extra elements to be allocated on each DE. See + section 28.2.15 for a discussion of the Array level halo operation. + The ArrayBundle level extents the Array halo operation to bundles of Arrays. + +
+First create an ESMF_ArrayBundle object containing a set of ESMF + Arrays. +
+
+ arraybundle = ESMF_ArrayBundleCreate(arrayList=arrayList, & + name="MyArrayBundle", rc=rc) ++ +
+The ArrayBundle object can be treated as a single entity. The + ESMF_ArrayBundleHaloStore() call determines the most efficient + halo exchange pattern for all Arrays that are part of + arraybundle. +
+
+ call ESMF_ArrayBundleHaloStore(arraybundle=arraybundle, & + routehandle=haloHandle, rc=rc) ++ +
+The halo exchange pattern stored in haloHandle can now be applied to + the arraybundle object, or any other ArrayBundle that is compatible + to the one used during the ESMF_ArrayBundleHaloStore() call. +
+
+ call ESMF_ArrayBundleHalo(arraybundle=arraybundle, routehandle=haloHandle, & + rc=rc) ++ +
+Finally, when no longer needed, the resources held by haloHandle need + to be returned to the system by calling ESMF_ArrayBundleHaloRelease(). +
+
+ call ESMF_ArrayBundleHaloRelease(routehandle=haloHandle, rc=rc) ++ +
+Finally the ArrayBundle object can be destroyed. +
+
+ call ESMF_ArrayBundleDestroy(arraybundle, rc=rc) ++ +
+ + +
+ +
+
+The following is a list of implementation specific details about the current ESMF ArrayBundle. + +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + arraybundle1 = arraybundle2 +ARGUMENTS: +
type(ESMF_ArrayBundle) :: arraybundle1 + type(ESMF_ArrayBundle) :: arraybundle2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign arraybundle1 as an alias to the same ESMF ArrayBundle object in memory + as arraybundle2. If arraybundle2 is invalid, then arraybundle1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (arraybundle1 == arraybundle2) then ... endif + OR + result = (arraybundle1 == arraybundle2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: arraybundle1 + type(ESMF_ArrayBundle), intent(in) :: arraybundle2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether arraybundle1 and arraybundle2 are valid aliases to the same ESMF + ArrayBundle object in memory. For a more general comparison of two ESMF ArrayBundles, + going beyond the simple alias test, the ESMF_ArrayBundleMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (arraybundle1 /= arraybundle2) then ... endif + OR + result = (arraybundle1 /= arraybundle2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: arraybundle1 + type(ESMF_ArrayBundle), intent(in) :: arraybundle2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether arraybundle1 and arraybundle2 are not valid aliases to the + same ESMF ArrayBundle object in memory. For a more general comparison of two ESMF + ArrayBundles, going beyond the simple alias test, the ESMF_ArrayBundleMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleAdd(arraybundle, arrayList, & + multiflag, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(inout) :: arraybundle + type(ESMF_Array), intent(in) :: arrayList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: multiflag + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Add Array(s) to an ArrayBundle. It is an error if arrayList contains + Arrays that match by name Arrays already contained in arraybundle. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleAddReplace(arraybundle, arrayList, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(inout) :: arraybundle + type(ESMF_Array), intent(in) :: arrayList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Arrays in arrayList that do not match any Arrays by name in + arraybundle are added to the ArrayBundle. Arrays in arraybundle + that match by name Arrays in arrayList are replaced by those Arrays. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_ArrayBundleCreate(arrayList, multiflag, & + relaxedflag, name, rc) +RETURN VALUE: +
type(ESMF_ArrayBundle) :: ESMF_ArrayBundleCreate +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Array), intent(in), optional :: arrayList(:) + logical, intent(in), optional :: multiflag + logical, intent(in), optional :: relaxedflag + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_ArrayBundle object from a list of existing Arrays. + +
+The creation of an ArrayBundle leaves the bundled Arrays unchanged, they + remain valid individual objects. An ArrayBundle is a light weight container + of Array references. The actual data remains in place, there are no + data movements or duplications associated with the creation of an + ArrayBundle. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleDestroy(arraybundle, noGarbage, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(inout) :: arraybundle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroys an ESMF_ArrayBundle object. The member Arrays are not + touched by this operation and remain valid objects that need to be + destroyed individually if necessary. + +
+By default a small remnant of the object is kept in memory in order to + prevent problems with dangling aliases. The default garbage collection + mechanism can be overridden with the noGarbage argument. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayBundleGet() + subroutine ESMF_ArrayBundleGetListAll(arraybundle, & + itemorderflag, arrayCount, arrayList, arrayNameList, name, vm, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: arraybundle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_ItemOrder_Flag), intent(in), optional :: itemorderflag + integer, intent(out), optional :: arrayCount + type(ESMF_Array), intent(out), optional :: arrayList(:) + character(len=*), intent(out), optional :: arrayNameList(:) + character(len=*), intent(out), optional :: name + type(ESMF_VM), intent(out), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get general, i.e. not Array name specific information from the ArrayBundle. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayBundleGet() + subroutine ESMF_ArrayBundleGetItem(arraybundle, arrayName, & + array, arrayCount, isPresent, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: arraybundle + character(len=*), intent(in) :: arrayName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Array), intent(out), optional :: array + integer, intent(out), optional :: arrayCount + logical, intent(out), optional :: isPresent + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get information about items that match arrayName in ArrayBundle. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayBundleGet() + subroutine ESMF_ArrayBundleGetList(arraybundle, arrayName, arrayList, & + itemorderflag, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: arraybundle + character(len=*), intent(in) :: arrayName + type(ESMF_Array), intent(out) :: arrayList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_ItemOrder_Flag), intent(in), optional :: itemorderflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get the list of Arrays from ArrayBundle that match arrayName. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleHalo(arraybundle, routehandle, & + checkflag, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(inout) :: arraybundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed ArrayBundle halo operation for the Arrays in + arrayBundle. + +
+See ESMF_ArrayBundleHaloStore() on how to precompute + routehandle. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleHaloRelease(routehandle, & + noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with an ArrayBundle halo operation. + After this call routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleHaloStore(arraybundle, routehandle, & + startregion, haloLDepth, haloUDepth, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(inout) :: arraybundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_StartRegion_Flag),intent(in), optional :: startregion + integer, intent(in), optional :: haloLDepth(:) + integer, intent(in), optional :: haloUDepth(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store an ArrayBundle halo operation over the data in arraybundle. By + default, i.e. without specifying startregion, haloLDepth + and haloUDepth, all elements in the total Array regions that lie + outside the exclusive regions will be considered potential destination + elements for the halo operation. However, only those elements that have a corresponding + halo source element, i.e. an exclusive element on one of the DEs, will be + updated under the halo operation. Elements that have no associated source + remain unchanged under halo. + +
+Specifying startregion allows to change the shape of the + effective halo region from the inside. Setting this flag to + ESMF_STARTREGION_COMPUTATIONAL means that only elements outside + the computational region for each Array are considered for potential + destination elements for the halo operation. The default is + ESMF_STARTREGION_EXCLUSIVE. + +
+The haloLDepth and haloUDepth arguments allow to reduce + the extent of the effective halo region. Starting at the region specified + by startregion, the haloLDepth and haloUDepth + define a halo depth in each direction. Note that the maximum halo region is + limited by the total region for each Array, independent of the actual + haloLDepth and haloUDepth setting. The total Array regions are + local DE specific. The haloLDepth and haloUDepth are interpreted + as the maximum desired extent, reducing the potentially larger region + available for the halo operation. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArrayBundleHalo() on any pair of ArrayBundles that matches + srcArrayBundle and dstArrayBundle in type, kind, + and memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_ArrayBundleIsCreated(arraybundle, rc) +RETURN VALUE: +
logical :: ESMF_ArrayBundleIsCreated +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: arraybundle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the arraybundle has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleLog(arraybundle, prefix, logMsgFlag, deepFlag, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: arraybundle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: prefix + type(ESMF_LogMsg_Flag), intent(in), optional :: logMsgFlag + logical, intent(in), optional :: deepFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write information about arraybundle to the ESMF default Log. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundlePrint(arraybundle, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: arraybundle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Print internal information of the specified ESMF_ArrayBundle
+ object to stdout.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleRead(arraybundle, fileName, & + singleFile, timeslice, iofmt, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(inout) :: arraybundle + character(*), intent(in) :: fileName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: singleFile + integer, intent(in), optional :: timeslice + type(ESMF_IOFmt_Flag), intent(in), optional :: iofmt + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Read Array data to an ArrayBundle object from file(s). + For this API to be functional, the environment variable ESMF_PIO + should be set to either "internal" or "external" when the ESMF library is built. + Please see the section on Data I/O, 38.2. + +
+Limitations: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleRedist(srcArrayBundle, dstArrayBundle, & + routehandle, checkflag, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in), optional :: srcArrayBundle + type(ESMF_ArrayBundle), intent(inout), optional :: dstArrayBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed ArrayBundle redistribution from the Arrays in + srcArrayBundle to the Arrays in dstArrayBundle. + +
+The srcArrayBundle and dstArrayBundle arguments are optional in + support of the situation where srcArrayBundle and/or + dstArrayBundle are not defined on all PETs. The srcArrayBundle + and dstArrayBundle must be specified on those PETs that hold source + or destination DEs, respectively, but may be omitted on all other PETs. + PETs that hold neither source nor destination DEs may omit both arguments. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleRedistRelease(routehandle, & + noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with an ArrayBundle redistribution. + After this call routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayBundleRedistStore() + subroutine ESMF_ArrayBundleRedistStore<type><kind>(srcArrayBundle, & + dstArrayBundle, routehandle, factor, ignoreUnmatchedIndicesFlag, & + srcToDstTransposeMap, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: srcArrayBundle + type(ESMF_ArrayBundle), intent(inout) :: dstArrayBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + <type>(ESMF_KIND_<kind>),intent(in) :: factor + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndicesFlag(:) + integer, intent(in), optional :: srcToDstTransposeMap(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store an ArrayBundle redistribution operation from + srcArrayBundle to dstArrayBundle. The redistribution + between ArrayBundles is defined as the sequence of + individual Array redistributions over all source and + destination Array pairs in sequence. The method requires that + srcArrayBundle and dstArrayBundle reference an identical + number of ESMF_Array objects. + +
+The effect of this method on ArrayBundles that contain aliased members is + undefined. + +
+PETs that specify a factor argument must use the + <type><kind> overloaded interface. Other PETs call into the interface + without factor argument. If multiple PETs specify the factor + argument its type and kind as well as its value must match across all + PETs. If none of the PETs specifies a factor argument the default + will be a factor of 1. + +
+See the description of method ESMF_ArrayRedistStore() for + the definition of the Array based operation. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArrayBundleRedist() on any pair of ArrayBundles that matches + srcArrayBundle and dstArrayBundle in type, kind, + and memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayBundleRedistStore() + subroutine ESMF_ArrayBundleRedistStoreNF(srcArrayBundle, dstArrayBundle, & + routehandle, ignoreUnmatchedIndicesFlag, & + srcToDstTransposeMap, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: srcArrayBundle + type(ESMF_ArrayBundle), intent(inout) :: dstArrayBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndicesFlag(:) + integer, intent(in), optional :: srcToDstTransposeMap(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store an ArrayBundle redistribution operation from + srcArrayBundle to dstArrayBundle. The redistribution + between ArrayBundles is defined as the sequence of + individual Array redistributions over all source and + destination Array pairs in sequence. The method requires that + srcArrayBundle and dstArrayBundle reference an identical + number of ESMF_Array objects. + +
+The effect of this method on ArrayBundles that contain aliased members is + undefined. + +
+PETs that specify a factor argument must use the + <type><kind> overloaded interface. Other PETs call into the interface + without factor argument. If multiple PETs specify the factor + argument its type and kind as well as its value must match across all + PETs. If none of the PETs specifies a factor argument the default + will be a factor of 1. + +
+See the description of method ESMF_ArrayRedistStore() for + the definition of the Array based operation. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArrayBundleRedist() on any pair of ArrayBundles that matches + srcArrayBundle and dstArrayBundle in type, kind, + and memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleRemove(arraybundle, arrayNameList, & + multiflag, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(inout) :: arraybundle + character(len=*), intent(in) :: arrayNameList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: multiflag + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Remove Array(s) by name from ArrayBundle. In the relaxed setting it is + not an error if arrayNameList contains names that are not + found in arraybundle. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleReplace(arraybundle, arrayList, & + multiflag, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(inout) :: arraybundle + type(ESMF_Array), intent(in) :: arrayList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: multiflag + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Replace Array(s) by name in ArrayBundle. In the relaxed setting it is not + an error if arrayList contains Arrays that do not match by name any + item in arraybundle. These Arrays are simply ignored in this case. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleSMM(srcArrayBundle, dstArrayBundle, & + routehandle, & + zeroregion, & ! DEPRECATED ARGUMENT + zeroregionflag, termorderflag, checkflag, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in), optional :: srcArrayBundle + type(ESMF_ArrayBundle), intent(inout), optional :: dstArrayBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Region_Flag), intent(in), optional :: zeroregion ! DEPRECATED ARGUMENT + type(ESMF_Region_Flag), intent(in), target, optional :: zeroregionflag(:) + type(ESMF_TermOrder_Flag), intent(in), target, optional :: termorderflag(:) + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed ArrayBundle sparse matrix multiplication from the + Arrays in srcArrayBundle to the Arrays in dstArrayBundle. + +
+The srcArrayBundle and dstArrayBundle arguments are optional in + support of the situation where srcArrayBundle and/or + dstArrayBundle are not defined on all PETs. The srcArrayBundle + and dstArrayBundle must be specified on those PETs that hold source + or destination DEs, respectively, but may be omitted on all other PETs. + PETs that hold neither source nor destination DEs may omit both arguments. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleSMMRelease(routehandle, & + noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with an ArrayBundle sparse matrix multiplication. + After this call routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayBundleSMMStore() + subroutine ESMF_ArrayBundleSMMStore<type><kind>(srcArrayBundle, & + dstArrayBundle, routehandle, factorList, factorIndexList, & + ignoreUnmatchedIndicesFlag, srcTermProcessing, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: srcArrayBundle + type(ESMF_ArrayBundle), intent(inout) :: dstArrayBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + <type>(ESMF_KIND_<kind>), target, intent(in) :: factorList(:) + integer, intent(in) :: factorIndexList(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndicesFlag(:) + integer, intent(inout), optional :: srcTermProcessing(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store an ArrayBundle sparse matrix multiplication operation from + srcArrayBundle to dstArrayBundle. The sparse matrix + multiplication between ArrayBundles is defined as the sequence of + individual Array sparse matrix multiplications over all source and + destination Array pairs in sequence. The method requires that + srcArrayBundle and dstArrayBundle reference an identical + number of ESMF_Array objects. + +
+The effect of this method on ArrayBundles that contain aliased members is + undefined. + +
+PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+See the description of method ESMF_ArraySMMStore() for + the definition of the Array based operation. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArrayBundleSMM() on any pair of ArrayBundles that matches + srcArrayBundle and dstArrayBundle in type, kind, + and memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+
+This call is collective across the current VM. + +
+
+The second dimension of factorIndexList steps through the list of + pairs, i.e. size(factorIndexList,2) == size(factorList). The first + dimension of factorIndexList is either of size 2 or size 4. + +
+In the size 2 format factorIndexList(1,:) specifies the + sequence index of the source element in the source Array while + factorIndexList(2,:) specifies the sequence index of the + destination element in the destination Array. For this format to be a + valid option source and destination Arrays must have matching number of + tensor elements (the product of the sizes of all Array tensor dimensions). + Under this condition an identity matrix can be applied within the space of + tensor elements for each sparse matrix factor. + +
+The size 4 format is more general and does not require a matching + tensor element count. Here the factorIndexList(1,:) specifies the + sequence index while factorIndexList(2,:) specifies the tensor + sequence index of the source element in the source Array. Further + factorIndexList(3,:) specifies the sequence index and + factorIndexList(4,:) specifies the tensor sequence index of the + destination element in the destination Array. + +
+See section 28.2.18 for details on the definition of + Array sequence indices and tensor sequence indices. + +
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayBundleSMMStore() + subroutine ESMF_ArrayBundleSMMStoreNF(srcArrayBundle, dstArrayBundle, & + routehandle, ignoreUnmatchedIndicesFlag, srcTermProcessing, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: srcArrayBundle + type(ESMF_ArrayBundle), intent(inout) :: dstArrayBundle + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndicesFlag(:) + integer, intent(inout), optional :: srcTermProcessing(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store an ArrayBundle sparse matrix multiplication operation from + srcArrayBundle to dstArrayBundle. The sparse matrix + multiplication between ArrayBundles is defined as the sequence of + individual Array sparse matrix multiplications over all source and + destination Array pairs in sequence. The method requires that + srcArrayBundle and dstArrayBundle reference an identical + number of ESMF_Array objects. + +
+The effect of this method on ArrayBundles that contain aliased members is + undefined. + +
+PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+See the description of method ESMF_ArraySMMStore() for + the definition of the Array based operation. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArrayBundleSMM() on any pair of ArrayBundles that matches + srcArrayBundle and dstArrayBundle in type, kind, + and memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This call is collective across the current VM. + +
+
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayBundleWrite(arraybundle, fileName, & + convention, purpose, singleFile, overwrite, status, timeslice, iofmt, rc) +ARGUMENTS: +
type(ESMF_ArrayBundle), intent(in) :: arraybundle + character(*), intent(in) :: fileName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(*), intent(in), optional :: convention + character(*), intent(in), optional :: purpose + logical, intent(in), optional :: singleFile + logical, intent(in), optional :: overwrite + type(ESMF_FileStatus_Flag), intent(in), optional :: status + integer, intent(in), optional :: timeslice + type(ESMF_IOFmt_Flag), intent(in), optional :: iofmt + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write the Arrays into a file. For this API to be functional, + the environment variable ESMF_PIO should be set to either "internal" or "external" + when the ESMF library is built. Please see the section on + Data I/O, 38.2. + +
+When convention and purpose arguments are specified, NetCDF dimension + labels and variable attributes are written from each Array in the ArrayBundle + from the corresponding Attribute package. Additionally, Attributes may be + set on the ArrayBundle level under the same Attribute package. This allows + the specification of global attributes within the file. + As with individual Arrays, the value associated with each name may be either + a scalar character string, or a scalar or array of type integer, real, or + double precision. + +
+Limitations: + +
+The arguments are: +
+ + +
+The Array class is an alternative to the Field class for representing +distributed, structured data. Unlike Fields, which are built to carry +grid coordinate information, Arrays only carry information about the +indices associated with grid cells. Since they do not have coordinate +information, Arrays cannot be used to calculate interpolation weights. +However, if the user supplies interpolation weights, the Array sparse +matrix multiply (SMM) operation can be used to apply the weights and transfer +data to the new grid. Arrays carry enough information to perform +redistribution, scatter, and gather communication operations. + +
+Like Fields, Arrays can be added to a State and used in inter-Component +data communications. Arrays can also be grouped together into ArrayBundles, +allowing operations to be performed collectively on the whole group. One +motivation for this is convenience; another is the ability to schedule +optimized, collective data transfers. + +
+From a technical standpoint, the ESMF Array class is an index space based, +distributed data storage class. Its purpose is to hold distributed user data. +Each decompositon element (DE) is associated with its own memory allocation. The +index space relationship between DEs is described by the ESMF DistGrid class. +DEs, and their associated memory allocation, are pinned either to a specific +perisistent execution thread (PET), virtual address space (VAS), or a single +system image (SSI). This aspect is managed by the ESMF DELayout class. Pinning +to PET is the most common mode and is the default. + +
+The Array class offers common communication patterns within the index space +formalism. All RouteHandle based communication methods of the Field, +FieldBundle, and ArrayBundle layers are implemented via the Array SMM operation. + +
+An ESMF_Array is a distributed object that must exist on all PETs of the current context. Each PET-local instance of an Array object contains memory allocations for all PET-local DEs. There may be 0, 1, or more DEs per PET and the number of DEs per PET can differ between PETs for the same Array object. Memory allocations may be provided for each PET by the user during Array creation or can be allocated as part of the Array create call. Many of the concepts of the ESMF_Array class are illustrated by the following examples. + +
+ +
+ +
+ +
+The create call of the ESMF_Array class has been overloaded + extensively to facilitate the need for generality while keeping simple + cases simple. The following program demonstrates one of the simpler + cases, where existing local Fortran arrays are to be used to provide + the PET-local memory allocations for the Array object. + +
+
+program ESMF_ArrayFarrayEx ++ +
+
+ use ESMF + use ESMF_TestMod + + implicit none ++ +
+The Fortran language provides a variety of ways to define and allocate + an array. Actual Fortran array objects must either be explicit-shape or + deferred-shape. In the first case the memory allocation and deallocation is + automatic from the user's perspective and the details of the allocation + (static or dynamic, heap or stack) are left to the compiler. (Compiler flags + may be used to control some of the details). In the second case, i.e. for + deferred-shape actual objects, the array definition must include the pointer + or allocatable attribute and it is the user's responsibility to allocate + memory. While it is also the user's responsibility to deallocate memory for + arrays with the pointer attribute the compiler will automatically deallocate + allocatable arrays under certain circumstances defined by the Fortran + standard. + +
+The ESMF_ArrayCreate() interface has been written to accept native + Fortran arrays of any flavor as a means to allow user-controlled memory + management. The Array create call will check on each PET if sufficient + memory has been provided by the specified Fortran arrays and will indicate + an error if a problem is detected. However, the Array create call cannot + validate the lifetime of the provided memory allocations. If, for instance, + an Array object was created in a subroutine from an automatic explicit-shape + array or an allocatable array, the memory allocations referenced by the Array + object will be automatically deallocated on return from the subroutine unless + provisions are made by the application writer to prevent such behavior. The + Array object cannot control when memory that has been provided by the user + during Array creation becomes deallocated, however, the Array will indicate + an error if its memory references have been invalidated. + +
+The easiest, portable way to provide safe native Fortran memory allocations + to Array create is to use arrays with the pointer attribute. Memory allocated + for an array pointer will not be deallocated automatically. However, in this + case the possibility of memory leaks becomes an issue of concern. The + deallocation of memory provided to an Array in form of a native Fortran + allocation will remain the users responsibility. + +
+None of the concerns discussed above are an issue in this example where the + native Fortran array farray is defined in the main program. All + different types of array memory allocation are demonstrated in this example. + First farrayE is defined as a 2D explicit-shape array on each PET which + will automatically provide memory for elements. +
+
+ ! local variables + real(ESMF_KIND_R8) :: farrayE(10,10) ! explicit shape Fortran array ++ +
+Then an allocatable array farrayA is declared which will be used + to show user-controlled dynamic memory allocation. +
+
+ real(ESMF_KIND_R8), allocatable :: farrayA(:,:) ! allocatable Fortran array ++ +
+Finally an array with pointer attribute farrayP is declared, also used + for user-controlled dynamic memory allocation. +
+
+ real(ESMF_KIND_R8), pointer :: farrayP(:,:) ! Fortran array pointer ++ +
+A matching array pointer must also be available to gain access to the arrays + held by an Array object. +
+
+ real(ESMF_KIND_R8), pointer :: farrayPtr(:,:) ! matching Fortran array ptr + type(ESMF_DistGrid) :: distgrid ! DistGrid object + type(ESMF_Array) :: array ! Array object + integer :: rc ++ +
+
+ call ESMF_Initialize(defaultlogfilename="ArrayFarrayEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+On each PET farrayE can be accessed directly to initialize the entire + PET-local array. +
+
+ farrayE = 12.45d0 ! initialize to some value ++ +
+In order to create an Array object a DistGrid must first be created that + describes the total index space and how it is decomposed and distributed. + In the simplest case only the minIndex and maxIndex of the + total space must be provided. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/40,10/), rc=rc) ++ +
+This example is assumed to run on 4 PETs. The default 2D decomposition will + then be into 4 x 1 DEs as to ensure 1 DE per PET. + +
+Now the Array object can be created using the farrayE and the DistGrid + just created. +
+
+ array = ESMF_ArrayCreate(farray=farrayE, distgrid=distgrid, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) ++ +
+The 40 x 10 index space defined by the minIndex and maxIndex + arguments paired with the default decomposition will result in the following + distributed Array. + +
+
+ + +---------------------------> 2nd dimension + | (1,1)-------+ + | | | + | | DE 0 | <--- farray on PET 0 + | | | + | +------(10,10) + | (11,1)-------+ + | | | + | | DE 1 | <--- farray on PET 1 + | | | + | +------(20,10) + | (21,1)-------+ + | | | + | | DE 2 | <--- farray on PET 2 + | | | + | +------(30,10) + | (31,1)-------+ + | | | + | | DE 3 | <--- farray on PET 3 + | | | + | +------(40,10) + v + 1st dimension ++ +
+Providing farrayE during Array creation does not change anything about + the actual farrayE object. This means that each PET can use its + local farrayE directly to access the memory referenced by the Array + object. +
+
+ print *, farrayE ++ +
+Another way of accessing the memory associated with an Array object is to + use ArrayGet() to obtain an Fortran pointer that references the + PET-local array. +
+
+ call ESMF_ArrayGet(array, farrayPtr=farrayPtr, rc=rc) ++ +
+
+ print *, farrayPtr ++ +
+Finally the Array object must be destroyed. The PET-local memory of the + farrayEs will remain in user control and will not be altered by + ArrayDestroy(). +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+Since the memory allocation for each farrayE is automatic there is + nothing more to do. + +
+The interaction between farrayE and the Array class is representative + also for the two other cases farrayA and farrayP. The only + difference is in the handling of memory allocations. +
+
+ allocate(farrayA(10,10)) ! user controlled allocation + farrayA = 23.67d0 ! initialize to some value + array = ESMF_ArrayCreate(farray=farrayA, distgrid=distgrid, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) ++ +
+
+ print *, farrayA ! print PET-local farrayA directly + call ESMF_ArrayGet(array, farrayPtr=farrayPtr, rc=rc)! obtain array pointer + print *, farrayPtr ! print PET-local piece of Array through pointer + call ESMF_ArrayDestroy(array, rc=rc) ! destroy the Array + deallocate(farrayA) ! user controlled de-allocation ++ +
+The farrayP case is identical. +
+
+ allocate(farrayP(10,10)) ! user controlled allocation + farrayP = 56.81d0 ! initialize to some value + array = ESMF_ArrayCreate(farray=farrayP, distgrid=distgrid, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) ++ +
+
+ print *, farrayP ! print PET-local farrayA directly + call ESMF_ArrayGet(array, farrayPtr=farrayPtr, rc=rc)! obtain array pointer + print *, farrayPtr ! print PET-local piece of Array through pointer + call ESMF_ArrayDestroy(array, rc=rc) ! destroy the Array + deallocate(farrayP) ! user controlled de-allocation ++ +
+To wrap things up the DistGrid object is destroyed and ESMF can be finalized. +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ! destroy the DistGrid ++ +
+
+ call ESMF_Finalize(rc=rc) ++ +
+
+end program ++ +
+ + +
+ +
+ +
+ +
+The example of the previous section showed how easy it is to create an Array + object from existing PET-local Fortran arrays. The example did, however, not + define any halo elements around the DE-local regions. The following code + demonstrates how an Array object with space for a halo can be set up. +
+
+program ESMF_ArrayFarrayHaloEx ++ +
+
+ use ESMF + use ESMF_TestMod + + implicit none ++ +
+The allocatable array farrayA will be used to provide the PET-local + Fortran array for this example. +
+
+ ! local variables + real(ESMF_KIND_R8), allocatable :: farrayA(:,:) ! allocatable Fortran array + real(ESMF_KIND_R8), pointer :: farrayPtr(:,:) ! matching Fortran array ptr + type(ESMF_DistGrid) :: distgrid ! DistGrid object + type(ESMF_Array) :: array ! Array object + integer :: rc, i, j + real(ESMF_KIND_R8) :: localSum ++ +
+
+ call ESMF_Initialize(defaultlogfilename="ArrayFarrayHaloEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+The Array is to cover the exact same index space as in the previous + example. Furthermore decomposition and distribution are also kept the same. + Hence the same DistGrid object will be created and it is expected to + execute this example with 4 PETs. + +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/40,10/), rc=rc) ++ +
+This DistGrid describes a 40 x 10 index space that will be decomposed into + 4 DEs when executed on 4 PETs, associating 1 DE per PET. Each DE-local + exclusive region contains 10 x 10 elements. The DistGrid also stores and provides + information about the relationship between DEs in index space, however, + DistGrid does not contain information about halos. Arrays contain halo + information and it is possible to create multiple Arrays covering the same + index space with identical decomposition and distribution using the same + DistGrid object, while defining different, Array-specific halo regions. + +
+The extra memory required to cover the halo in the Array object must be + taken into account when allocating the PET-local farrayA arrays. For + a halo of 2 elements in each direction the following allocation will suffice. +
+
+ allocate(farrayA(14,14)) ! Fortran array with halo: 14 = 10 + 2 * 2 ++ +
+The farrayA can now be used to create an Array object with enough space + for a two element halo in each direction. The Array creation method checks for + each PET that the local Fortran array can accommodate the requested regions. + +
+The default behavior of ArrayCreate() is to center the exclusive region within + the total region. Consequently the following call will provide the 2 extra + elements on each side of the exclusive 10 x 10 region without having to specify + any additional arguments. +
+
+ array = ESMF_ArrayCreate(farray=farrayA, distgrid=distgrid, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) ++ +
+The exclusive Array region on each PET can be accessed through a suitable + Fortran array pointer. See section 28.2.6 + for more details on Array regions. +
+
+ call ESMF_ArrayGet(array, farrayPtr=farrayPtr, rc=rc) ++ +
+Following Array bounds convention, which by default puts the beginning of + the exclusive region at (1, 1, ...), the following loop will add up the + values of the local exclusive region for each DE, regardless of how the bounds + were chosen for the original PET-local farrayA arrays. +
+
+ localSum = 0. + do j=1, 10 + do i=1, 10 + localSum = localSum + farrayPtr(i, j) + enddo + enddo ++ +
+Elements with or in the [-1,0] or [11,12] ranges are located outside the + exclusive region and may be used to define extra computational points or + halo operations. + +
+Cleanup and shut down ESMF. +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+
+ deallocate(farrayA) + call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+
+ call ESMF_Finalize(rc=rc) ++ +
+
+end program ++ +
+ + +
+ +
+ +
+ +
+Alternative to the direct usage of Fortran arrays during Array creation + it is also possible to first create an ESMF_LocalArray and create the + Array from it. While this may seem more burdensome for the 1 DE per PET cases + discussed in the previous sections it allows a straightforward + generalization to the multiple DE per PET case. The following example first + recaptures the previous example using an ESMF_LocalArray and then + expands to the multiple DE per PET case. + +
+
+program ESMF_ArrayLarrayEx ++ +
+
+ use ESMF + use ESMF_TestMod + + implicit none ++ +
+The current ESMF_LocalArray interface requires Fortran arrays to be + defined with pointer attribute. +
+
+ ! local variables + real(ESMF_KIND_R8), pointer :: farrayP(:,:) ! Fortran array pointer + real(ESMF_KIND_R8), pointer :: farrayPtr(:,:) ! matching Fortran array ptr + type(ESMF_LocalArray) :: larray ! ESMF_LocalArray object + type(ESMF_LocalArray) :: larrayRef ! ESMF_LocalArray object + type(ESMF_DistGrid) :: distgrid ! DistGrid object + type(ESMF_Array) :: array ! Array object + integer :: rc, i, j, de + real(ESMF_KIND_R8) :: localSum + type(ESMF_LocalArray), allocatable :: larrayList(:) ! LocalArray object list + type(ESMF_LocalArray), allocatable :: larrayRefList(:)!LocalArray obj. list + + type(ESMF_VM):: vm + integer:: localPet, petCount ++ +
+
+ call ESMF_Initialize(vm=vm, defaultlogfilename="ArrayLarrayEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + if (petCount /= 4) then + finalrc = ESMF_FAILURE + goto 10 + endif ++ +
+DistGrid and array allocation remains unchanged. + +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/40,10/), rc=rc) ++ +
+
+ allocate(farrayP(14,14)) ! allocate Fortran array on each PET with halo ++ +
+Now instead of directly creating an Array object using the PET-local + farrayPs an ESMF_LocalArray object will be created on each PET. +
+
+ larray = ESMF_LocalArrayCreate(farrayP, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) ++ +
+The Array object can now be created from larray. The Array + creation method checks for each PET that the LocalArray can + accommodate the requested regions. +
+
+ array = ESMF_ArrayCreate(localarrayList=(/larray/), distgrid=distgrid, rc=rc) ++ +
+Once created there is no difference in how the Array object can be used. + The exclusive Array region on each PET can be accessed through a suitable + Fortran array pointer as before. +
+
+ call ESMF_ArrayGet(array, farrayPtr=farrayPtr, rc=rc) ++ +
+Alternatively it is also possible (independent of how the Array object was + created) to obtain the reference to the array allocation held by Array in + form of an ESMF_LocalArray object. The farrayPtr can then be + extracted using LocalArray methods. +
+
+ call ESMF_ArrayGet(array, localarray=larrayRef, rc=rc) ++ +
+
+ call ESMF_LocalArrayGet(larrayRef, farrayPtr, rc=rc) ++ +
+Either way the farrayPtr reference can be used now to add up the values + of the local exclusive region for each DE. The following loop + works regardless of how the bounds were chosen for the original PET-local + farrayP arrays and consequently the PET-local larray objects. +
+
+ localSum = 0. + do j=1, 10 + do i=1, 10 + localSum = localSum + farrayPtr(i, j) + enddo + enddo + print *, "localSum=", localSum ++ +
+Cleanup. +
+
+ call ESMF_ArrayDestroy(array, rc=rc) + call ESMF_LocalArrayDestroy(larray, rc=rc) + deallocate(farrayP) ! use the pointer that was used in allocate statement + call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+While the usage of LocalArrays is unnecessarily cumbersome for 1 DE per PET + Arrays, it provides a straightforward path for extending the interfaces + to multiple DEs per PET. + +
+In the following example a 8 x 8 index space will be decomposed into + 2 x 4 = 8 DEs. The situation is captured by the following DistGrid object. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/8,8/), & + regDecomp=(/2,4/), rc=rc) ++ +
+The distgrid object created in this manner will contain 8 DEs no + matter how many PETs are available during execution. Assuming an execution + on 4 PETs will result in the following distribution of the decomposition. + +
+
+ + +---------------------------------------> 2nd dimension + | (1,1) + | +-----------+-----------+-----------+-----------+ + | | DE0, PET0 | DE2, PET1 | DE4, PET2 | DE6, PET3 | + | | * * | * * | * * | * * | + | | | | | | + | | * * | * * | * * | * * | + | | | | | | + | | * * | * * | * * | * * | + | | | | | | + | | * * | * * | * * | * * | + | +-----------+-----------+-----------+-----------+ + | | DE1, PET0 | DE3, PET1 | DE5, PET2 | DE7, PET3 | + | | * * | * * | * * | * * | + | | | | | | + | | * * | * * | * * | * * | + | | | | | | + | | * * | * * | * * | * * | + | | | | | | + | | * * | * * | * * | * * | + | +-----------+-----------+-----------+-----------+ + | (8,8) + v + 1st dimension ++ +
+Obviously each PET is associated with 2 DEs. Each PET must allocate enough + space for all its DEs. This is done by allocating + as many DE-local arrays as there are DEs on the PET. The reference to these + array allocations is passed into ArrayCreate via a LocalArray list argument + that holds as many elements as there are DEs on the PET. Here each PET must + allocate for two DEs. + +
+
+ allocate(larrayList(2)) ! 2 DEs per PET + allocate(farrayP(4, 2)) ! without halo each DE is of size 4 x 2 + farrayP = 123.456d0 + larrayList(1) = ESMF_LocalArrayCreate(farrayP, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) !1st DE + allocate(farrayP(4, 2)) ! without halo each DE is of size 4 x 2 + farrayP = 456.789d0 + larrayList(2) = ESMF_LocalArrayCreate(farrayP, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) !2nd DE ++ +
+Notice that it is perfectly fine to re-use farrayP for all + allocations of DE-local Fortran arrays. The allocated memory can be + deallocated at the end using the array pointer contained in the + larrayList. + +
+With this information an Array object can be created. The distgrid + object indicates 2 DEs for each PET and ArrayCreate() expects to find two + LocalArray elements in larrayList. +
+
+ array = ESMF_ArrayCreate(localarrayList=larrayList, distgrid=distgrid, rc=rc) ++ +
+Usage of a LocalArray list is the only way to provide a list of variable + length of Fortran array allocations to ArrayCreate() for each PET. The + array object created by the above call is an ESMF distributed + object. As such it must follow the ESMF convention that requires that + the call to ESMF_ArrayCreate() must be issued in unison by all + PETs of the current context. Each PET only calls ArrayCreate() once, even if + there are multiple DEs per PET. + +
+The ArrayGet() method provides access to the list of LocalArrays on each PET. +
+
+ allocate(larrayRefList(2)) + call ESMF_ArrayGet(array, localarrayList=larrayRefList, rc=rc) ++ +
+Finally, access to the actual Fortran pointers is done on a per DE basis. + Generally each PET will loop over its DEs. +
+
+ do de=1, 2 + call ESMF_LocalArrayGet(larrayRefList(de), farrayPtr, rc=rc) + localSum = 0. + do j=1, 2 + do i=1, 4 + localSum = localSum + farrayPtr(i, j) + enddo + enddo + print *, "localSum=", localSum + enddo ++ +
+Note: If the VM associates multiple PEs with a PET the application writer + may decide to use OpenMP loop parallelization on the de loop. + +
+Cleanup requires that the PET-local deallocations are done before the + pointers to the actual Fortran arrays are lost. Notice that larrayList + is used to obtain the pointers used in the deallocate statement. Pointers + obtained from the larrayRefList, while pointing to the same data, + cannot be used to deallocate the array allocations! +
+
+ do de=1, 2 + call ESMF_LocalArrayGet(larrayList(de), farrayPtr, rc=rc) ++ +
+
+ deallocate(farrayPtr) + call ESMF_LocalArrayDestroy(larrayList(de), rc=rc) ++ +
+
+ enddo + deallocate(larrayList) + deallocate(larrayRefList) + call ESMF_ArrayDestroy(array, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + call ESMF_DistGridDestroy(distgrid, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+With that ESMF can be shut down cleanly. +
+
+ call ESMF_Finalize(rc=rc) ++ +
+
+end program ++ +
+ + +
+ +
+ +
+ +
+In the examples of the previous sections the user provided memory allocations + for each of the DE-local regions for an Array object. The user was able to + use any of the Fortran methods to allocate memory, or go through + the ESMF_LocalArray interfaces to obtain memory allocations before + passing them into ArrayCreate(). Alternatively ESMF offers methods that + handle Array memory allocations inside the library. + +
+As before, to create an ESMF_Array object an ESMF_DistGrid + must be created. The DistGrid object holds information about the entire + index space and how it is decomposed into DE-local exclusive regions. The + following line of code creates a DistGrid for a 5x5 global index space that + is decomposed into 2 x 3 = 6 DEs. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + regDecomp=(/2,3/), rc=rc) ++ +
+The following is a representation of the index space and its decomposition into + DEs. Each asterisk (*) represents a single element. + +
+
+ + +---------------------------------------> 2nd dimension + | (1,1) + | +-----------+-----------+------+ + | | DE 0 | DE 2 | DE 4 | + | | | | | + | | * * | * * | * | + | | | | | + | | * * | * * | * | + | | | | | + | | * * | * * | * | + | +-----------+-----------+------+ + | | | | | + | | DE 1 | DE 3 | DE 5 | + | | | | | + | | * * | * * | * | + | | | | | + | | * * | * * | * | + | +-----------+-----------+------+ + | (5,5) + v + 1st dimension ++ +
+Besides the DistGrid it is the type, kind and rank information, + "tkr" for short, that is required to create an Array object. It turns out that + the rank of the Array object is fully determined by the DistGrid and other + (optional) arguments passed into ArrayCreate(), so that explicit + specification of the Array rank is redundant. + +
+The simplest way to supply the type and kind information of the Array is + directly through the typekind argument. Here a double precision Array + is created on the previously created DistGrid. Since no other arguments are + specified that could alter the rank of the Array it becomes equal to the + dimCount of the DistGrid, i.e a 2D Array is created on top of the DistGrid. +
+
+ array = ESMF_ArrayCreate(typekind=ESMF_TYPEKIND_R8, distgrid=distgrid, rc=rc) ++ +
+The different methods on how an Array object is created have no effect on + the use of ESMF_ArrayDestroy(). +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+Alternatively the same Array can be created specifying the "tkr" information + in form of an ArraySpec variable. The ArraySpec explicitly contains the + Array rank and thus results in an over specification on the ArrayCreate() + interface. ESMF checks all input information for consistency and returns + appropriate error codes in case any inconsistencies are found. +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=2, rc=rc) ++ +
+
+ array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, rc=rc) ++ +
+The Array object created by the above call is an ESMF distributed + object. As such it must follow the ESMF convention that requires that + the call to ESMF_ArrayCreate() must be issued in unison by all + PETs of the current context. + +
+ +
+There are two different methods by which the user can access the data held + inside an ESMF Array object. The first method provides direct access to a + native language array object. Specifically, the farrayPtr argument + returned by ESMF_ArrayGet() is a Fortran array pointer that can be + used to access the PET-local data inside the Array object. + +
+Many applications work in the 1 DE per PET mode, with exactly one DE on + every PET. Accessing the Array memory on each PET for this situation is + especially simple as is shown in section 28.2.1. + However, the Array class is not restricted to the special 1 DE per PET case, + but supports multiple separate memory allocations on each PET. + The number of such PET-local allocations is given by the localDeCount, + i.e. there is one memory allocation for every DE that is associated with the + local PET. + +
+Access to a specific local memory allocation of an Array object is still + accomplished by returning the farrayPtr argument. However, for + + the formally optional localDe argument to + ESMF_ArrayGet() turns into a practically required argument. While + in general the localDe in ESMF is simply a local index variable that + enumerates the DEs that are associated with the local PET (e.g. see section + 50.3.7), the bounds of this index variable are + strictly defined as [0,...,localDeCount-1] when it is used as an + input argument. The following code demonstrates this. + +
+First query the Array for localDeCount. This number may be different + on each PET and indicates how many DEs are mapped against the local PET. +
+
+ call ESMF_ArrayGet(array, localDeCount=localDeCount, rc=rc) ++ +
+Looping the localDe index variable from 0 to localDeCount-1 allows + access to each of the local memory allocations of the Array object: +
+
+ do localDe=0, localDeCount-1 + call ESMF_ArrayGet(array, farrayPtr=myFarray, localDe=localDe, rc=rc) ++ +
+
+ ! use myFarray to access local DE data + enddo ++ +
+The second method to access the memory allocations in an Array object is to + go through the ESMF LocalArray object. To this end the Array is queried + for a list of PET-local LocalArray objects. The LocalArray objects in the list + correspond to the DEs on the local PET. Here the localDe argument is + solely a user level index variable, and in principle the lower bound can be + chosen freely. However, for better alignment with the previous case (where + localDe served as an input argument to an ESMF method) the following + example again fixes the lower bound at zero. +
+
+ allocate(larrayList(0:localDeCount-1)) + call ESMF_ArrayGet(array, localarrayList=larrayList, rc=rc) ++ +
+
+ do localDe=0, localDeCount-1 + call ESMF_LocalArrayGet(larrayList(localDe), myFarray, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) ++ +
+
+ ! use myFarray to access local DE data + enddo ++ +
+See section 28.2.3 for more on LocalArray usage in Array. + In most cases memory access through a LocalArray list is less convenient than + the direct farrayPtr method because it adds an extra object level + between the ESMF Array and the native language array. + +
+ +
+Each ESMF_Array object is decomposed into DEs as specified by the + associated ESMF_DistGrid object. Each piece of this decomposition, i.e. + each DE, holds a chunk of the Array data in its own local piece of memory. + The details of the Array decomposition are described in the following + paragraphs. + +
+At the center of the Array decomposition is the ESMF_DistGrid class. + The DistGrid object specified during Array creation contains three essential + pieces of information: + +
+Each element of an Array is associated with a single DE. The union of + elements associated with a DE, as defined by the DistGrid above, corresponds + to a LR chunk of index space, called the exclusive region of the DE. + +
+There is a hierarchy of four regions that can be identified for each DE in an + Array object. Their definition and relationship to each other is as follows: + +
+
+ + +-totalLBound(:)----------------------------------+ + |\ | + | \ <--- totalLWidth(:) | + | \ | + | +-computationalLBound(:)------------------+ | + | |\ | | + | | \ <--- computationalLWidth(:) | | + | | \ | | + | | +-exclusiveLBound(:)-------------+ | | + | | | | | | + | | | +------+ +-----+ | | | + | | | | | | | | | | + | | | | +------+ | | | | + | | | | "Interior Region" | | | | + | | | +-----+ | | | | + | | | | | | | | + | | | +-------------+ | | | + | | | | | | + | | | "Exclusive Region" | | | + | | +-------------exclusiveUBound(:)-+ | | + | | \ | | + | | computationalUWidth(:) --> \ | | + | | \ | | + | | "Computational Region" \| | + | +------------------computationalUBound(:)-+ | + | \ | + | totalUWidth(:) -> \ | + | "Total Region" \| + +--------------------------------- totalUBound(:)-+ ++ +
+With the following definitions: +
+ + computationalLWidth(:) = exclusiveLBound(:) - computationalLBound(:) + computationalUWidth(:) = computationalUBound(:) - exclusiveUBound(:) ++ and +
+ + totalLWidth(:) = exclusiveLBound(:) - totalLBound(:) + totalUWidth(:) = totalUBound(:) - exclusiveUBound(:) ++ +
+The exclusive region is determined during Array creation by the + DistGrid argument. Optional arguments may be used to specify the + computational region when the Array is created, by default it will be + set equal to the exclusive region. The total region, i.e. the actual + memory allocation for each DE, is also determined during Array creation. When + creating the Array object from existing Fortran arrays the total region is + set equal to the memory provided by the Fortran arrays. Otherwise the + default is to allocate as much memory as is needed to accommodate the union + of the DE-local exclusive and computational region. Finally it is also + possible to use optional arguments to the ArrayCreate() call to specify the + total region of the object explicitly. + +
+The ESMF_ArrayCreate() call checks that the input parameters are + consistent and will result in an Array that fulfills all of the above + mentioned requirements for its DE-local regions. + +
+Once an Array object has been created the exclusive and total regions are + fixed. The computational region, however, may be adjusted within the limits + of the total region using the ArraySet() call. + +
+The interior region is very different from the other regions in that + it cannot be specified. The interior region for each DE is a consequence of the choices made for the other regions collectively across + all DEs into which an Array object is decomposed. An Array object can be + queried for its DE-local interior regions as to offer additional + information to the user necessary to write more efficient code. + +
+By default the bounds of each DE-local total region are defined as + to put the start of the DE-local exclusive region at the "origin" of + the local index space, i.e. at (1, 1, ..., 1). With that definition the + following loop will access each element of the DE-local memory segment for + each PET-local DE of the Array object used in the previous sections and + print its content. +
+
+ do localDe=0, localDeCount-1 + call ESMF_LocalArrayGet(larrayList(localDe), myFarray, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) + do i=1, size(myFarray, 1) + do j=1, size(myFarray, 2) + print *, "localPET=", localPet, " localDE=", & + localDe, ": array(",i,",",j,")=", myFarray(i,j) + enddo + enddo + enddo ++ +
+ +
+The loop over Array elements at the end of the last section only works + correctly because of the default definition of the computational and + total regions used in the example. In general, without such specific + knowledge about an Array object, it is necessary to use a more formal approach + to access its regions with DE-local indices. + +
+The DE-local exclusive region takes a central role in the definition + of Array bounds. Even as the computational region may adjust during + the course of execution the exclusive region remains unchanged. + The exclusive region provides a unique reference frame + for the index space of all Arrays associated with the same DistGrid. + +
+There is a choice between two indexing options that needs to be made during + Array creation. By default each DE-local exclusive region starts at + (1, 1, ..., 1). However, for some computational kernels it may be more + convenient to choose the index bounds of the DE-local exclusive regions to + match the index space coordinates as they are defined in the corresponding + DistGrid object. The second option is only available if the DistGrid object + does not contain any non-contiguous decompositions (such as cyclically + decomposed dimensions). + +
+The following example code demonstrates the safe way of dereferencing the + DE-local exclusive regions of the previously created array object. + +
+
+ allocate(exclusiveUBound(2, 0:localDeCount-1)) ! dimCount=2 + allocate(exclusiveLBound(2, 0:localDeCount-1)) ! dimCount=2 + call ESMF_ArrayGet(array, indexflag=indexflag, & + exclusiveLBound=exclusiveLBound, exclusiveUBound=exclusiveUBound, rc=rc) + if (indexflag == ESMF_INDEX_DELOCAL) then + ! this is the default +! print *, "DE-local exclusive regions start at (1,1)" + do localDe=0, localDeCount-1 + call ESMF_LocalArrayGet(larrayList(localDe), myFarray, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) + do i=1, exclusiveUBound(1, localDe) + do j=1, exclusiveUBound(2, localDe) +! print *, "DE-local exclusive region for localDE=", localDe, & +! ": array(",i,",",j,")=", myFarray(i,j) + enddo + enddo + enddo + else if (indexflag == ESMF_INDEX_GLOBAL) then + ! only if set during ESMF_ArrayCreate() +! print *, "DE-local exclusive regions of this Array have global bounds" + do localDe=0, localDeCount-1 + call ESMF_LocalArrayGet(larrayList(localDe), myFarray, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) + do i=exclusiveLBound(1, localDe), exclusiveUBound(1, localDe) + do j=exclusiveLBound(2, localDe), exclusiveUBound(2, localDe) +! print *, "DE-local exclusive region for localDE=", localDe, & +! ": array(",i,",",j,")=", myFarray(i,j) + enddo + enddo + enddo + endif + call ESMF_ArrayDestroy(array, rc=rc) ! destroy the array object ++ +
+Obviously the second branch of this simple code will work for either case, + however, if a complex computational kernel was written assuming + ESMF_INDEX_DELOCAL type bounds the second branch would simply be + used to indicate the problem and bail out. + +
+The advantage of the ESMF_INDEX_GLOBAL index option is that + the Array bounds directly contain information on where the DE-local + Array piece is located in a global index space sense. When the + ESMF_INDEX_DELOCAL option is used the correspondence between local + and global index space must be made by querying the associated DistGrid for + the DE-local indexList arguments. + +
+ +
+In the previous examples the computational region of array was chosen + by default to be identical to the exclusive region defined by the DistGrid + argument during Array creation. In the following the same arrayspec and + distgrid objects as before will be used to create an Array but now a + larger computational region shall be defined around each DE-local exclusive + region. Furthermore, extra space will be defined around the computational + region of each DE to accommodate a halo and/or serve as memory padding. + +
+In this example the indexflag argument is set to + ESMF_INDEX_GLOBAL indicating that the bounds of the exclusive region + correspond to the index space coordinates as they are defined by the DistGrid + object. + +
+The same arrayspec and distgrid objects as before are used + which also allows the reuse of the already allocated larrayList + variable. +
+
+ array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, & + computationalLWidth=(/0,3/), computationalUWidth=(/1,1/), & + totalLWidth=(/1,4/), totalUWidth=(/3,1/), & + indexflag=ESMF_INDEX_GLOBAL, rc=rc) ++ +
+Obtain the larrayList on every PET. +
+
+ allocate(localDeToDeMap(0:localDeCount-1)) + call ESMF_ArrayGet(array, localarrayList=larrayList, & + localDeToDeMap=localDeToDeMap, rc=rc) ++ +
+The bounds of DE 1 for array are shown in the following + diagram to illustrate the situation. Notice that the totalLWidth and + totalUWidth arguments in the ArrayCreate() call define the total region + with respect to the exclusive region given for each DE by the distgrid + argument. + +
+
+ +-(3,-3)---------------------------------+ + |\ | + | +-(4,-2)-+-(4,1)--------------------+--+ + | | | | | + | | | | | + | | | DE 1 | | + | | | | | + | | | | | + | | | Exclusive Region | | + | | +--------------------(5,2)-+ | + | | Computational Region | + | +-------------------------------(6,3)--+ + | | + | Total Region | + +---------------------------------(8,3)--+ ++ +
+When working with this array it is possible for the computational + kernel to overstep the exclusive region for both read/write access + (computational region) and potentially read-only access into the total region + outside of the computational region, if a halo operation provides valid + entries for these elements. + +
+The Array object can be queried for absolute bounds +
+
+ allocate(computationalLBound(2, 0:localDeCount-1)) ! dimCount=2 + allocate(computationalUBound(2, 0:localDeCount-1)) ! dimCount=2 + allocate(totalLBound(2, 0:localDeCount-1)) ! dimCount=2 + allocate(totalUBound(2, 0:localDeCount-1)) ! dimCount=2 + call ESMF_ArrayGet(array, exclusiveLBound=exclusiveLBound, & + exclusiveUBound=exclusiveUBound, & + computationalLBound=computationalLBound, & + computationalUBound=computationalUBound, & + totalLBound=totalLBound, & + totalUBound=totalUBound, rc=rc) ++ +
+or for the relative widths. +
+
+ allocate(computationalLWidth(2, 0:localDeCount-1)) ! dimCount=2 + allocate(computationalUWidth(2, 0:localDeCount-1)) ! dimCount=2 + allocate(totalLWidth(2, 0:localDeCount-1)) ! dimCount=2 + allocate(totalUWidth(2, 0:localDeCount-1)) ! dimCount=2 + call ESMF_ArrayGet(array, computationalLWidth=computationalLWidth, & + computationalUWidth=computationalUWidth, totalLWidth=totalLWidth, & + totalUWidth=totalUWidth, rc=rc) ++ +
+Either way the dereferencing of Array data is centered around the DE-local + exclusive region: +
+
+ do localDe=0, localDeCount-1 + call ESMF_LocalArrayGet(larrayList(localDe), myFarray, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) + ! initialize the DE-local array + myFarray = 0.1d0 * localDeToDeMap(localDe) + ! first time through the total region of array +! print *, "myFarray bounds for DE=", localDeToDeMap(localDe), & +! lbound(myFarray), ubound(myFarray) + do j=exclusiveLBound(2, localDe), exclusiveUBound(2, localDe) + do i=exclusiveLBound(1, localDe), exclusiveUBound(1, localDe) +! print *, "Excl region DE=", localDeToDeMap(localDe), & +! ": array(",i,",",j,")=", myFarray(i,j) + enddo + enddo + do j=computationalLBound(2, localDe), computationalUBound(2, localDe) + do i=computationalLBound(1, localDe), computationalUBound(1, localDe) +! print *, "Excl region DE=", localDeToDeMap(localDe), & +! ": array(",i,",",j,")=", myFarray(i,j) + enddo + enddo + do j=totalLBound(2, localDe), totalUBound(2, localDe) + do i=totalLBound(1, localDe), totalUBound(1, localDe) +! print *, "Total region DE=", localDeToDeMap(localDe), & +! ": array(",i,",",j,")=", myFarray(i,j) + enddo + enddo + + ! second time through the total region of array + do j=exclusiveLBound(2, localDe)-totalLWidth(2, localDe), & + exclusiveUBound(2, localDe)+totalUWidth(2, localDe) + do i=exclusiveLBound(1, localDe)-totalLWidth(1, localDe), & + exclusiveUBound(1, localDe)+totalUWidth(1, localDe) +! print *, "Excl region DE=", localDeToDeMap(localDe), & +! ": array(",i,",",j,")=", myFarray(i,j) + enddo + enddo + enddo ++ +
+ +
+All previous examples were written for the 2D case. There is, however, no + restriction within the Array or DistGrid class that limits the dimensionality + of Array objects beyond the language-specific limitations (7D for Fortran). + +
+In order to create an n-dimensional Array the rank indicated by both + the arrayspec and the distgrid arguments specified during Array + create must be equal to n. A 1D Array of double precision real data + hence requires the following arrayspec. +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=1, rc=rc) ++ +
+The index space covered by the Array and the decomposition description is + provided to the Array create method by the distgrid argument. The index + space in this example has 16 elements and covers the interval . It is + decomposed into as many DEs as there are PETs in the current context. +
+
+ distgrid1D = ESMF_DistGridCreate(minIndex=(/-10/), maxIndex=(/5/), & + regDecomp=(/petCount/), rc=rc) ++ +
+A 1D Array object with default regions can now be created. +
+
+ array1D = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid1D, rc=rc) ++ +
+The creation of a 3D Array proceeds analogous to the 1D case. The rank of the + arrayspec must be changed to 3 +
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=3, rc=rc) ++ +
+and an appropriate 3D DistGrid object must be created +
+ distgrid3D = ESMF_DistGridCreate(minIndex=(/1,1,1/), & + maxIndex=(/16,16,16/), regDecomp=(/4,4,4/), rc=rc) ++ +
+before an Array object can be created. +
+
+ array3D = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid3D, rc=rc) ++ +
+The distgrid3D object decomposes the 3-dimensional index space into + + DEs. These DEs are laid out across the computational + resources (PETs) of the current component according to a default DELayout that + is created during the DistGrid create call. Notice that in the index space + proposal a DELayout does not have a sense of dimensionality. The DELayout + function is simply to map DEs to PETs. The DistGrid maps chunks of index space + against DEs and thus its rank is equal to the number of index space + dimensions. + +
+The previously defined DistGrid and the derived Array object decompose + the index space along all three dimension. It is, however, not a requirement + that the decomposition be along all dimensions. An Array with the same 3D + index space could as well be decomposed along just one or along two of the + dimensions. The following example shows how for the same index space only the + last two dimensions are decomposed while the first Array dimension has full + extent on all DEs. +
+
+ call ESMF_ArrayDestroy(array3D, rc=rc) + call ESMF_DistGridDestroy(distgrid3D, rc=rc) + distgrid3D = ESMF_DistGridCreate(minIndex=(/1,1,1/), & + maxIndex=(/16,16,16/), regDecomp=(/1,4,4/), rc=rc) + array3D = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid3D, rc=rc) ++ +
+ +
+
+ call ESMF_DistGridGet(distgrid3D, delayout=delayout, rc=rc) ! get DELayout + distgrid2D = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/16,16/), & + regDecomp=(/4,4/), delayout=delayout, rc=rc) + call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=2, rc=rc) + array2D = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid2D, rc=rc) ++ +
+Now the following kernel is sure to work with array3D and array2D. +
+
+ call ESMF_DELayoutGet(delayout, localDeCount=localDeCount, rc=rc) + allocate(larrayList1(0:localDeCount-1)) + call ESMF_ArrayGet(array3D, localarrayList=larrayList1, rc=rc) + allocate(larrayList2(0:localDeCount-1)) + call ESMF_ArrayGet(array2D, localarrayList=larrayList2, rc=rc) + do localDe=0, localDeCount-1 + call ESMF_LocalArrayGet(larrayList1(localDe), myFarray3D, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) + myFarray3D = 0.1d0 * localDe ! initialize + call ESMF_LocalArrayGet(larrayList2(localDe), myFarray2D, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) + myFarray2D = 0.5d0 * localDe ! initialize + do k=1, 4 + do j=1, 4 + dummySum = 0.d0 + do i=1, 16 + dummySum = dummySum + myFarray3D(i,j,k) ! sum up the (j,k) column + enddo + dummySum = dummySum * myFarray2D(j,k) ! multiply with local 2D element +! print *, "dummySum(",j,k,")=",dummySum + enddo + enddo + enddo ++ +
+ +
+Except for the special Array create interface that implements a copy from + an existing Array object all other Array create interfaces require the + specification of at least two arguments: farray and distgrid, + larrayList and distgrid, or arrayspec and distgrid. + In all these cases both required arguments contain a sense of dimensionality. + The relationship between these two arguments deserves extra attention. + +
+The first argument, farray, larrayList or arrayspec, + determines the rank of the created Array object, i.e. the dimensionality + of the actual data storage. The rank of a native language array, extracted + from an Array object, is equal to the rank specified by either of these + arguments. So is the rank that is returned by the ESMF_ArrayGet() + call. + +
+The rank specification contained in the distgrid argument, which is of + type ESMF_DistGrid, on the other hand has no effect on the + rank of the Array. The dimCount specified by the DistGrid object, + which may be equal, greater or less than the Array rank, determines the + dimensionality of the decomposition. + +
+While there is no constraint between DistGrid dimCount and Array + rank, there is an important relationship between the two, resulting in + the concept of index space dimensionality. Array dimensions can be + arbitrarily mapped against DistGrid dimension, rendering them decomposed + dimensions. The index space dimensionality is equal to the number of + decomposed Array dimensions. + +
+Array dimensions that are not mapped to DistGrid dimensions are the + undistributed dimensions of the Array. They are not part + of the index space. The mapping is specified during ESMF_ArrayCreate() + via the distgridToArrayMap argument. DistGrid dimensions that have + not been associated with Array dimensions are replicating dimensions. + The Array will be replicated across the DEs that lie along replication + DistGrid dimensions. + +
+Undistributed Array dimensions can be used to store multi-dimensional data for + each Array index space element. One application of this is to store the + components of a vector quantity in a single Array. The same 2D distgrid + object as before will be used. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + regDecomp=(/2,3/), rc=rc) ++ +
+The rank in the arrayspec argument, however, must change from 2 to 3 in + order to provide for the extra Array dimension. +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=3, rc=rc) ++ +
+During Array creation with extra dimension(s) it is necessary to specify the + bounds of these undistributed dimension(s). This requires two additional + arguments, undistLBound and undistUBound, which are vectors in + order to accommodate multiple undistributed dimensions. The other arguments + remain unchanged and apply across all undistributed components. + +
+
+ array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, & + totalLWidth=(/0,1/), totalUWidth=(/0,1/), & + undistLBound=(/1/), undistUBound=(/2/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+This will create array with 2+1 dimensions. The 2D DistGrid is used + to describe decomposition into DEs with 2 Array dimensions mapped to the + DistGrid dimensions resulting in a 2D index space. The extra Array dimension + provides storage for multi component user data within the Array object. + +
+By default the distgrid dimensions are associated + with the first Array dimensions in sequence. For the example above this means + that the first 2 Array dimensions are decomposed according to the provided 2D + DistGrid. The 3rd Array dimension does not have an associated DistGrid + dimension, rendering it an undistributed Array dimension. + +
+Native language access to an Array with undistributed dimensions is in + principle the same as without extra dimensions. +
+
+ call ESMF_ArrayGet(array, localDeCount=localDeCount, rc=rc) + allocate(larrayList(0:localDeCount-1)) + call ESMF_ArrayGet(array, localarrayList=larrayList, rc=rc) ++ +
+The following loop shows how a Fortran pointer to the DE-local data chunks + can be obtained and used to set data values in the exclusive regions. The + myFarray3D variable must be of rank 3 to match the Array rank of + array. However, variables such as exclusiveUBound that store the + information about the decomposition, remain to be allocated for the 2D + index space. +
+
+ call ESMF_ArrayGet(array, exclusiveLBound=exclusiveLBound, & + exclusiveUBound=exclusiveUBound, rc=rc) + do localDe=0, localDeCount-1 + call ESMF_LocalArrayGet(larrayList(localDe), myFarray3D, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) + myFarray3D = 0.0 ! initialize + myFarray3D(exclusiveLBound(1,localDe):exclusiveUBound(1,localDe), & + exclusiveLBound(2,localDe):exclusiveUBound(2,localDe), & + 1) = 5.1 ! dummy assignment + myFarray3D(exclusiveLBound(1,localDe):exclusiveUBound(1,localDe), & + exclusiveLBound(2,localDe):exclusiveUBound(2,localDe), & + 2) = 2.5 ! dummy assignment + enddo + deallocate(larrayList) ++ +
+For some applications the default association rules between DistGrid and Array + dimensions may not satisfy the user's needs. The optional distgridToArrayMap + argument can be used during Array creation to explicitly specify the mapping + between DistGrid and Array dimensions. To demonstrate this the following lines + of code reproduce the above example but with rearranged dimensions. Here the + distgridToArrayMap argument is a list with two elements corresponding to + the DistGrid dimCount of 2. The first element indicates which Array + dimension the first DistGrid dimension is mapped against. Here the + 1st DistGrid dimension maps against the 3rd Array dimension and the 2nd + DistGrid dimension maps against the 1st Array dimension. This leaves the 2nd + Array dimension to be the extra and undistributed dimension in the resulting + Array object. +
+
+ call ESMF_ArrayDestroy(array, rc=rc) + array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, & + distgridToArrayMap=(/3, 1/), totalLWidth=(/0,1/), totalUWidth=(/0,1/), & + undistLBound=(/1/), undistUBound=(/2/), rc=rc) ++ +
+Operations on the Array object as a whole are unchanged by the different + mapping of dimensions. + +
+When working with Arrays that contain explicitly mapped Array and DistGrid + dimensions it is critical to know the order in which the entries of + width and bound arguments that are associated with distributed + Array dimensions are specified. The size of these arguments is equal to the + DistGrid dimCount, because the maximum number of distributed Array + dimensions is given by the dimensionality of the index space. + +
+The order of dimensions in these arguments, however, is not that of + the associated DistGrid. Instead each entry corresponds to the distributed + Array dimensions in sequence. In the example above the entries in + totalLWidth and totalUWidth correspond to Array dimensions 1 and + 3 in this sequence. + +
+The distgridToArrrayMap argument optionally provided during Array create + indicates how the DistGrid dimensions map to Array dimensions. The inverse + mapping, i.e. Array to DistGrid dimensions, is just as important. The + ESMF_ArrayGet() call offers both mappings as distgridToArrrayMap + and arrayToDistGridMap, respectively. The number of elements in + arrayToDistGridMap is equal to the rank of the Array. Each element + corresponds to an Array dimension and indicates the associated DistGrid + dimension by an integer number. An entry of "0" in arrayToDistGridMap + indicates that the corresponding Array dimension is undistributed. + +
+Correct understanding about the association between Array and DistGrid + dimensions becomes critical for correct data access into the Array. +
+
+ allocate(arrayToDistGridMap(3)) ! arrayRank = 3 + call ESMF_ArrayGet(array, arrayToDistGridMap=arrayToDistGridMap, & + exclusiveLBound=exclusiveLBound, exclusiveUBound=exclusiveUBound, & + localDeCount=localDeCount, rc=rc) + if (arrayToDistGridMap(2) /= 0) then ! check if extra dimension at + ! expected index indicate problem and bail out + endif + ! obtain larrayList for local DEs + allocate(larrayList(0:localDeCount-1)) + call ESMF_ArrayGet(array, localarrayList=larrayList, rc=rc) + do localDe=0, localDeCount-1 + call ESMF_LocalArrayGet(larrayList(localDe), myFarray3D, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) + myFarray3D(exclusiveLBound(1,localDe):exclusiveUBound(1,localDe), & + 1, exclusiveLBound(2,localDe):exclusiveUBound(2, & + localDe)) = 10.5 !dummy assignment + myFarray3D(exclusiveLBound(1,localDe):exclusiveUBound(1,localDe), & + 2, exclusiveLBound(2,localDe):exclusiveUBound(2, & + localDe)) = 23.3 !dummy assignment + enddo + deallocate(exclusiveLBound, exclusiveUBound) + deallocate(arrayToDistGridMap) + deallocate(larrayList) + call ESMF_ArrayDestroy(array, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+Thus far most examples demonstrated cases where the DistGrid dimCount + was equal to the Array rank. The previous section introduced the + concept of Array tensor dimensions when dimCount < rank. In this + section dimCount and rank are assumed completely unconstrained and + the relationship to distgridToArrayMap and arrayToDistGridMap will + be discussed. + +
+The Array class allows completely arbitrary mapping between Array and + DistGrid dimensions. Most cases considered in the previous sections used + the default mapping which assigns the DistGrid dimensions in sequence to the + lower Array dimensions. Extra Array dimensions, if present, are considered + non-distributed tensor dimensions for which the optional undistLBound + and undistUBound arguments must be specified. + +
+The optional distgridToArrayMap argument provides the option to override + the default DistGrid to Array dimension mapping. The entries of the + distgridToArrayMap array correspond to the DistGrid dimensions in + sequence and assign a unique Array dimension to each DistGrid dimension. + DistGrid and Array dimensions are indexed starting at 1 for the lowest + dimension. A value of "0" in the distgridToArrayMap array + indicates that the respective DistGrid dimension is not mapped against + any Array dimension. What this means is that the Array will be replicated + along this DistGrid dimension. + +
+As a first example consider the case where a 1D Array +
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=1, rc=rc) ++ +
+is created on the 2D DistGrid used during the previous section. +
+
+ array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, rc=rc) ++ +
+Here the default DistGrid to Array dimension mapping is used which assigns + the Array dimensions in sequence to the DistGrid dimensions starting with + dimension "1". Extra DistGrid dimensions are considered replicator dimensions + because the Array will be replicated along those dimensions. In the above + example the 2nd DistGrid dimension will cause 1D Array pieces to be + replicated along the DEs of the 2nd DistGrid dimension. Replication in the + context of ESMF_ArrayCreate() does not mean that data values are + communicated and replicated between different DEs, but it means that different + DEs provide memory allocations for identical exclusive elements. + +
+Access to the data storage of an Array that has been replicated along + DistGrid dimensions is the same as for Arrays without replication. +
+
+ call ESMF_ArrayGet(array, localDeCount=localDeCount, rc=rc) ++ +
+
+ allocate(larrayList(0:localDeCount-1)) + allocate(localDeToDeMap(0:localDeCount-1)) + call ESMF_ArrayGet(array, localarrayList=larrayList, & + localDeToDeMap=localDeToDeMap, rc=rc) ++ +
+The array object was created without additional padding which means + that the bounds of the Fortran array pointer correspond to the bounds of + the exclusive region. The following loop will cycle through all local DEs, + print the DE number as well as the Fortran array pointer bounds. The bounds + should be: +
+ lbound ubound + + DE 0: 1 3 --+ + DE 2: 1 3 --| 1st replication set + DE 4: 1 3 --+ + + DE 1: 1 2 --+ + DE 3: 1 2 --| 2nd replication set + DE 5: 1 2 --+ ++
+
+ do localDe=0, localDeCount-1 + call ESMF_LocalArrayGet(larrayList(localDe), myFarray1D, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) ++ +
+
+ print *, "localPet: ", localPet, "DE ",localDeToDeMap(localDe)," [", & + lbound(myFarray1D), ubound(myFarray1D),"]" + enddo + deallocate(larrayList) + deallocate(localDeToDeMap) + call ESMF_ArrayDestroy(array, rc=rc) ++ +
+The Fortran array pointer in the above loop was of rank 1 because the + Array object was of rank 1. However, the distgrid object associated + with array is 2-dimensional! Consequently DistGrid based information + queried from array will be 2D. The distgridToArrayMap and + arrayToDistGridMap + arrays provide the necessary mapping to correctly associate DistGrid based + information with Array dimensions. + +
+The next example creates a 2D Array +
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=2, rc=rc) ++ +
+on the previously used 2D DistGrid. By default, i.e. without the + distgridToArrayMap + argument, both DistGrid dimensions would be associated with the two Array + dimensions. However, the distgridToArrayMap specified in the following + call will only associate the second DistGrid dimension with the first Array + dimension. This will render the first DistGrid dimension a replicator + dimension and the second Array dimension a tensor dimension for which 1D + undistLBound and undistUBound arguments must be supplied. +
+
+ array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, & + distgridToArrayMap=(/0,1/), undistLBound=(/11/), & + undistUBound=(/14/), rc=rc) ++ +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+Finally, the same arrayspec and distgrid arguments are used to + create a 2D Array that is fully replicated in both dimensions of the DistGrid. + Both Array dimensions are now tensor dimensions and both DistGrid dimensions + are replicator dimensions. +
+
+ array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, & + distgridToArrayMap=(/0,0/), undistLBound=(/11,21/), & + undistUBound=(/14,22/), rc=rc) ++ +
+The result will be an Array with local lower bound (/11,21/) and upper bound + (/14,22/) on all 6 DEs of the DistGrid. +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+Replicated Arrays can also be created from existing local Fortran arrays. + The following Fortran array allocation will provide a 3 x 10 array on each + PET. +
+
+ allocate(myFarray2D(3,10)) ++ +
+Assuming a petCount of 4 the following DistGrid defines a 2D index space + that is distributed across the PETs along the first dimension. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/40,10/), rc=rc) ++ +
+The following call creates an Array object on the above distgrid using + the locally existing myFarray2D Fortran arrays. The difference + compared to the case with automatic memory allocation is that instead of + arrayspec the Fortran array is provided as argument. Furthermore, + the undistLBound and undistUBound arguments can be omitted, + defaulting into Array tensor dimension lower bound of 1 and an upper + bound equal to the size of the respective Fortran array dimension. +
+
+ array = ESMF_ArrayCreate(farray=myFarray2D, distgrid=distgrid, & + indexflag=ESMF_INDEX_DELOCAL, distgridToArrayMap=(/0,2/), rc=rc) ++ +
+The array object associates the 2nd DistGrid dimension with the 2nd + Array dimension. The first DistGrid dimension is not associated with any + Array dimension and will lead to replication of the Array along the DEs of + this direction. +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+ +
+Practically all modern computer systems today utilize multi-core processors, + supporting the concurrent execution of multiple hardware threads. + A number of these multi-core processors are commonly packaged into the same + compute node, having access to the same physical memory. Under ESMF each + hardware thread (or core) is identified as a unique Processing Element (PE). + The collection of PEs that share the same physical memory (i.e. compute node) + is referred to as a Single System Image (SSI). The ESMF Array class implements + features that allow the user to leverage the shared memory within each SSI to + efficiently exchange data without copies or explicit communication calls. + +
+The software threads executing an ESMF application on the hardware, and that + ESMF is aware of, are referred to as Persistent Execution Threads (PETs). In + practice a PET can typically be thought of as an MPI rank, i.e. an OS process, + defining its own private virtual address space (VAS). + The ESMF Virtual Machine (VM) class keeps track of the mapping between PETs + and PEs, and their location on the available SSIs. + +
+When an ESMF Array object is created, the specified DistGrid indicates how + many Decomposition Elements (DEs) are created. Each DE has its own memory + allocation to hold user data. The DELayout, referenced by the DistGrid, + determines which PET is considered the owner of each of the DEs. Queried + for the local DEs, the Array object returns the list of DEs that are owned by + the local PET making the query. + +
+By default DEs are pinned to the PETs under which they were created. + The memory allocation associated with a specific DE is only defined in the + VAS of the PET to which the DE is pinned. As a consequence, only the PET + owning a DE has access to its memory allocation. + +
+On shared memory systems, however, ESMF allows DEs to be pinned to SSIs + instead of PETs. In this case the PET under which a DE was created is still + consider the owner, but now all PETs under the same SSI have access to + the DE. For this the memory allocation associated with the DE is mapped into + the VAS of all the PETs under the SSI. + +
+To create an Array with each DE pinned to SSI instead of PET, first query the + VM for the available level of support. +
+
+ call ESMF_VMGet(vm, ssiSharedMemoryEnabledFlag=ssiSharedMemoryEnabled, rc=rc) ++ +
+
+ if (ssiSharedMemoryEnabled) then ++ +
+Knowing that the SSI shared memory feature is available, it is now possible + to create an Array object with DE to SSI pinning. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/40,10/), rc=rc) ++ +
+
+ array = ESMF_ArrayCreate(typekind=ESMF_TYPEKIND_R8, distgrid=distgrid, & + pinflag=ESMF_PIN_DE_TO_SSI, rc=rc) ++ +
+Just as in the cases discussed before, where the same DistGrid was used, a + default DELayout with as many DEs as PETs in the VM is constructed. Setting + the pinflag to ESMF_PIN_DE_TO_SSI does not change the + fact that each PET owns exactly one of the DEs. However, assuming that this + code is run on a set of PETs that are all located under the same SSI, every + PET now has access to all of the DEs. The situation can be observed by + querying for both the localDeCount, and the ssiLocalDeCount. +
+
+ call ESMF_ArrayGet(array, localDeCount=localDeCount, & + ssiLocalDeCount=ssiLocalDeCount, rc=rc) ++ +
+Assuming execution on 4 PETs, all located on the same SSI, the values of the + returned variable are localDeCount==1 and ssiLocalDeCount==4 on + all of the PETs. The mapping between each PET's local DE, and the global DE + index is provided through the localDeToDeMap array argument. The amount + of mapping information returned is dependent on how large localDeToDeMap + has been sized by the user. For size(localDeToDeMap)==localDeCount, + only mapping information for those DEs owned by the local PET is filled + in. However for size(localDeToDeMap)==ssiLocalDeCount, mapping + information for all locally accessible DEs is returned, including + those owned by other PETs on the same SSI. + +
+
+ allocate(localDeToDeMap(0:ssiLocalDeCount-1)) + call ESMF_ArrayGet(array, localDeToDeMap=localDeToDeMap, rc=rc) ++ +
+The first localDeCount entries of localDeToDeMap are always the + global DE indices of the DEs owned by the local PET. The remaining + ssiLocalDeCount-localDeCount entries are the global DE indices of + DEs shared by other PETs. The ordering of the shared DEs is from + smallest to greatest, excluding the locally owned DEs, which were already + listed at the beginning of localDeToDeMap. For the current case, again + assuming execution on 4 PETs all located on the same SSI, we expect the + following situation: + +
+PET 0: localDeToDeMap==(/0,1,2,3/)
+
+PET 1: localDeToDeMap==(/1,0,2,3/)
+
+PET 2: localDeToDeMap==(/2,0,1,3/)
+
+PET 3: localDeToDeMap==(/3,0,1,2/)
+
+
+
+Each PET can access the memory allocations associated with all of the + DEs listed in the localDeToDeMap returned by the Array object. Direct + access to the Fortran array pointer of a specific memory allocation is + available through ESMF_ArrayGet(). Here each PET queries for the + farrayPtr of localDe==2, i.e. the 2nd shared DE. +
+
+ call ESMF_ArrayGet(array, farrayPtr=myFarray, localDe=2, rc=rc) ++ +
+Now variable myFarray on PETs 0 and 1 both point to the same + memory allocation for global DE 2. Both PETs have access to the same + piece of shared memory! The same is true for PETs 2 and 3, pointing to the + shared memory allocation of global DE 1. + +
+It is important to note that all of the typical considerations surrounding + shared memory programming apply when accessing shared DEs! Proper + synchronization between PETs accessing shared DEs is critical to avoid + race conditions. Also performance issues like false sharing + need to be considered for optimal use. + +
+For a simple demonstration, PETs 0 and 2 fill the entire memory allocation of + DE 2 and 1, respectively, to a unique value. +
+
+ if (localPet==0) then + myFarray = 12345.6789d0 + else if (localPet==2) then + myFarray = 6789.12345d0 + endif ++ +
+Here synchronization is needed before any PETs that share access to the same + DEs can safely access the data without race condition. The Array class provides + a simple synchronization method that can be used. +
+
+ call ESMF_ArraySync(array, rc=rc) ! prevent race condition ++ +
+Now it is safe for PETs 1 and 3 to access the shared DEs. We expect to find + the data that was set above. For simplicity of the code only the first + array element is inspected here. +
+
+ if (localPet==1) then + if (abs(myFarray(1,1)-12345.6789d0)>1.d10) print *, "bad data detected" + else if (localPet==3) then + if (abs(myFarray(1,1)-6789.12345d0)>1.d10) print *, "bad data detected" + endif ++ +
+Working with shared DEs requires additional bookkeeping on the user code + level. In some situations, however, DE sharing is simply used as a mechanism + to move DEs between PETs without requiring data copies. One practical + application of this case is the transfer of an Array between two components, + both of which use the same PEs, but run with different number of PETs. + These would typically be sequential components that use OpenMP on the user + level with varying threading levels. + +
+DEs that are pinned to SSI can be moved or migrated to any PET within + the SSI. This is accomplished by creating a new Array object from an + existing Array that was created with pinflag=ESMF_PIN_DE_TO_SSI. + The information of how the DEs are to migrate between the old and the new + Array is provided through a DELayout object. This object must have the + same number of DEs and describes how they map to the PETs on the current VM. + If this is in the context of a different component, the number of PETs might + differ from the original VM under which the existing Array was created. This + situation is explicitly supported, still the number of DEs must match. + +
+Here a simple DELayout is created on the same 4 PETs, but with rotated + DE ownerships: + +
+DE 0 -> PET 1 (old PET 0)
+
+DE 1 -> PET 2 (old PET 1)
+
+DE 2 -> PET 3 (old PET 2)
+
+DE 3 -> PET 0 (old PET 3)
+
+
+ delayout = ESMF_DELayoutCreate(petMap=(/1,2,3,0/), rc=rc) ! DE->PET mapping ++ +
+The creation of the new Array is done by reference, i.e. + datacopyflag=ESMF_DATACOPY_REFERENCE, since the new Array does + not create its own memory allocations. Instead the new Array references the + shared memory resources held by the incoming Array object. +
+
+ arrayMigrated = ESMF_ArrayCreate(array, delayout=delayout, & + datacopyflag=ESMF_DATACOPY_REFERENCE, rc=rc) ++ +
+Querying arrayMigrated for the number of local DEs will return 1 on + each PET. Sizing the localDeToDeMap accordingly and querying for it. +
+
+ deallocate(localDeToDeMap) ! free previous allocation + allocate(localDeToDeMap(0:1)) + call ESMF_ArrayGet(arrayMigrated, localDeToDeMap=localDeToDeMap, rc=rc) ++ +
+This yields the following expected outcome: + +
+PET 0: localDeToDeMap==(/1/)
+
+PET 1: localDeToDeMap==(/2/)
+
+PET 2: localDeToDeMap==(/3/)
+
+PET 3: localDeToDeMap==(/0/)
+
+
+
+On each PET the respective Fortran array pointer is returned by the Array. +
+
+ call ESMF_ArrayGet(arrayMigrated, farrayPtr=myFarray, rc=rc) ++ +
+The same situation could have been achieved with the original array. + However, it would have required first finding the correct local DE + for the target global DE on each PET, and then querying array + accordingly. If needed more repeatedly, this bookkeeping would need to be + kept in a user code data structure. The DE migration feature on the other + hand provides a formal way to create a standard ESMF Array object that can be + used directly in any Array level method as usual, letting ESMF handle the + extra bookkeeping needed. + +
+Before destroying an Array whose DEs are shared between PETs, it is + advisable to issue one more synchronization. This prevents cases where a + PET still might be accessing a shared DE, while the owner PET is already + destroying the Array, therefore deallocating the shared memory resource. +
+
+ call ESMF_ArraySync(array, rc=rc) ! prevent race condition ++ +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+Remember that arrayMigrated shares the same memory allocations that were + held by array. Array arrayMigrated must therefore not be used + beyond the life time of array. Best to destroy it now. +
+
+ call ESMF_ArrayDestroy(arrayMigrated, rc=rc) ++ +
+
+ endif ! ending the ssiSharedMemoryEnabled conditional ++ +
+ + +
+ +
+ +
+ +
+It is a common situation, particularly in legacy code, that an ESMF Array + object must be filled with data originating from a large Fortran array stored + on a single PET. +
+
+ if (localPet == 0) then + allocate(farray(10,20,30)) + do k=1, 30 + do j=1, 20 + do i=1, 10 + farray(i, j, k) = k*1000 + j*100 + i + enddo + enddo + enddo + else + allocate(farray(0,0,0)) + endif ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1,1/), maxIndex=(/10,20,30/), & + rc=rc) ++ +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_I4, rank=3, rc=rc) ++ +
+
+ array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, rc=rc) ++ +
+The ESMF_ArrayScatter() method provides a convenient way of scattering + array data from a single root PET across the DEs of an ESMF Array object. +
+
+ call ESMF_ArrayScatter(array, farray=farray, rootPet=0, rc=rc) ++ +
+
+ deallocate(farray) ++ +
+The destination of the ArrayScatter() operation are all the DEs of a single + tile. For multi-tile Arrays the destination tile can be specified. The + shape of the scattered Fortran array must match the shape of the destination + tile in the ESMF Array. + +
+Gathering data decomposed and distributed across the DEs of an ESMF Array + object into a single Fortran array on root PET is accomplished by calling + ESMF_ArrayGather(). +
+
+ if (localPet == 3) then + allocate(farray(10,20,30)) + else + allocate(farray(0,0,0)) + endif + + call ESMF_ArrayGather(array, farray=farray, rootPet=3, rc=rc) ++ +
+
+ deallocate(farray) ++ +
+The source of the ArrayGather() operation are all the DEs of a single + tile. For multi-tile Arrays the source tile can be specified. The + shape of the gathered Fortran array must match the shape of the source + tile in the ESMF Array. + +
+The ESMF_ArrayScatter() operation allows to fill entire replicated + Array objects with data coming from a single root PET. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + regDecomp=(/2,3/), rc=rc) ++ +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=2, rc=rc) ++ +
+
+ array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, & + distgridToArrayMap=(/0,0/), undistLBound=(/11,21/), & + undistUBound=(/14,22/), rc=rc) ++ +
+The shape of the Fortran source array used in the Scatter() call must be + that of the contracted Array, i.e. contracted DistGrid dimensions do not + count. For the array just created this means that the source array + on rootPet must be of shape 4 x 2. +
+
+ if (localPet == 0) then + allocate(myFarray2D(4,2)) + do j=1,2 + do i=1,4 + myFarray2D(i,j) = i * 100.d0 + j * 1.2345d0 ! initialize + enddo + enddo + else + allocate(myFarray2D(0,0)) + endif + + call ESMF_ArrayScatter(array, farray=myFarray2D, rootPet=0, rc=rc) ++ +
+
+ deallocate(myFarray2D) ++ +
+This will have filled each local 4 x 2 Array piece with the replicated + data of myFarray2D. +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+As a second example for the use of Scatter() and Gather() consider the + following replicated Array created from existing local Fortran arrays. +
+
+ allocate(myFarray2D(3,10)) + distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/40,10/), rc=rc) ++ +
+
+ array = ESMF_ArrayCreate(farray=myFarray2D, distgrid=distgrid, & + indexflag=ESMF_INDEX_DELOCAL, distgridToArrayMap=(/0,2/), rc=rc) ++ +
+The array object associates the 2nd DistGrid dimension with the 2nd + Array dimension. The first DistGrid dimension is not associated with any + Array dimension and will lead to replication of the Array along the DEs of + this direction. Still, the local arrays that comprise the array + object refer to independent pieces of memory and can be initialized + independently. +
+
+ myFarray2D = localPet ! initialize ++ +
+However, the notion of replication becomes visible when an array of shape + 3 x 10 on root PET 0 is scattered across the Array object. +
+
+ if (localPet == 0) then + allocate(myFarray2D2(5:7,11:20)) + + do j=11,20 + do i=5,7 + myFarray2D2(i,j) = i * 100.d0 + j * 1.2345d0 ! initialize + enddo + enddo + else + allocate(myFarray2D2(0,0)) + endif + + call ESMF_ArrayScatter(array, farray=myFarray2D2, rootPet=0, rc=rc) ++ +
+
+ deallocate(myFarray2D2) ++ +
+The Array pieces on every DE will receive the same source data, resulting + in a replication of data along DistGrid dimension 1. + +
+When the inverse operation, i.e. ESMF_ArrayGather(), is applied to + a replicated Array an intrinsic ambiguity needs to be considered. ESMF + defines the gathering of data of a replicated Array as the collection of data + originating from the numerically higher DEs. This means that data in + replicated elements associated with numerically lower DEs will be ignored + during ESMF_ArrayGather(). For the current example this means that + changing the Array contents on PET 1, which here corresponds to DE 1, +
+
+ if (localPet == 1) then + myFarray2D = real(1.2345, ESMF_KIND_R8) + endif ++ +
+will not affect the result of +
+ allocate(myFarray2D2(3,10)) + myFarray2D2 = 0.d0 ! initialize to a known value + call ESMF_ArrayGather(array, farray=myFarray2D2, rootPet=0, rc=rc) ++ +
+The result remains completely defined by the unmodified values of Array in + DE 3, the numerically highest DE. However, overriding the DE-local Array + piece on DE 3 +
+ if (localPet==3) then + myFarray2D = real(5.4321, ESMF_KIND_R8) + endif ++ +
+will change the outcome of +
+ call ESMF_ArrayGather(array, farray=myFarray2D2, rootPet=0, rc=rc) ++ +
+as expected. +
+
+ deallocate(myFarray2D2) + + call ESMF_ArrayDestroy(array, rc=rc) ++ +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+One of the most fundamental communication pattern in domain decomposition + codes is the halo operation. The ESMF Array class supports halos + by allowing memory for extra elements to be allocated on each DE. See + sections 28.2.2 and 28.2.8 for examples and + details on how to create an Array with extra DE-local elements. + +
+Here we consider an Array object that is created on a DistGrid that + defines a 10 x 20 index space, decomposed into 4 DEs using a regular + 2 x 2 decomposition. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/10,20/), & + regDecomp=(/2,2/), rc=rc) ++ +
+The Array holds 2D double precision float data. +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=2, rc=rc) ++ +
+The totalLWidth and totalUWidth arguments are used during Array + creation to allocate 2 extra elements along every direction outside the + exclusive region defined by the DistGrid for every DE. (The indexflag + set to ESMF_INDEX_GLOBAL in this example does not affect the halo + behavior of Array. The setting is simply more convenient for the following + code.) +
+
+ array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, & + totalLWidth=(/2,2/), totalUWidth=(/2,2/), indexflag=ESMF_INDEX_GLOBAL, & + rc=rc) ++ +
+Without the explicit definition of boundary conditions in the DistGrid + the following inner connections are defined. + +
+
+ + +-------------------+ +-------------------+ + | \ 2 / | | \ 2 / | + | +-------------+ | | +-------------+ | + | | DE 0 | | | | DE 2 | | + | | | | | | | | + |2 | 5 x 10 | 2| <-> |2 | 5 x 10 | 2| + | | | | | | | | + | | | | | | | | + | +-------------+ | | +-------------+ | + | / 2 \ | | / 2 \ | + +-------------------+ +-------------------+ + + ^ \/ ^ + | /\ | + v v + + +-------------------+ +-------------------+ + | \ 2 / | | \ 2 / | + | +-------------+ | | +-------------+ | + | | DE 1 | | | | DE 3 | | + | | | | | | | | + |2 | 5 x 10 | 2| <-> |2 | 5 x 10 | 2| + | | | | | | | | + | | | | | | | | + | +-------------+ | | +-------------+ | + | / 2 \ | | / 2 \ | + +-------------------+ +-------------------+ ++ +
+The exclusive region on each DE is of shape 5 x 10, while the total region
+ on each DE is of shape (5+2+2) x (10+2+2) = 9 x 14. In a typical application
+ the elements in the exclusive region are updated exclusively by the PET that
+ owns the DE. In this example the exclusive elements on every DE are
+ initialized to the value of the geometric function
+
+
+ | +(1) |
+ | +(2) |
+ | +(3) |
+
+ a = 2. * 3.14159 / 10. + b = 2. * 3.14159 / 20. + + call ESMF_ArrayGet(array, farrayPtr=farrayPtr, rc=rc) ++ +
+
+ + call ESMF_ArrayGet(array, exclusiveLBound=eLB, exclusiveUBound=eUB, rc=rc) ++ +
+
+ + do j=eLB(2,1), eUB(2,1) + do i=eLB(1,1), eUB(1,1) + farrayPtr(i,j) = sin(a*i) * cos(b*j) ! test function + enddo + enddo ++ +
+The above loop only initializes the exclusive elements on each DE. The extra + elements, outside the exclusive region, are left untouched, holding undefined + values. Elements outside the exclusive region that correspond to + exclusive elements in neighboring DEs can be filled with the data values + in those neighboring elements. This is the definition of the halo operation. + +
+In ESMF the halo communication pattern is first precomputed and stored in + a RouteHandle object. This RouteHandle can then be used repeatedly to + perform the same halo operation in the most efficient way. + +
+The default halo operation for an Array is precomputed by the following call. +
+
+ call ESMF_ArrayHaloStore(array=array, routehandle=haloHandle, rc=rc) ++ +
+The haloHandle now holds the default halo operation for array, + which matches as many elements as possible outside the exclusive region to + their corresponding halo source elements in neighboring DEs. Elements that + could not be matched, e.g. at the edge of the global domain with open + boundary conditions, will not be updated by the halo operation. + +
+The haloHandle is applied through the ESMF_ArrayHalo() method. +
+
+ call ESMF_ArrayHalo(array=array, routehandle=haloHandle, rc=rc) ++ +
+Finally the resources held by haloHandle need to be released. +
+
+ call ESMF_ArrayHaloRelease(routehandle=haloHandle, rc=rc) ++ +
+The array object created above defines a 2 element wide rim around the + exclusive region on each DE. Consequently the default halo operation used + above will have resulted in updating both elements along the inside edges. + For simple numerical kernels often a single halo element is + sufficient. One way to achieve this would be to reduce the size of the + rim surrounding the exclusive region to 1 element along each direction. + However, if the same Array object is also used for higher order kernels + during a different phase of the calculation, a larger element rim is + required. For this case ESMF_ArrayHaloStore() offers two optional + arguments haloLDepth and haloUDepth. Using these arguments a + reduced halo depth can be specified. +
+
+ call ESMF_ArrayHaloStore(array=array, routehandle=haloHandle, & + haloLDepth=(/1,1/), haloUDepth=(/1,1/), rc=rc) ++ +
+This halo operation with a depth of 1 is sufficient to support a simple + quadratic differentiation kernel. +
+
+ allocate(farrayTemp(eLB(1,1):eUB(1,1), eLB(2,1):eUB(2,1))) + + do step=1, 4 + call ESMF_ArrayHalo(array=array, routehandle=haloHandle, rc=rc) ++ +
+
+ do j=eLB(2,1), eUB(2,1) + do i=eLB(1,1), eUB(1,1) + if (i==1) then + ! global edge + farrayTemp(i,j) = 0.5 * (-farrayPtr(i+2,j) + 4.*farrayPtr(i+1,j) & + - 3.*farrayPtr(i,j)) / a + else if (i==10) then + ! global edge + farrayTemp(i,j) = 0.5 * (farrayPtr(i-2,j) - 4.*farrayPtr(i-1,j) & + + 3.*farrayPtr(i,j)) / a + else + farrayTemp(i,j) = 0.5 * (farrayPtr(i+1,j) - farrayPtr(i-1,j)) / a + endif + enddo + enddo + farrayPtr(eLB(1,1):eUB(1,1), eLB(2,1):eUB(2,1)) = farrayTemp + enddo + + deallocate(farrayTemp) + + call ESMF_ArrayHaloRelease(routehandle=haloHandle, rc=rc) ++ +
+The special treatment of the global edges in the above kernel is due to the + fact that the underlying DistGrid object does not define any special + boundary conditions. By default open global boundaries are assumed which + means that the rim elements on the global edges are untouched during + the halo operation, and cannot be used in the symmetric numerical derivative + formula. The kernel can be simplified (and the calculation is more precise) + with periodic boundary conditions along the first Array dimension. + +
+First destroy the current Array and DistGrid objects. +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+Create a DistGrid with periodic boundary condition along the first dimension. +
+
+ allocate(connectionList(1)) ! one connection + call ESMF_DistGridConnectionSet(connection=connectionList(1), & + tileIndexA=1, tileIndexB=1, positionVector=(/10, 0/), rc=rc) ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/10,20/), & + regDecomp=(/2,2/), connectionList=connectionList, rc=rc) ++ +
+
+ deallocate(connectionList) + array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, & + totalLWidth=(/2,2/), totalUWidth=(/2,2/), indexflag=ESMF_INDEX_GLOBAL, & + rc=rc) ++ +
+Initialize the exclusive elements to the same geometric function as before. +
+
+ call ESMF_ArrayGet(array, farrayPtr=farrayPtr, rc=rc) ++ +
+
+ + call ESMF_ArrayGet(array, exclusiveLBound=eLB, exclusiveUBound=eUB, rc=rc) ++ +
+
+ + do j=eLB(2,1), eUB(2,1) + do i=eLB(1,1), eUB(1,1) + farrayPtr(i,j) = sin(a*i) * cos(b*j) ! test function + enddo + enddo ++ +
+The numerical kernel only operates along the first dimension. An + asymmetric halo depth can be used to take this fact into account. +
+
+ call ESMF_ArrayHaloStore(array=array, routehandle=haloHandle, & + haloLDepth=(/1,0/), haloUDepth=(/1,0/), rc=rc) ++ +
+Now the same numerical kernel can be used without special treatment of + global edge elements. The symmetric derivative formula can be used for + all exclusive elements. +
+
+ allocate(farrayTemp(eLB(1,1):eUB(1,1), eLB(2,1):eUB(2,1))) + + do step=1, 4 + call ESMF_ArrayHalo(array=array, routehandle=haloHandle, rc=rc) ++ +
+
+ do j=eLB(2,1), eUB(2,1) + do i=eLB(1,1), eUB(1,1) + farrayTemp(i,j) = 0.5 * (farrayPtr(i+1,j) - farrayPtr(i-1,j)) / a + enddo + enddo + farrayPtr(eLB(1,1):eUB(1,1), eLB(2,1):eUB(2,1)) = farrayTemp + enddo ++ +
+The precision of the above kernel can be improved by going to + a higher order interpolation. Doing so requires that the halo depth must be + increased. The following code resets the exclusive Array elements + to the test function, precomputes a RouteHandle for a halo operation + with depth 2 along the first dimension, and finally uses the deeper halo + in the higher order kernel. +
+
+ + do j=eLB(2,1), eUB(2,1) + do i=eLB(1,1), eUB(1,1) + farrayPtr(i,j) = sin(a*i) * cos(b*j) ! test function + enddo + enddo + + call ESMF_ArrayHaloStore(array=array, routehandle=haloHandle2, & + haloLDepth=(/2,0/), haloUDepth=(/2,0/), rc=rc) ++ +
+
+ do step=1, 4 + call ESMF_ArrayHalo(array=array, routehandle=haloHandle2, rc=rc) ++ +
+
+ do j=eLB(2,1), eUB(2,1) + do i=eLB(1,1), eUB(1,1) + farrayTemp(i,j) = (-farrayPtr(i+2,j) + 8.*farrayPtr(i+1,j) & + - 8.*farrayPtr(i-1,j) + farrayPtr(i-2,j)) / (12.*a) + enddo + enddo + farrayPtr(eLB(1,1):eUB(1,1), eLB(2,1):eUB(2,1)) = farrayTemp + enddo + + deallocate(farrayTemp) ++ +
+ESMF supports having multiple halo operations defined on the same Array + object at the same time. Each operation can be accessed through its unique + RouteHandle. The above kernel could have made ESMF_ArrayHalo() calls + with a depth of 1 along the first dimension using the previously precomputed + haloHandle if it needed to. Both RouteHandles need to release their + resources when no longer used. +
+
+ + + call ESMF_ArrayHaloRelease(routehandle=haloHandle, rc=rc) ++ +
+
+ call ESMF_ArrayHaloRelease(routehandle=haloHandle2, rc=rc) ++ +
+Finally the Array and DistGrid objects can be destroyed. +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+In the previous section the Array halo operation was demonstrated + for regularly decomposed ESMF Arrays. However, the ESMF halo operation + is not restricted to regular decompositions. The same Array halo methods + apply unchanged to Arrays that are created on arbitrarily distributed + DistGrids. This includes the non-blocking features discussed in section + 28.2.20. + +
+All of the examples in this section are based on the same arbitrarily + distributed DistGrid. Section 36.3.5 discusses + DistGrids with user-supplied, arbitrary sequence indices in detail. Here + a global index space range from 1 through 20 is decomposed across 4 DEs. + There are 4 PETs in this example with 1 DE per PET. Each PET constructs + its local seqIndexList variable. +
+
+ do i=1, 5 +#ifdef TEST_I8RANGE_on + seqIndexList(i) = localPet + (i - 1) * petCount + 1 + seqIndexOffset +#else + seqIndexList(i) = localPet + (i - 1) * petCount + 1 +#endif + enddo ++ +
+This results in the following cyclic distribution scheme: +
+ DE 0 on PET 0: seqIndexList = (/1, 5, 9, 13, 17/) + DE 1 on PET 1: seqIndexList = (/2, 6, 10, 14, 18/) + DE 2 on PET 2: seqIndexList = (/3, 7, 11, 15, 19/) + DE 3 on PET 3: seqIndexList = (/4, 8, 12, 16, 20/) ++ +
+The local seqIndexList variables are then used to create a + DistGrid with the indicated arbitrary distribution pattern. +
+
+ distgrid = ESMF_DistGridCreate(arbSeqIndexList=seqIndexList, rc=rc) ++ +
+The resulting DistGrid is one-dimensional, although the user code may + interpret the sequence indices as a 1D map into a problem of higher + dimensionality. + +
+In this example the local DE on each PET is associated with a 5 element + exclusive region. Providing seqIndexList of different size on the + different PETs is supported and would result in different number of + exclusive elements on each PET. + +
+ +
+Creating an ESMF Array on top of a DistGrid with arbitrary sequence indices + is in principle no different from creating an Array on a regular DistGrid. + However, while an Array that was created on a regular DistGrid automatically + inherits the index space topology information that is contained within the + DistGrid object, there is no such topology information available for + DistGrid objects with arbitrary sequence indices. As a consequence of + this, Arrays created on arbitrary DistGrids do not automatically have + the information that is required to associated halo elements with the + exclusive elements across DEs. Instead the user must supply this information + explicitly during Array creation. + +
+Multiple ArrayCreate() interfaces exist that allow the creation of an Array + on a DistGrid with arbitrary sequence indices. The sequence indices for the + halo region of the local DE are supplied through an additional argument + with dummy name haloSeqIndexList. As in the regular case, the + ArrayCreate() interfaces differ in the way that the memory allocations for + the Array elements are passed into the call. The following code shows how + an ESMF Array can be wrapped around existing PET-local memory allocations. + The allocations are of different size on each PET as to accommodate the correct + number of local Array elements (exclusive region + halo region). +
+
+ allocate(farrayPtr1d(5+localPet+1)) !use explicit Fortran allocate statement + + if (localPet==0) then + allocate(haloList(1)) +#ifdef TEST_I8RANGE_on + haloList(:)=(/1099511627782_ESMF_KIND_I8/) +#else + haloList(:)=(/6/) +#endif + array = ESMF_ArrayCreate(distgrid, farrayPtr1d, & + haloSeqIndexList=haloList, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==1) then + allocate(haloList(2)) +#ifdef TEST_I8RANGE_on + haloList(:)=(/1099511627777_ESMF_KIND_I8,& + 1099511627795_ESMF_KIND_I8/) +#else + haloList(:)=(/1,19/) +#endif + array = ESMF_ArrayCreate(distgrid, farrayPtr1d, & + haloSeqIndexList=haloList, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==2) then + allocate(haloList(3)) +#ifdef TEST_I8RANGE_on + haloList(:)=(/1099511627792_ESMF_KIND_I8,& + 1099511627782_ESMF_KIND_I8,& + 1099511627785_ESMF_KIND_I8/) +#else + haloList(:)=(/16,6,9/) +#endif + array = ESMF_ArrayCreate(distgrid, farrayPtr1d, & + haloSeqIndexList=haloList, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==3) then + allocate(haloList(4)) +#ifdef TEST_I8RANGE_on + haloList(:)=(/1099511627777_ESMF_KIND_I8,& + 1099511627779_ESMF_KIND_I8,& + 1099511627777_ESMF_KIND_I8,& + 1099511627780_ESMF_KIND_I8/) +#else + haloList(:)=(/1,3,1,4/) +#endif + array = ESMF_ArrayCreate(distgrid, farrayPtr1d, & + haloSeqIndexList=haloList, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif ++ +
+The haloSeqIndexList arguments are 1D arrays of sequence indices. + It is through this argument that the user associates the halo elements with + exclusive Array elements covered by the DistGrid. In this example there + are different number of halo elements on each DE. They are associated + with exclusive elements as follows: + +
+
+ halo on DE 0 on PET 0: <seqIndex=6> 2nd exclusive element on DE 1 + halo on DE 1 on PET 1: <seqIndex=1> 1st exclusive element on DE 0 + <seqIndex=19> 5th exclusive element on DE 2 + halo on DE 2 on PET 2: <seqIndex=16> 4th exclusive element on DE 3 + <seqIndex=6> 2nd exclusive element on DE 1 + <seqIndex=9> 3rd exclusive element on DE 0 + halo on DE 3 on PET 3: <seqIndex=1> 1st exclusive element on DE 0 + <seqIndex=3> 1st exclusive element on DE 2 + <seqIndex=1> 1st exclusive element on DE 0 + <seqIndex=4> 1st exclusive element on DE 3 ++ +
+The above haloSeqIndexList arguments were constructed very artificially + in order to show the following general features: + +
+The ArrayCreate() call checks that the provided Fortran memory allocation + is correctly sized to hold the exclusive elements, as indicated by the + DistGrid object, plus the halo elements as indicated by the local + haloSeqIndexList argument. The size of the Fortran allocation must + match exactly or a runtime error will be returned. + +
+Analogous to the case of Arrays on regular DistGrids, it is the exclusive + region of the local DE that is typically modified by the code running on + each PET. All of the ArrayCreate() calls that accept the + haloSeqIndexList argument place the exclusive region at the beginning + of the memory allocation on each DE and use the remaining space for the halo + elements. The following loop demonstrates this by filling the exclusive + elements on each DE with initial values. Remember that in this example each + DE holds 5 exclusive elements associated with different arbitrary sequence + indices. +
+
+ farrayPtr1d = 0 ! initialize + do i=1, 5 + farrayPtr1d(i) = real(seqIndexList(i), ESMF_KIND_R8) + enddo + print *, "farrayPtr1d: ", farrayPtr1d ++ +
+Now the exclusive elements of array are initialized on each DE, however, + the halo elements remain unchanged. A RouteHandle can be set up that encodes + the required communication pattern for a halo exchange. The halo exchange + is precomputed according to the arbitrary sequence indices specified for the + exclusive elements by the DistGrid and the sequence indices provided by the + user for each halo element on the local DE in form of the + haloSeqIndexList argument during ArrayCreate(). + +
+
+ call ESMF_ArrayHaloStore(array, routehandle=haloHandle, rc=rc) ++ +
+Executing this halo operation will update the local halo elements according + to the associated sequence indices. +
+
+ call ESMF_ArrayHalo(array, routehandle=haloHandle, rc=rc) ++ +
+As always it is good practice to release the RouteHandle when done with it. +
+
+ call ESMF_ArrayHaloRelease(haloHandle, rc=rc) ++ +
+Also the Array object should be destroyed when no longer needed. +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+Further, since the memory allocation was done explicitly using the Fortran + allocate() statement, it is necessary to explicitly deallocate in order + to prevent memory leaks in the user application. +
+
+ deallocate(farrayPtr1d) ++ +
+ +
+Alternatively the exact same Array can be created where ESMF does the + memory allocation and deallocation. In this case the typekind of the + Array must be specified explicitly. +
+
+ if (localPet==0) then + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + haloSeqIndexList=haloList, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==1) then + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + haloSeqIndexList=haloList, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==2) then + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + haloSeqIndexList=haloList, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==3) then + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + haloSeqIndexList=haloList, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif ++ +
+Use ESMF_ArrayGet() to gain access to the local memory allocation. +
+
+ call ESMF_ArrayGet(array, farrayPtr=farrayPtr1d, rc=rc) ++ +
+The returned Fortran pointer can now be used to initialize the exclusive + elements on each DE as in the previous case. +
+
+ do i=1, 5 + farrayPtr1d(i) = real(seqIndexList(i),ESMF_KIND_R8) / 10.d0 + enddo ++ +
+Identical halo operations are constructed and used. +
+
+ call ESMF_ArrayHaloStore(array, routehandle=haloHandle, rc=rc) ++ +
+
+ call ESMF_ArrayHalo(array, routehandle=haloHandle, rc=rc) ++ +
+
+ call ESMF_ArrayHaloRelease(haloHandle, rc=rc) ++ +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+ +
+A current limitation of the Array implementation restricts DistGrids that + contain user-specified, arbitrary sequence indices to be exactly 1D + when used to create Arrays. See section 28.3 for a list of + current implementation restrictions. However, an Array created on such a + 1D arbitrary DistGrid is allowed to have undistributed dimensions. The + following example creates an Array on the same arbitrary DistGrid, with the + same arbitrary sequence indices for the halo elements as before, but with + one undistributed dimension with a size of 3. +
+
+ if (localPet==0) then + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + haloSeqIndexList=haloList, undistLBound=(/1/), undistUBound=(/3/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==1) then + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + haloSeqIndexList=haloList, undistLBound=(/1/), undistUBound=(/3/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==2) then + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + haloSeqIndexList=haloList, undistLBound=(/1/), undistUBound=(/3/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==3) then + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + haloSeqIndexList=haloList, undistLBound=(/1/), undistUBound=(/3/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif ++ +
+By default the DistGrid dimension is mapped to the first Array dimension, + associating the remaining Array dimensions with the undistributed dimensions + in sequence. The dimension order is important when accessing the individual + Array elements. Here the same initialization as before is extended to + cover the undistributed dimension. +
+
+ call ESMF_ArrayGet(array, farrayPtr=farrayPtr2d, rc=rc) ++ +
+
+ do j=1, 3 + do i=1, 5 + farrayPtr2d(i,j) = real(seqIndexList(i),ESMF_KIND_R8) / 10.d0 + 100.d0*j + enddo + enddo ++ +
+In the context of the Array halo operation additional undistributed dimensions + are treated in a simple factorized manner. The same halo association between + elements that is encoded in the 1D arbitrary sequence index scheme is + applied to each undistributed element separately. This is completely + transparent on the user level and the same halo methods are used as before. +
+
+ call ESMF_ArrayHaloStore(array, routehandle=haloHandle, rc=rc) ++ +
+
+ call ESMF_ArrayHalo(array, routehandle=haloHandle, rc=rc) ++ +
+
+ call ESMF_ArrayHaloRelease(haloHandle, rc=rc) ++ +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+ +
+In some situations it is more convenient to associate some or all of + the undistributed dimensions with the first Array dimensions. This can be + done easily by explicitly mapping the DistGrid dimension to an Array dimension + other than the first one. The distgridToArrayMap argument is used to + provide this information. The following code creates essentially the same + Array as before, but with swapped dimension order - now the first Array + dimension is the undistributed one. +
+
+ if (localPet==0) then + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + distgridToArrayMap=(/2/), haloSeqIndexList=haloList, & + undistLBound=(/1/), undistUBound=(/3/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==1) then + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + distgridToArrayMap=(/2/), haloSeqIndexList=haloList, & + undistLBound=(/1/), undistUBound=(/3/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==2) then + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + distgridToArrayMap=(/2/), haloSeqIndexList=haloList, & + undistLBound=(/1/), undistUBound=(/3/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==3) then +#ifdef TEST_I8RANGE_on + haloList(:)=(/1099511627777_ESMF_KIND_I8,& + 1099511627780_ESMF_KIND_I8,& + 1099511627779_ESMF_KIND_I8,& + 1099511627778_ESMF_KIND_I8/) +#else + haloList(:)=(/1,3,5,4/) +#endif + array = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + distgridToArrayMap=(/2/), haloSeqIndexList=haloList, & + undistLBound=(/1/), undistUBound=(/3/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif ++ +
+Notice that the haloList constructed on PET 3 is different from the + previous examples. All other PETs reuse the same haloList as before. + In the previous examples the list loaded into PET 3's + haloSeqIndexList argument contained a duplicate sequence index. + However, now that the undistributed dimension is placed first, the + ESMF_ArrayHaloStore() call will try to optimize the data exchange by + vectorizing it. Duplicate sequence indices are currently not supported + during vectorization. + +
+When accessing the Array elements, the swapped dimension order results in + a swapping of i and j. This can be seen in the following + initialization loop. +
+
+ call ESMF_ArrayGet(array, farrayPtr=farrayPtr2d, rc=rc) ++ +
+
+ do j=1, 3 + do i=1, 5 + farrayPtr2d(j,i) = real(seqIndexList(i),ESMF_KIND_R8) / 10.d0 + 100.d0*j + enddo + enddo ++ +
+Once set up, there is no difference in how the the halo operations are applied. +
+
+ call ESMF_ArrayHaloStore(array, routehandle=haloHandle, rc=rc) ++ +
+
+ call ESMF_ArrayHalo(array, routehandle=haloHandle, rc=rc) ++ +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+ +
+Arrays can reuse the same RouteHandle, saving the overhead that is caused by + the precompute step. In order to demonstrate this the RouteHandle of the + previous halo call was not yet released and will be applied to a new Array. + +
+The following code creates an Array that is compatible to the + previous Array by using the same input information as before, only that + the size of the undistributed dimension is now 6 instead of 3. +
+
+ if (localPet==0) then + array2 = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + distgridToArrayMap=(/2/), haloSeqIndexList=haloList, & + undistLBound=(/1/), undistUBound=(/6/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==1) then + array2 = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + distgridToArrayMap=(/2/), haloSeqIndexList=haloList, & + undistLBound=(/1/), undistUBound=(/6/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==2) then + array2 = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + distgridToArrayMap=(/2/), haloSeqIndexList=haloList, & + undistLBound=(/1/), undistUBound=(/6/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif + if (localPet==3) then + array2 = ESMF_ArrayCreate(distgrid=distgrid, typekind=ESMF_TYPEKIND_R8, & + distgridToArrayMap=(/2/), haloSeqIndexList=haloList, & + undistLBound=(/1/), undistUBound=(/6/), rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif ++ +
+Again the exclusive Array elements must be initialized. +
+
+ call ESMF_ArrayGet(array2, farrayPtr=farrayPtr2d, rc=rc) ++ +
+
+ do j=1, 6 + do i=1, 5 + farrayPtr2d(j,i) = real(seqIndexList(i),ESMF_KIND_R8) / 10.d0 + 100.d0*j + enddo + enddo ++ +
+Now the haloHandle that was previously pre-computed for array can + be used directly for array2. +
+
+ call ESMF_ArrayHalo(array2, routehandle=haloHandle, rc=rc) ++ +
+Release the RouteHandle after its last use and clean up the remaining + Array and DistGrid objects. +
+
+ call ESMF_ArrayHaloRelease(haloHandle, rc=rc) ++ +
+
+ call ESMF_ArrayDestroy(array2, rc=rc) ++ +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+Arrays used in different models often cover the same index space region, + however, the distribution of the Arrays may be different, e.g. the models + run on exclusive sets of PETs. Even if the Arrays are defined on the same + list of PETs the decomposition may be different. +
+
+ srcDistgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/10,20/), & + regDecomp=(/4,1/), rc=rc) ++ +
+
+ dstDistgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/10,20/), & + regDecomp=(/1,4/), rc=rc) ++ +
+The number of elements covered by srcDistgrid is identical to the number + of elements covered by dstDistgrid - in fact the index space regions + covered by both DistGrid objects are congruent. However, the decomposition + defined by regDecomp, and consequently the distribution of source and + destination, are different. +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=2, rc=rc) ++ +
+
+ srcArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=srcDistgrid, rc=rc) ++ +
+
+ dstArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=dstDistgrid, rc=rc) ++ +
+ +
+By construction srcArray and dstArray are of identical type and + kind. Further the number of exclusive elements matches between both Arrays. + These are the prerequisites for the application of an Array redistribution + in default mode. In order to increase performance of the actual + redistribution the communication pattern is precomputed once, and stored in + an ESMF_RouteHandle object. +
+
+ call ESMF_ArrayRedistStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, rc=rc) ++ +
+The redistHandle can now be used repeatedly to transfer data from + srcArray to dstArray. +
+
+ call ESMF_ArrayRedist(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, rc=rc) ++ +
+The use of the precomputed redistHandle is not restricted to + the (srcArray, dstArray) pair. Instead the redistHandle + can be used to redistribute data between any two Arrays that are compatible + with the Array pair used during precomputation. I.e. any pair of Arrays that + matches srcArray and dstArray in type, kind, and + memory layout of the distributed dimensions. However, the size, number, + and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+The transferability of RouteHandles between Array pairs can greatly reduce + the number of communication store calls needed. + In a typical application Arrays are often defined on the same decomposition, + typically leading to congruent distributed dimensions. For these Arrays, while + they may not have the same shape or size in the undistributed dimensions, + RouteHandles are reusable. + +
+For the current case, the redistHandle was precomputed for simple 2D + Arrays without undistributed dimensions. The RouteHandle transferability + rule allows us to use this same RouteHandle to redistribute between two + 3D Array that are built on the same 2D DistGrid, but have an undistributed + dimension. Note that the undistributed dimension does not have to be in the + same position on source and destination. Here the undistributed dimension is + in position 2 for srcArray1, and in position 1 for dstArray1. +
+
+ call ESMF_ArraySpecSet(arrayspec3d, typekind=ESMF_TYPEKIND_R8, rank=3, rc=rc) ++ +
+
+ srcArray1 = ESMF_ArrayCreate(arrayspec=arrayspec3d, distgrid=srcDistgrid, & + distgridToArrayMap=(/1,3/), undistLBound=(/1/), undistUBound=(/10/), rc=rc) ++ +
+
+ dstArray1 = ESMF_ArrayCreate(arrayspec=arrayspec3d, distgrid=dstDistgrid, & + distgridToArrayMap=(/2,3/), undistLBound=(/1/), undistUBound=(/10/), rc=rc) ++ +
+
+ call ESMF_ArrayRedist(srcArray=srcArray1, dstArray=dstArray1, & + routehandle=redistHandle, rc=rc) ++ +
+The following variation of the code shows that the same RouteHandle can be + applied to an Array pair even when the number of undistributed dimensions does + not match between source and destination Array, as long as to the total + number of undistributed elements matches. + +
+We prepare a source Array with two undistributed dimensions, in position + 1 and 3, of size and , respectively. Thus there are + undistributed source elements. The destination array is the same as before + with only a single undistributed dimension in position 1 + of size . +
+
+ call ESMF_ArraySpecSet(arrayspec4d, typekind=ESMF_TYPEKIND_R8, rank=4, rc=rc) ++ +
+
+ srcArray2 = ESMF_ArrayCreate(arrayspec=arrayspec4d, distgrid=srcDistgrid, & + distgridToArrayMap=(/2,4/), undistLBound=(/1,1/), undistUBound=(/2,5/), & + rc=rc) ++ +
+
+ call ESMF_ArrayRedist(srcArray=srcArray2, dstArray=dstArray1, & + routehandle=redistHandle, rc=rc) ++ +
+When done, the resources held by redistHandle need to be deallocated + by the user code before the RouteHandle becomes inaccessible. +
+
+ call ESMF_ArrayRedistRelease(routehandle=redistHandle, rc=rc) ++ +
+ +
+In default mode, i.e. without providing the optional + srcToDstTransposeMap argument, ESMF_ArrayRedistStore() does not + require equal number of dimensions in source and destination Array. Only the + total number of elements must match. + Specifying srcToDstTransposeMap switches ESMF_ArrayRedistStore() + into transpose mode. In this mode each dimension of srcArray + is uniquely associated with a dimension in dstArray, and the sizes of + associated dimensions must match for each pair. + + +
+
+ dstDistgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/20,10/), & + rc=rc) ++ +
+
+ dstArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=dstDistgrid, rc=rc) ++ +
+This dstArray object covers a 20 x 10 index space while the + srcArray, defined further up, covers a 10 x 20 index space. Setting + srcToDstTransposeMap = (/2,1/) will associate the first and second + dimension of srcArray with the second and first dimension of + dstArray, respectively. This corresponds to a transpose of dimensions. + Since the decomposition and distribution of dimensions may be different for + source and destination redistribution may occur at the same time. +
+
+ call ESMF_ArrayRedistStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, srcToDstTransposeMap=(/2,1/), rc=rc) ++ +
+
+ call ESMF_ArrayRedist(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, rc=rc) ++ +
+The transpose mode of ESMF_ArrayRedist() is not limited to + distributed dimensions of Arrays. The srcToDstTransposeMap argument + can be used to transpose undistributed dimensions in the same manner. + Furthermore transposing distributed and undistributed dimensions between + Arrays is also supported. + +
+The srcArray used in the following examples is of rank 4 with 2 + distributed and 2 undistributed dimensions. The distributed dimensions + are the two first dimensions of the Array and are distributed according to the + srcDistgrid which describes a total index space region of 100 x 200 + elements. The last two Array dimensions are undistributed dimensions of size + 2 and 3, respectively. +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=4, rc=rc) ++ +
+
+ srcDistgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/100,200/), & + rc=rc) ++ +
+
+ srcArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=srcDistgrid, & + undistLBound=(/1,1/), undistUBound=(/2,3/), rc=rc) ++ +
+The first dstArray to consider is defined on a DistGrid that also + describes a 100 x 200 index space region. The distribution indicated + by dstDistgrid may be different from the source distribution. Again + the first two Array dimensions are associated with the DistGrid dimensions in + sequence. Furthermore, the last two Array dimensions are undistributed + dimensions, however, the sizes are 3 and 2, respectively. +
+
+ dstDistgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/100,200/), & + rc=rc) ++ +
+
+ dstArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=dstDistgrid, & + undistLBound=(/1,1/), undistUBound=(/3,2/), rc=rc) ++ +
+The desired mapping between srcArray and dstArray dimensions + is expressed by srcToDstTransposeMap = (/1,2,4,3/), transposing only + the two undistributed dimensions. +
+
+ call ESMF_ArrayRedistStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, srcToDstTransposeMap=(/1,2,4,3/), rc=rc) ++ +
+
+ call ESMF_ArrayRedist(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, rc=rc) ++ +
+Next consider a dstArray that is defined on the same dstDistgrid, + but with a different order of Array dimensions. The desired order is + specified during Array creation using the argument + distgridToArrayMap = (/2,3/). This map associates the first and second + DistGrid dimensions with the second and third Array dimensions, respectively, + leaving Array dimensions one and four undistributed. +
+
+ dstArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=dstDistgrid, & + distgridToArrayMap=(/2,3/), undistLBound=(/1,1/), undistUBound=(/3,2/), & + rc=rc) ++ +
+Again the sizes of the undistributed dimensions are chosen in reverse order + compared to srcArray. The desired transpose mapping in this case will + be srcToDstTransposeMap = (/2,3,4,1/). +
+
+ call ESMF_ArrayRedistStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, srcToDstTransposeMap=(/2,3,4,1/), rc=rc) ++ +
+
+ call ESMF_ArrayRedist(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, rc=rc) ++ +
+Finally consider the case where dstArray is constructed on a + 200 x 3 index space and where the undistributed dimensions are of size + 100 and 2. +
+
+ dstDistgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/200,3/), & + rc=rc) ++ +
+
+ dstArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=dstDistgrid, & + undistLBound=(/1,1/), undistUBound=(/100,2/), rc=rc) ++ +
+By construction srcArray and dstArray hold the same number of + elements, albeit in a very different layout. Nevertheless, with a + srcToDstTransposeMap that maps matching dimensions from source to + destination, the following Array redistribution becomes a well defined + operation between srcArray and dstArray. +
+
+ call ESMF_ArrayRedistStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, srcToDstTransposeMap=(/3,1,4,2/), rc=rc) ++ +
+
+ call ESMF_ArrayRedist(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, rc=rc) ++ +
+The srcToDstTransposeMap mechanism supports negative map entries. + Negative entries indicate that the order of elements is to be reversed when + going from source to destination. + Using the same srcArray and dstArray objects as in the previous + example, the following code maps the first srcArray dimension to the + third dstArray dimension, as before. However, the ordering of + the elements along this dimension is reversed between source and destination. +
+
+ call ESMF_ArrayRedistStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, srcToDstTransposeMap=(/-3,1,4,2/), rc=rc) ++ +
+
+ call ESMF_ArrayRedist(srcArray=srcArray, dstArray=dstArray, & + routehandle=redistHandle, rc=rc) ++ +
+Redistribution of multi-tile Arrays is supported, although not shown as an + example here. In default mode, the + index space defined by both source and destination Arrays must match, + regardless of how it is comprised by tiles. In particular, there is no + restriction on the number of source and desination tiles, as long as both + sides define the same global index space. + +
+The situation is different in transpose mode. Here the number of source + and destination tiles must match. In this case, the redistribution is defined + tile-by-tile in order. If the provided + srcToDstTransposeMap is of size rank, it is used for all of the + tiles. The other supported option is where srcToDstTransposeMap is of + size +. In that case each source-destination tile-pair + has its own transpose map. + + +
+ +
+ +
+ +
+Sparse matrix multiplication is a fundamental Array communication method. One + frequently used application of this method is the interpolation between pairs + of Arrays. The principle is this: the value of each element in the exclusive + region of the destination Array is expressed as a linear combination of potentially all the exclusive elements of the source Array. Naturally most of + the coefficients of these linear combinations will be zero and it is more + efficient to store explicit information about the non-zero elements than to + keep track of all the coefficients. + +
+There is a choice to be made with respect to the format in which to store the + information about the non-zero elements. One option is to store the value + of each coefficient together with the corresponding destination element index + and source element index. Destination and source indices could be expressed in + terms of the corresponding DistGrid tile index together with the coordinate + tuple within the tile. While this format may be the most natural way to + express elements in the source and destination Array, it has two major drawbacks. + First the coordinate tuple is dimCount specific and second the format + is extremely bulky. For 2D source and destination Arrays it would require 6 + integers to store the source and destination element information for each + non-zero coefficient and matters get worse for higher dimensions. + +
+Both problems can be circumvented by interpreting source and destination + Arrays as sequentialized strings or vectors of elements. This is done + by assigning a unique sequence index to each exclusive element in both + Arrays. With that the operation of updating the elements in the destination Array + as linear combinations of source Array elements takes the form of a sparse + matrix multiplication. + +
+The default sequence index rule assigns index to the minIndex corner + element of the first tile of the DistGrid on which the Array is defined. It then + increments the sequence index by for each element running through the + DistGrid dimensions by order. The index space position of the DistGrid tiles + does not affect the sequence labeling of elements. The default sequence indices + for +
+ srcDistgrid = ESMF_DistGridCreate(minIndex=(/-1,0/), maxIndex=(/1,3/), rc=rc) ++ +
+for each element are: +
+ -------------------------------------> 2nd dim + | + | +------+------+------+------+ + | |(-1,0)| | |(-1,3)| + | | | | | | + | | 1 | 4 | 7 | 10 | + | +------+------+------+------+ + | | | | | | + | | | | | | + | | 2 | 5 | 8 | 11 | + | +------+------+------+------+ + | | (1,0)| | | (1,3)| + | | | | | | + | | 3 | 6 | 9 | 12 | + | +------+------+------+------+ + | + v + 1st dim ++ +
+The assigned sequence indices are decomposition and distribution invariant by + construction. Furthermore, when an Array is created with extra elements per DE on + a DistGrid the sequence indices (which only cover the exclusive elements) remain + unchanged. +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=2, rc=rc) ++ +
+
+ srcArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=srcDistgrid, & + totalLWidth=(/1,1/), totalUWidth=(/1,1/), indexflag=ESMF_INDEX_GLOBAL, & + rc=rc) ++ +
+The extra padding of 1 element in each direction around the exclusive elements on + each DE are "invisible" to the Array sparse matrix multiplication method. These + extra elements are either updated by the computational kernel or by Array halo + operations. + +
+An alternative way to assign sequence indices to all the elements in the tiles + covered by a DistGrid object is to use a special ESMF_DistGridCreate() + call. This call has been specifically designed for 1D cases with arbitrary, + user-supplied sequence indices. +
+
+ seqIndexList(1) = localPet*10 + seqIndexList(2) = localPet*10 + 1 + dstDistgrid = ESMF_DistGridCreate(arbSeqIndexList=seqIndexList, rc=rc) ++ +
+This call to ESMF_DistGridCreate() is collective across the current VM. + The arbSeqIndexList argument specifies the PET-local arbitrary sequence + indices that need to be covered by the local DE. The resulting DistGrid has + one local DE per PET which covers the entire PET-local index range. The user + supplied sequence indices must be unique, but the sequence may be interrupted. + The four DEs of dstDistgrid have the following local 1D index space + coordinates (given between "()") and sequence indices: +
+ covered by DE 0 covered by DE 1 covered by DE 2 covered by DE 3 + on PET 0 on PET 1 on PET 2 on PET 3 + ---------------------------------------------------------------------- + (1) : 0 (1) : 10 (1) : 20 (1) : 30 + (2) : 1 (2) : 11 (2) : 21 (2) : 31 ++ +
+Again the DistGrid object provides the sequence index labeling for the + exclusive elements of an Array created on the DistGrid regardless of extra, + non-exclusive elements. +
+
+ dstArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=dstDistgrid, rc=rc) ++ +
+With the definition of sequence indices, either by the default rule or as user + provided arbitrary sequence indices, it is now possible to uniquely identify + each exclusive element in the source and destination Array by a single integer + number. Specifying a pair of source and destination elements takes two integer + number regardless of the number of dimensions. + +
+The information required to carry out a sparse matrix multiplication are the + pair of source and destination sequence indices and the associated + multiplication factor for each pair. ESMF requires this information in form of + two Fortran arrays. The factors are stored in a 1D array of the appropriate + type and kind, e.g. real(ESMF_KIND_R8)::factorList(:). Array sparse + matrix multiplications are supported between Arrays of different type and + kind. The type and kind of the factors can also be chosen freely. The + sequence index pairs associated with the factors provided by factorList + are stored in a 2D Fortran array of default integer kind of the shape integer::factorIndexList(2,:). The sequence indices of the source Array elements + are stored in the first row of factorIndexList while the sequence indices of the destination Array elements are + stored in the second row. + +
+Each PET in the current VM must call into ESMF_ArraySMMStore() + to precompute and store the communication pattern for the sparse matrix + multiplication. The multiplication factors may be provided in parallel, i.e. + multiple PETs may specify factorList and factorIndexList arguments + when calling into ESMF_ArraySMMStore(). PETs that do not + provide factors either call with factorList and factorIndexList + arguments containing zero elements or issue the call omitting both arguments. +
+
+ if (localPet == 0) then + allocate(factorList(1)) ! PET 0 specifies 1 factor + allocate(factorIndexList(2,1)) + factorList = (/0.2/) ! factors + factorIndexList(1,:) = (/5/) ! seq indices into srcArray + factorIndexList(2,:) = (/30/) ! seq indices into dstArray + + call ESMF_ArraySMMStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, factorList=factorList, & + factorIndexList=factorIndexList, rc=rc) ++ +
+
+ + deallocate(factorList) + deallocate(factorIndexList) + else if (localPet == 1) then + allocate(factorList(3)) ! PET 1 specifies 3 factor + allocate(factorIndexList(2,3)) + factorList = (/0.5, 0.5, 0.8/) ! factors + factorIndexList(1,:) = (/8, 2, 12/) ! seq indices into srcArray + factorIndexList(2,:) = (/11, 11, 30/) ! seq indices into dstArray + + call ESMF_ArraySMMStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, factorList=factorList, & + factorIndexList=factorIndexList, rc=rc) ++ +
+
+ + deallocate(factorList) + deallocate(factorIndexList) + else + ! PETs 2 and 3 do not provide factors + + call ESMF_ArraySMMStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, rc=rc) ++ +
+
+ + endif ++ +
+The RouteHandle object sparseMatMulHandle produced by + ESMF_ArraySMMStore() can now be used to call ESMF_ArraySMM() collectively across all PETs of the current VM to + perform +
+ dstArray = 0.0 + do n=1, size(combinedFactorList) + dstArray(combinedFactorIndexList(2, n)) += + combinedFactorList(n) * srcArray(combinedFactorIndexList(1, n)) + enddo ++ in parallel. Here combinedFactorList and combinedFactorIndexList + are the combined lists defined by the respective local lists provided by + PETs 0 and 1 in parallel. For this example +
+ call ESMF_ArraySMM(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, rc=rc) ++ +
+will initialize the entire dstArray to 0.0 and then update two elements: + +
+
+ on DE 1: + dstArray(2) = 0.5 * srcArray(0,0) + 0.5 * srcArray(0,2) ++ +
+and + +
+
+ on DE 3: + dstArray(1) = 0.2 * srcArray(0,1) + 0.8 * srcArray(1,3). ++ +
+The call to ESMF_ArraySMM() does provide the option to turn + the default dstArray initialization off. If argument zeroregion + is set to ESMF_REGION_EMPTY +
+
+ call ESMF_ArraySMM(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, zeroregion=ESMF_REGION_EMPTY, rc=rc) ++ +
+skips the initialization and elements in dstArray are updated according to: + +
+
+ do n=1, size(combinedFactorList) + dstArray(combinedFactorIndexList(2, n)) += + combinedFactorList(n) * srcArray(combinedFactorIndexList(1, n)). + enddo ++ +
+The ESMF_RouteHandle object returned by ESMF_ArraySMMStore() + can be applied to any src/dst Array pairs that is compatible with the + Array pair used during precomputation, i.e. any pair of Arrays that matches + srcArray and dstArray in type, kind, and + memory layout of the distributed dimensions. However, the size, number, + and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+The resources held by sparseMatMulHandle need to be deallocated by the + user code before the handle becomes inaccessible. +
+
+ call ESMF_ArraySMMRelease(routehandle=sparseMatMulHandle, rc=rc) ++ +
+The Array sparse matrix multiplication also applies to Arrays with + undistributed dimensions. The undistributed dimensions are interpreted + in a sequentialized manner, much like the distributed dimensions, + introducing a second sequence index for source and destination elements. + Sequence index 1 is assigned to the first element in the first + (i.e. fastest varying in memory) undistributed dimension. The following + undistributed elements are labeled in consecutive order as they are stored in + memory. + +
+In the simplest case the Array sparse matrix multiplication will apply an + identity matrix to the vector of sequentialized undistributed Array elements + for every non-zero element in the sparse matrix. The requirement in this case + is that the total undistributed element count, i.e. the product of the sizes + of all undistributed dimensions, be the same for source and destination Array. +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=3, rc=rc) + srcArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=srcDistgrid, & + totalLWidth=(/1,1/), totalUWidth=(/1,1/), indexflag=ESMF_INDEX_GLOBAL, & + distgridToArrayMap=(/1,2/), undistLBound=(/1/), undistUBound=(/2/), rc=rc) ++ +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=2, rc=rc) + dstArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=dstDistgrid, & + distgridToArrayMap=(/2/), undistLBound=(/1/), undistUBound=(/2/), rc=rc) ++ +
+Setting up factorList and factorIndexList is identical to the + case for Arrays without undistributed dimensions. Also the call to + ESMF_ArraySMMStore() remains unchanged. Internally, however, + the source and destination Arrays are checked to make sure the total + undistributed element count matches. +
+
+ if (localPet == 0) then + allocate(factorList(1)) ! PET 0 specifies 1 factor + allocate(factorIndexList(2,1)) + factorList = (/0.2/) ! factors + factorIndexList(1,:) = (/5/) ! seq indices into srcArray + factorIndexList(2,:) = (/30/) ! seq indices into dstArray + + call ESMF_ArraySMMStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, factorList=factorList, & + factorIndexList=factorIndexList, rc=rc) ++ +
+
+ + deallocate(factorList) + deallocate(factorIndexList) + else if (localPet == 1) then + allocate(factorList(3)) ! PET 1 specifies 3 factor + allocate(factorIndexList(2,3)) + factorList = (/0.5, 0.5, 0.8/) ! factors + factorIndexList(1,:) = (/8, 2, 12/) ! seq indices into srcArray + factorIndexList(2,:) = (/11, 11, 30/) ! seq indices into dstArray + + call ESMF_ArraySMMStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, factorList=factorList, & + factorIndexList=factorIndexList, rc=rc) ++ +
+
+ + deallocate(factorList) + deallocate(factorIndexList) + else + ! PETs 2 and 3 do not provide factors + + call ESMF_ArraySMMStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, rc=rc) ++ +
+
+ endif ++ +
+The call into the ESMF_ArraySMM() operation is completely + transparent with respect to whether source and/or destination Arrays contain + undistributed dimensions. +
+
+ call ESMF_ArraySMM(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, rc=rc) ++ +
+This operation will initialize the entire dstArray to 0.0 and then + update four elements: + +
+
+ on DE 1: + dstArray[1](2) = 0.5 * srcArray(0,0)[1] + 0.5 * srcArray(0,2)[1], + dstArray[2](2) = 0.5 * srcArray(0,0)[2] + 0.5 * srcArray(0,2)[2] ++ +
+and + +
+
+ on DE 3: + dstArray[1](1) = 0.2 * srcArray(0,1)[1] + 0.8 * srcArray(1,3)[1], + dstArray[2](1) = 0.2 * srcArray(0,1)[2] + 0.8 * srcArray(1,3)[2]. ++ +
+Here indices between "()" refer to distributed dimensions while indices + between "[]" correspond to undistributed dimensions. + +
+In a more general version of the Array sparse matrix multiplication the + total undistributed element count, i.e. the product of the sizes + of all undistributed dimensions, need not be the same for source and + destination Array. In this formulation each non-zero element of the sparse + matrix is identified with a unique element in the source and destination + Array. This requires a generalization of the factorIndexList argument + which now must contain four integer numbers for each element. These numbers + in sequence are the sequence index of the distributed dimensions and the + sequence index of the undistributed dimensions of the element in the source + Array, followed by the sequence index of the distributed dimensions and + the sequence index of the undistributed dimensions of the element in the + destination Array. +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=3, rc=rc) + srcArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=srcDistgrid, & + totalLWidth=(/1,1/), totalUWidth=(/1,1/), indexflag=ESMF_INDEX_GLOBAL, & + distgridToArrayMap=(/1,2/), undistLBound=(/1/), undistUBound=(/2/), rc=rc) ++ +
+
+ call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_R8, rank=2, rc=rc) + dstArray = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=dstDistgrid, & + distgridToArrayMap=(/2/), undistLBound=(/1/), undistUBound=(/4/), rc=rc) ++ +
+Setting up factorList is identical to the previous cases since there is + still only one value associated with each non-zero matrix element. However, + each entry in factorIndexList now has 4 instead of just 2 components. +
+
+ if (localPet == 0) then + allocate(factorList(1)) ! PET 0 specifies 1 factor + allocate(factorIndexList(4,1)) + factorList = (/0.2/) ! factors + factorIndexList(1,:) = (/5/) ! seq indices into srcArray + factorIndexList(2,:) = (/1/) ! undistr. seq indices into srcArray + factorIndexList(3,:) = (/30/) ! seq indices into dstArray + factorIndexList(4,:) = (/2/) ! undistr. seq indices into dstArray + + call ESMF_ArraySMMStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, factorList=factorList, & + factorIndexList=factorIndexList, rc=rc) ++ +
+
+ + deallocate(factorList) + deallocate(factorIndexList) + else if (localPet == 1) then + allocate(factorList(3)) ! PET 1 specifies 3 factor + allocate(factorIndexList(4,3)) + factorList = (/0.5, 0.5, 0.8/) ! factors + factorIndexList(1,:) = (/8, 2, 12/) ! seq indices into srcArray + factorIndexList(2,:) = (/2, 1, 1/) ! undistr. seq indices into srcArray + factorIndexList(3,:) = (/11, 11, 30/) ! seq indices into dstArray + factorIndexList(4,:) = (/4, 4, 2/) ! undistr. seq indices into dstArray + + call ESMF_ArraySMMStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, factorList=factorList, & + factorIndexList=factorIndexList, rc=rc) ++ +
+
+ + deallocate(factorList) + deallocate(factorIndexList) + else + ! PETs 2 and 3 do not provide factors + + call ESMF_ArraySMMStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, rc=rc) ++ +
+
+ endif ++ +
+The call into the ESMF_ArraySMM() operation remains + unchanged. +
+
+ call ESMF_ArraySMM(srcArray=srcArray, dstArray=dstArray, & + routehandle=sparseMatMulHandle, rc=rc) ++ +
+This operation will initialize the entire dstArray to 0.0 and then + update two elements: + +
+
+ on DE 1: + dstArray[4](2) = 0.5 * srcArray(0,0)[1] + 0.5 * srcArray(0,2)[2], ++ +
+and + +
+
+ on DE 3: + dstArray[2](1) = 0.2 * srcArray(0,1)[1] + 0.8 * srcArray(1,3)[1], ++ +
+Here indices in refer to distributed dimensions while indices in + correspond to undistributed dimensions. + + +
+ +
+ +
+ +
+The ESMF_ArrayScatter() and ESMF_ArrayGather() calls, + introduced in section 28.2.14, provide a convenient + way of communicating data between a Fortran array and all of the DEs of + a single Array tile. A key requirement of ESMF_ArrayScatter() + and ESMF_ArrayGather() is that the shape of the Fortran array + and the Array tile must match. This means that the dimCount must be + equal, and that the size of each dimension must match. Element reordering + during scatter and gather is only supported on a per dimension level, + based on the decompflag option available during DistGrid creation. + +
+While the ESMF_ArrayScatter() and ESMF_ArrayGather() methods + cover a broad, and important spectrum of cases, there are situations that + require a different set of rules to scatter and gather data between a + Fortran array and an ESMF Array object. For instance, it is often convenient + to create an Array on a DistGrid that was created with arbitrary, + user-supplied sequence indices. See section 36.3.5 + for more background on DistGrids with arbitrary sequence indices. +
+
+ allocate(arbSeqIndexList(10)) ! each PET will have 10 elements + + do i=1, 10 + arbSeqIndexList(i) = (i-1)*petCount + localPet+1 ! initialize unique + ! seq. indices + enddo + + distgrid = ESMF_DistGridCreate(arbSeqIndexList=arbSeqIndexList, rc=rc) ++ +
+
+ deallocate(arbSeqIndexList) + + call ESMF_ArraySpecSet(arrayspec, typekind=ESMF_TYPEKIND_I4, rank=1, rc=rc) ++ +
+
+ array = ESMF_ArrayCreate(arrayspec=arrayspec, distgrid=distgrid, rc=rc) ++ +
+This array object holds 10 elements on each DE, and there is one DE + per PET, for a total element count of 10 x petCount. The + arbSeqIndexList, used during DistGrid creation, was constructed cyclic + across all DEs. DE 0, for example, on a 4 PET run, would hold sequence + indices 1, 5, 9, ... . DE 1 would hold 2, 6, 10, ..., and so on. + +
+The usefulness of the user-specified arbitrary sequence indices becomes + clear when they are interpreted as global element ids. The ArrayRedist() + and ArraySMM() communication methods are based on sequence index mapping + between source and destination Arrays. Other than providing a canonical + sequence index order via the default sequence scheme, outlined in + 28.2.18, ESMF does not place any restrictions on the + sequence indices. Objects that were not created with user supplied + sequence indices default to the ESMF sequence index order. + +
+A common, and useful interpretation of the arbitrary sequence indices, + specified during DistGrid creation, is that of relating them to the + canonical ESMF sequence index order of another data object. Within this + interpretation the array object created above could be viewed as an + arbitrary distribution of a (petCount x 10) 2D array. + +
+
+ if (localPet == 0) then + allocate(farray(petCount,10)) ! allocate 2D Fortran array petCount x 10 + do j=1, 10 + do i=1, petCount + farray(i,j) = 100 + (j-1)*petCount + i ! initialize to something + enddo + enddo + else + allocate(farray(0,0)) ! must allocate an array of size 0 on all other PETs + endif ++ +
+For a 4 PET run, farray on PET 0 now holds the following data. +
+ -----1----2----3------------10-----> j + | + 1 101, 105, 109, .... , 137 + | + 2 102, 106, 110, .... , 138 + | + 3 103, 107, 111, .... , 139 + | + 4 104, 108, 112, .... , 140 + | + | + v + i ++ +
+On all other PETs farray has a zero size allocation. + +
+Following the sequence index interpretation from above, scattering the data + contained in farray on PET 0 across the array object created + further up, seems like a well defined operation. Looking at it a bit closer, + it becomes clear that it is in fact more of a redistribution than a simple + scatter operation. The general rule for such a "redist-scatter" operation, + of a Fortran array, located on a single PET, into an ESMF Array, is to + use the canonical ESMF sequence index scheme to label the elements of the + Fortran array, and to send the data to the Array element with the same + sequence index. + +
+The just described "redist-scatter" operation is much more general than + the standard ESMF_ArrayScatter() method. It does not require shape + matching, and supports full element reordering based on the sequence indices. + Before farray can be scattered across array in the described way, + it must be wrapped into an ESMF Array object itself, essentially labeling the + array elements according to the canonical sequence index scheme. + +
+
+ distgridAux = ESMF_DistGridCreate(minIndex=(/1,1/), & + maxIndex=(/petCount,10/), & + regDecomp=(/1,1/), rc=rc) ! DistGrid with only 1 DE ++ +
+The first step is to create a DistGrid object with only a single DE. This + DE must be located on the PET on which the Fortran data array resides. + In this example farray holds data on PET 0, which is where the default + DELayout will place the single DE defined in the DistGrid. If the farray + was setup on a different PET, an explicit DELayout would need to be created + first, mapping the only DE to the PET on which the data is defined. + +
+Next the Array wrapper object can be created from the farray and the + just created DistGrid object. +
+
+ arrayAux = ESMF_ArrayCreate(farray=farray, distgrid=distgridAux, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) ++ +
+At this point all of the pieces are in place to use ESMF_ArrayRedist() + to do the "redist-scatter" operation. The typical store/execute/release + pattern must be followed. +
+
+ call ESMF_ArrayRedistStore(srcArray=arrayAux, dstArray=array, & + routehandle=scatterHandle, rc=rc) ++ +
+
+ call ESMF_ArrayRedist(srcArray=arrayAux, dstArray=array, & + routehandle=scatterHandle, rc=rc) ++ +
+In this example, after ESMF_ArrayRedist() was called, the content + of array on a 4 PET run would look like this: +
+ PET 0: 101, 105, 109, .... , 137 + PET 1: 102, 106, 110, .... , 138 + PET 2: 103, 107, 111, .... , 139 + PET 3: 104, 108, 112, .... , 140 ++ +
+Once set up, scatterHandle can be used repeatedly to scatter data + from farray on PET 0 to all the DEs of array. All of the + resources should be released once scatterHandle is no longer needed. +
+
+ call ESMF_ArrayRedistRelease(routehandle=scatterHandle, rc=rc) ++ +
+The opposite operation, i.e. gathering of the array data + into farray on PET 0, follows a very similar setup. In fact, the + arrayAux object already constructed for the scatter direction, can + directly be re-used. The only thing that is different for the "redist-gather", + are the srcArray and dstArray argument assignments, reflecting + the opposite direction of data movement. +
+
+ call ESMF_ArrayRedistStore(srcArray=array, dstArray=arrayAux, & + routehandle=gatherHandle, rc=rc) ++ +
+
+ call ESMF_ArrayRedist(srcArray=array, dstArray=arrayAux, & + routehandle=gatherHandle, rc=rc) ++ +
+Just as for the scatter case, the gatherHandle can be used repeatedly + to gather data from array into farray on PET 0. All of the + resources should be released once gatherHandle is no longer needed. +
+
+ call ESMF_ArrayRedistRelease(routehandle=gatherHandle, rc=rc) ++ +
+Finally the wrapper Array arrayAux and the associated DistGrid object + can also be destroyed. +
+
+ call ESMF_ArrayDestroy(arrayAux, rc=rc) ++ +
+
+ call ESMF_DistGridDestroy(distgridAux, rc=rc) ++ +
+Further, the primary data objects of this example must be deallocated + and destroyed. +
+
+ deallocate(farray) + + call ESMF_ArrayDestroy(array, rc=rc) ++ +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+All ESMF_RouteHandle based communication methods, like + ESMF_ArrayRedist(), ESMF_ArrayHalo() and ESMF_ArraySMM(), + can be executed in blocking or non-blocking mode. The non-blocking feature is + useful, for example, to overlap computation with communication, or to + implement a more loosely synchronized inter-Component interaction scheme than + is possible with the blocking communication mode. + +
+Access to the non-blocking execution mode is provided uniformly across all + RouteHandle based communication calls. Every such call contains the optional + routesyncflag argument of type ESMF_RouteSync_Flag. Section + 54.53 lists all of the valid settings for this flag. + +
+It is an execution time decision to select whether to invoke a precomputed + communication pattern, stored in a RouteHandle, in the blocking or + non-blocking mode. Neither requires specifically precomputed RouteHandles + - i.e. a RouteHandle is neither specifically blocking nor specifically + non-blocking. +
+
+ call ESMF_ArrayRedistStore(srcArray=srcArray, dstArray=dstArray, & + routehandle=routehandle, rc=rc) ++ +
+The returned RouteHandle routehandle can be used in blocking or + non-blocking execution calls. The application is free to switch between + both modes for the same RouteHandle. + +
+By default routesyncflag is set to ESMF_ROUTESYNC_BLOCKING in all of the + RouteHandle execution methods, and the behavior is that of the VM-wide + collective communication calls described in the previous sections. In the + blocking mode the user must assume that the communication call will not + return until all PETs have exchanged the precomputed information. On the + other hand, the user has no guarantee about the exact synchronization + behavior, and it is unsafe to make specific assumptions. What is guaranteed + in the blocking communication mode is that when the call returns on the + local PET, all data exchanges associated with all local DEs have finished. + This means that all in-bound data elements are valid and that all out-bound + data elements can safely be overwritten by the user. +
+
+ call ESMF_ArrayRedist(srcArray=srcArray, dstArray=dstArray, & + routehandle=routehandle, routesyncflag=ESMF_ROUTESYNC_BLOCKING, rc=rc) ++ +
+The same exchange pattern, that is encoded in routehandle, can be + executed in non-blocking mode, simply by setting the appropriate + routesyncflag when calling into ESMF_ArrayRedist(). + +
+At first sight there are obvious similarities between the non-blocking + RouteHandle based execution paradigm and the non-blocking message passing + calls provided by MPI. However, there are significant differences in + the behavior of the non-blocking point-to-point calls that MPI defines and + the non-blocking mode of the collective exchange patterns described by ESMF + RouteHandles. + +
+Setting routesyncflag to ESMF_ROUTESYNC_NBSTART in any RouteHandle + execution call returns immediately after all out-bound data has been moved + into ESMF internal transfer buffers and the exchange has been initiated. +
+
+ call ESMF_ArrayRedist(srcArray=srcArray, dstArray=dstArray, & + routehandle=routehandle, routesyncflag=ESMF_ROUTESYNC_NBSTART, rc=rc) ++ +
+Once a call with routesyncflag = ESMF_ROUTESYNC_NBSTART returns, it is safe + to modify the out-bound data elements in the srcArray object. However, + no guarantees are made for the in-bound data elements in dstArray at + this phase of the non-blocking execution. It is unsafe to access these + elements until the exchange has finished locally. + +
+One way to ensure that the exchange has finished locally is to call + with routesyncflag set to ESMF_ROUTESYNC_NBWAITFINISH. + +
+
+ call ESMF_ArrayRedist(srcArray=srcArray, dstArray=dstArray, & + routehandle=routehandle, routesyncflag=ESMF_ROUTESYNC_NBWAITFINISH, rc=rc) ++ +
+Calling with routesyncflag = ESMF_ROUTESYNC_NBWAITFINISH instructs the + communication method to wait and block until the previously started + exchange has finished, and has been processed locally according to + the RouteHandle. Once the call returns, it is safe to access both in-bound + and out-bound data elements in dstArray and srcArray, + respectively. + +
+Some situations require more flexibility than is provided by the + ESMF_ROUTESYNC_NBSTART - ESMF_ROUTESYNC_NBWAITFINISH pair. For + instance, a Component that needs to interact with several other Components, + virtually simultaneously, would initiated several different exchanges with + ESMF_ROUTESYNC_NBSTART. Calling with ESMF_ROUTESYNC_NBWAITFINISH for + any of the outstanding exchanges may potentially block for a long time, + lowering the throughput. In the worst case a dead lock situation may arise. + Calling with routesyncflag = ESMF_ROUTESYNC_NBTESTFINISH addresses this problem. + +
+
+ call ESMF_ArrayRedist(srcArray=srcArray, dstArray=dstArray, & + routehandle=routehandle, routesyncflag=ESMF_ROUTESYNC_NBTESTFINISH, & + finishedflag=finishflag, rc=rc) ++ +
+This call tests the locally outstanding data transfer operation in + routehandle, and finishes the exchange as much as currently possible. + It does not block until the entire exchange has finished locally, instead + it returns immediately after one round of testing has been + completed. The optional return argument finishedflag is set to + .true. if the exchange is completely finished locally, and set to + .false. otherwise. + +
+The user code must decide, depending on the value of the returned + finishedflag, whether additional calls are required to finish an + outstanding non-blocking exchange. If so, it can be done by + calling ESMF_ArrayRedist() repeatedly with + ESMF_ROUTESYNC_NBTESTFINISH until + finishedflag comes back with a value of .true.. Such a loop + allows other pieces of user code to be executed between the calls. + A call with ESMF_ROUTESYNC_NBWAITFINISH can alternatively be used to + block until the exchange has locally finished. + +
+Noteworthy property. + It is allowable to invoke a RouteHandle based communication call + with routesyncflag set to + ESMF_ROUTESYNC_NBTESTFINISH or + ESMF_ROUTESYNC_NBWAITFINISH on a specific RouteHandle without there + being an outstanding non-blocking exchange. As a matter of fact, it is not + required that there was ever a call made with ESMF_ROUTESYNC_NBSTART for + the RouteHandle. In these cases the calls made with + ESMF_ROUTESYNC_NBTESTFINISH or ESMF_ROUTESYNC_NBWAITFINISH will + simply return immediately (with finishedflag set to .true.). + +
+Noteworthy property. + It is fine to mix blocking and non-blocking invocations of the same + RouteHandle based communication call across the PETs. This means that it is + fine for some PETs to issue the call with ESMF_ROUTESYNC_BLOCKING + (or using the default), while other PETs call the same communication call + with ESMF_ROUTESYNC_NBSTART. + +
+Noteworthy restriction. + A RouteHandle that is currently involved in an outstanding non-blocking + exchange may not be used to start any further exchanges, neither + blocking nor non-blocking. This restriction is independent of whether the + newly started RouteHandle based exchange is made for the same or for + different data objects. + +
+ + +
+
+
+The Array class is part of the ESMF index space layer and is built on top of the DistGrid and DELayout classes. The DELayout class introduces the notion of +decomposition elements (DEs) and their layout across the available PETs. The DistGrid describes how index space is decomposed by assigning logically rectangular index space pieces or DE-local tiles to the DEs. The Array finally associates a local memory allocation with each local DE. + +
+The following is a list of implementation specific details about the current ESMF Array. + +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + array1 = array2 +ARGUMENTS: +
type(ESMF_Array) :: array1 + type(ESMF_Array) :: array2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign array1 as an alias to the same ESMF Array object in memory + as array2. If array2 is invalid, then array1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (array1 == array2) then ... endif + OR + result = (array1 == array2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array1 + type(ESMF_Array), intent(in) :: array2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether array1 and array2 are valid aliases to the same ESMF + Array object in memory. For a more general comparison of two ESMF Arrays, + going beyond the simple alias test, the ESMF_ArrayMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (array1 /= array2) then ... endif + OR + result = (array1 /= array2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array1 + type(ESMF_Array), intent(in) :: array2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether array1 and array2 are not valid aliases to the + same ESMF Array object in memory. For a more general comparison of two ESMF + Arrays, going beyond the simple alias test, the ESMF_ArrayMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayCopy(arrayOut, arrayIn, rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: arrayOut + type(ESMF_Array), intent(in) :: arrayIn + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Copy data from one ESMF_Array object to another. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayCreate() + function ESMF_ArrayCreateFrmPtr<rank><type><kind>(distgrid, farrayPtr, & + datacopyflag, distgridToArrayMap, computationalEdgeLWidth, & + computationalEdgeUWidth, computationalLWidth, & + computationalUWidth, totalLWidth, & + totalUWidth, name, rc) +RETURN VALUE: +
type(ESMF_Array) :: ESMF_ArrayCreateDataPtr<rank><type><kind> +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: distgridToArrayMap(:) + integer, intent(in), optional :: computationalEdgeLWidth(:) + integer, intent(in), optional :: computationalEdgeUWidth(:) + integer, intent(in), optional :: computationalLWidth(:) + integer, intent(in), optional :: computationalUWidth(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Array object from existing local native Fortran + arrays with pointer attribute. The decomposition and distribution is + specified by the distgrid argument. Each PET must issue this call + with identical arguments in order to create a consistent Array object. + The only exception is the farrayPtr argument which will be different + on each PET. The bounds of the local arrays are preserved by this call and + determine the bounds of the total region of the + resulting Array object. Bounds of the DE-local exclusive regions are set + to be consistent with the total regions and the specified distgrid + argument. Bounds for Array dimensions that are not distributed are + automatically set to the bounds provided by farrayPtr. + +
+This interface requires a 1 DE per PET decomposition. The Array object will + not be created and an error will be returned if this condition is not met. + +
+The not distributed Array dimensions form a tensor of rank = array.rank - + distgrid.dimCount. The widths of the computational region are set to + the provided value, or zero by default, for all tensor elements. Use + ESMF_ArraySet() to change these default settings after the + Array object has been created. + +
+The return value is the newly created ESMF_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayCreate() + function ESMF_ArrayCreateFrmPtrArb<indexkind><rank><type><kind>(distgrid, & + farrayPtr, haloSeqIndexList, datacopyflag, & + distgridToArrayMap, name, rc) +RETURN VALUE: +
type(ESMF_Array) :: ESMF_ArrayCreateDataPtrArb<rank><type><kind> +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + integer(ESMF_KIND_<indexkind>), intent(in) :: haloSeqIndexList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: distgridToArrayMap(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Array object from existing local native Fortran + arrays with pointer attribute, according to distgrid. Besides + farrayPtr each PET must issue this call with identical arguments in + order to create a consistent Array object. The bounds of the local arrays + are preserved by this call and determine the bounds of the total region of + the resulting Array object. Bounds of the DE-local exclusive regions are + set to be consistent with the total regions and the specified distgrid + argument. Bounds for Array dimensions that are not distributed are + automatically set to the bounds provided by farrayPtr. + +
+This interface requires a 1 DE per PET decomposition. The Array object will + not be created and an error will be returned if this condition is not met. + +
+The not distributed Array dimensions form a tensor of rank = array.rank - + distgrid.dimCount. The widths of the computational region are set to + the provided value, or zero by default, for all tensor elements. Use + ESMF_ArraySet() to change these default settings after the + Array object has been created. + +
+The return value is the newly created ESMF_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayCreate() + function ESMF_ArrayCreateAsmdSp<rank><type><kind>(distgrid, farray, & + indexflag, datacopyflag, distgridToArrayMap, & + computationalEdgeLWidth, computationalEdgeUWidth, computationalLWidth, & + computationalUWidth, totalLWidth, & + totalUWidth, undistLBound, undistUBound, name, rc) +RETURN VALUE: +
type(ESMF_Array) :: ESMF_ArrayCreateDataAssmdShape<rank><type><kind> +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + <type> (ESMF_KIND_<kind>), intent(in), target :: farray(<rank>) + type(ESMF_Index_Flag), intent(in) :: indexflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: distgridToArrayMap(:) + integer, intent(in), optional :: computationalEdgeLWidth(:) + integer, intent(in), optional :: computationalEdgeUWidth(:) + integer, intent(in), optional :: computationalLWidth(:) + integer, intent(in), optional :: computationalUWidth(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(in), optional :: undistLBound(:) + integer, intent(in), optional :: undistUBound(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Array object from an existing local native Fortran + array. The decomposition and distribution is + specified by the distgrid argument. Each PET must issue this call + with identical arguments in order to create a consistent Array object. + The only exception is the farray argument which will be different + on each PET. The local arrays provided must be dimensioned according to + the DE-local total region. Bounds of the exclusive regions are set as + specified in the distgrid argument. Bounds for Array dimensions + that are not distributed can be chosen freely using the + undistLBound and undistUBound arguments. + +
+This interface requires a 1 DE per PET decomposition. The Array object will + not be created and an error will be returned if this condition is not met. + +
+The not distributed Array dimensions form a tensor of rank = array.rank - + distgrid.dimCount. The widths of the computational region are set to + the provided value, or zero by default, for all tensor elements. Use + ESMF_ArraySet() to change these default settings after the + Array object has been created. + +
+The return value is the newly created ESMF_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayCreate() + function ESMF_ArrayCreateAsmdSpArb<indexkind><rank><type><kind>(distgrid, & + farray, indexflag, haloSeqIndexList, datacopyflag, & + distgridToArrayMap, computationalEdgeLWidth, computationalEdgeUWidth, & + computationalLWidth, computationalUWidth, totalLWidth, totalUWidth, & + undistLBound, undistUBound, name, rc) +RETURN VALUE: +
type(ESMF_Array) :: ESMF_ArrayCreateDataAssmdShapeArb<rank><type><kind> +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + <type> (ESMF_KIND_<kind>), intent(in), target :: farray(<rank>) + type(ESMF_Index_Flag), intent(in) :: indexflag + integer(ESMF_KIND_<indexkind>), intent(in) :: haloSeqIndexList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: distgridToArrayMap(:) + integer, intent(in), optional :: computationalEdgeLWidth(:) + integer, intent(in), optional :: computationalEdgeUWidth(:) + integer, intent(in), optional :: computationalLWidth(:) + integer, intent(in), optional :: computationalUWidth(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(in), optional :: undistLBound(:) + integer, intent(in), optional :: undistUBound(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Array object from an existing local native Fortran + array. The decomposition and distribution is + specified by the distgrid argument. Each PET must issue this call + with identical arguments in order to create a consistent Array object. + The only exception is the farray argument which will be different + on each PET. The local arrays provided must be dimensioned according to + the DE-local total region. Bounds of the exclusive regions are set as + specified in the distgrid argument. Bounds for Array dimensions + that are not distributed can be chosen freely using the + undistLBound and undistUBound arguments. + +
+This interface requires a 1 DE per PET decomposition. The Array object will + not be created and an error will be returned if this condition is not met. + +
+The not distributed Array dimensions form a tensor of rank = array.rank - + distgrid.dimCount. The widths of the computational region are set to + the provided value, or zero by default, for all tensor elements. Use + ESMF_ArraySet() to change these default settings after the + Array object has been created. + +
+The return value is the newly created ESMF_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayCreate() + function ESMF_ArrayCreateLocalArray(distgrid, localarrayList, & + indexflag, datacopyflag, distgridToArrayMap, computationalEdgeLWidth, & + computationalEdgeUWidth, computationalLWidth, computationalUWidth, & + totalLWidth, totalUWidth, undistLBound, undistUBound, name, rc) +RETURN VALUE: +
type(ESMF_Array) :: ESMF_ArrayCreateLocalArray +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + type(ESMF_LocalArray), intent(in) :: localarrayList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_DataCopy_Flag),intent(in), optional :: datacopyflag + integer, intent(in), optional :: distgridToArrayMap(:) + integer, intent(in), optional :: computationalEdgeLWidth(:) + integer, intent(in), optional :: computationalEdgeUWidth(:) + integer, intent(in), optional :: computationalLWidth(:) + integer, intent(in), optional :: computationalUWidth(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(in), optional :: undistLBound(:) + integer, intent(in), optional :: undistUBound(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Array object from existing ESMF_LocalArray + objects. The decomposition and distribution is + specified by the distgrid argument. Each PET must issue this call + with identical arguments in order to create a consistent Array object. + The only exception is the localarrayList argument which will be + different on each PET. The local arrays provided must be dimensioned + according to the DE-local total region. Bounds of the exclusive regions + are set as specified in the distgrid argument. Bounds for Array + dimensions that are not distributed can be chosen freely using the + undistLBound and undistUBound arguments. + +
+This interface is able to handle multiple DEs per PET. + +
+The not distributed Array dimensions form a tensor of rank = array.rank - + distgrid.dimCount. The widths of the computational region are set to + the provided value, or zero by default, for all tensor elements. Use + ESMF_ArraySet() to change these default settings after the + Array object has been created. + +
+The return value is the newly created ESMF_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayCreate() + function ESMF_ArrayCreateLocalArrayArb<indexkind>(distgrid, localarrayList, & + haloSeqIndexList, indexflag, datacopyflag, & + distgridToArrayMap, computationalEdgeLWidth, computationalEdgeUWidth, & + computationalLWidth, computationalUWidth, & + totalLWidth, totalUWidth, undistLBound, undistUBound, name, rc) +RETURN VALUE: +
type(ESMF_Array) :: ESMF_ArrayCreateLocalArrayArb +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + type(ESMF_LocalArray), intent(in) :: localarrayList(:) + integer(ESMF_KIND_<indexkind>), intent(in) :: haloSeqIndexList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_DataCopy_Flag),intent(in), optional :: datacopyflag + integer, intent(in), optional :: distgridToArrayMap(:) + integer, intent(in), optional :: computationalEdgeLWidth(:) + integer, intent(in), optional :: computationalEdgeUWidth(:) + integer, intent(in), optional :: computationalLWidth(:) + integer, intent(in), optional :: computationalUWidth(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(in), optional :: undistLBound(:) + integer, intent(in), optional :: undistUBound(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Array object from existing ESMF_LocalArray + objects according to distgrid. Each PET must issue this call in unison + in order to create a consistent Array object. The local arrays provided must + be dimensioned according to the DE-local total region. Bounds of the + exclusive regions are set as specified in the distgrid argument. Bounds + for array dimensions that are not distributed can be chosen freely using + the undistLBound and undistUBound arguments. + +
+The return value is the newly created ESMF_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayCreate() + function ESMF_ArrayCreateAllocate(distgrid, typekind, & + indexflag, pinflag, distgridToArrayMap, computationalEdgeLWidth, & + computationalEdgeUWidth, computationalLWidth, computationalUWidth, & + totalLWidth, totalUWidth, undistLBound, undistUBound, name, vm, rc) +RETURN VALUE: +
type(ESMF_Array) :: ESMF_ArrayCreateAllocate +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + type(ESMF_TypeKind_Flag), intent(in) :: typekind + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + integer, intent(in), optional :: distgridToArrayMap(:) + integer, intent(in), optional :: computationalEdgeLWidth(:) + integer, intent(in), optional :: computationalEdgeUWidth(:) + integer, intent(in), optional :: computationalLWidth(:) + integer, intent(in), optional :: computationalUWidth(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(in), optional :: undistLBound(:) + integer, intent(in), optional :: undistUBound(:) + character (len=*), intent(in), optional :: name + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Array object and allocate uninitialized data space + according to typekind and distgrid. The Array rank is indirectly determined + by the incoming information. Each PET must issue this call in unison in order + to create a consistent Array object. DE-local allocations are made according + to the total region defined by the distgrid and the optional Width + arguments. + +
+The return value is the newly created ESMF_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayCreate() + function ESMF_ArrayCreateAllocateArb<indexkind>(distgrid, typekind, & + haloSeqIndexList, pinflag, distgridToArrayMap, & + undistLBound, undistUBound, name, rc) +RETURN VALUE: +
type(ESMF_Array) :: ESMF_ArrayCreateAllocateArb +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + type(ESMF_TypeKind_Flag), intent(in) :: typekind + integer(ESMF_KIND_<indexkind>), intent(in) :: haloSeqIndexList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + integer, intent(in), optional :: distgridToArrayMap(:) + integer, intent(in), optional :: undistLBound(:) + integer, intent(in), optional :: undistUBound(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Array object and allocate uninitialized data space + according to typekind and distgrid. The Array rank is indirectly determined + by the incoming information. Each PET must issue this call in unison in order + to create a consistent Array object. DE-local allocations are made according + to the total region defined by the distgrid and haloSeqIndexList + arguments. + +
+The return value is the newly created ESMF_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayCreate() + function ESMF_ArrayCreateAllocateAS(distgrid, arrayspec, & + indexflag, pinflag, distgridToArrayMap, computationalEdgeLWidth, & + computationalEdgeUWidth, computationalLWidth, computationalUWidth, & + totalLWidth, totalUWidth, undistLBound, undistUBound, name, vm, rc) +RETURN VALUE: +
type(ESMF_Array) :: ESMF_ArrayCreateAllocateAS +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + type(ESMF_ArraySpec), intent(in) :: arrayspec + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + integer, intent(in), optional :: distgridToArrayMap(:) + integer, intent(in), optional :: computationalEdgeLWidth(:) + integer, intent(in), optional :: computationalEdgeUWidth(:) + integer, intent(in), optional :: computationalLWidth(:) + integer, intent(in), optional :: computationalUWidth(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + integer, intent(in), optional :: undistLBound(:) + integer, intent(in), optional :: undistUBound(:) + character (len=*), intent(in), optional :: name + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Array object and allocate uninitialized data space + according to arrayspec and distgrid. Each PET must issue + this call with identical arguments in order to create a consistent Array + object. DE-local allocations are made according to the total region defined + by the arguments to this call: distgrid and the optional Width + arguments. + +
+The return value is the newly created ESMF_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayCreate() + function ESMF_ArrayCreateAllocateASArb<indexkind>(distgrid, arrayspec, & + haloSeqIndexList, pinflag, distgridToArrayMap, & + undistLBound, undistUBound, name, rc) +RETURN VALUE: +
type(ESMF_Array) :: ESMF_ArrayCreateAllocateASArb +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + type(ESMF_ArraySpec), intent(in) :: arrayspec + integer(ESMF_KIND_<indexkind>), intent(in) :: haloSeqIndexList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + integer, intent(in), optional :: distgridToArrayMap(:) + integer, intent(in), optional :: undistLBound(:) + integer, intent(in), optional :: undistUBound(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Array object and allocate uninitialized data space + according to arrayspec and distgrid. Each PET must issue this call in unison + in order to create a consistent Array object. DE-local allocations are made + according to the total region defined by the arguments to this call: + distgrid and haloSeqIndexList arguments. + +
+The return value is the newly created ESMF_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayCreate() + function ESMF_ArrayCreateFromArray(array, datacopyflag, delayout, & + trailingUndistSlice, name, rc) +RETURN VALUE: +
type(ESMF_Array) :: ESMF_ArrayCreateFromArray +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + type(ESMF_DELayout), intent(in), optional :: delayout + integer, intent(in), optional :: trailingUndistSlice(:) + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_Array object from an existing Array. Supports array + slicing. + +
+The return value is the newly created ESMF_Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayDestroy(array, noGarbage, rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroy an ESMF_Array, releasing the resources associated with + the object. + +
+By default a small remnant of the object is kept in memory in order to + prevent problems with dangling aliases. The default garbage collection + mechanism can be overridden with the noGarbage argument. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayGather(array, farray, rootPet, tile, vm, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + <type>(ESMF_KIND_<kind>), intent(out), target :: farray(<rank>) + integer, intent(in) :: rootPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: tile + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gather the data of an ESMF_Array object into the farray located on + rootPET. A single DistGrid tile of array must be + gathered into farray. The optional tile + argument allows selection of the tile. For Arrays defined on a single + tile DistGrid the default selection (tile 1) will be correct. The + shape of farray must match the shape of the tile in Array. + +
+If the Array contains replicating DistGrid dimensions data will be + gathered from the numerically higher DEs. Replicated data elements in + numerically lower DEs will be ignored. + +
+This version of the interface implements the PET-based blocking paradigm: + Each PET of the VM must issue this call exactly once for all of its + DEs. The call will block until all PET-local data objects are accessible. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayGet() + subroutine ESMF_ArrayGetDefault(array, arrayspec, typekind, & + rank, localarrayList, indexflag, distgridToArrayMap, & + distgridToPackedArrayMap, arrayToDistGridMap, undistLBound, & + undistUBound, exclusiveLBound, exclusiveUBound, computationalLBound, & + computationalUBound, totalLBound, totalUBound, computationalLWidth, & + computationalUWidth, totalLWidth, totalUWidth, distgrid, & + dimCount, undistDimCount, replicatedDimCount, & + tileCount, minIndexPTile, maxIndexPTile, deToTileMap, indexCountPDe, & + delayout, deCount, localDeCount, ssiLocalDeCount, localDeToDeMap, & + localDeList, & ! DEPRECATED ARGUMENT + isESMFAllocated, name, vm, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_ArraySpec), intent(out), optional :: arrayspec + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: rank + type(ESMF_LocalArray), target, intent(out), optional :: localarrayList(:) + type(ESMF_Index_Flag), intent(out), optional :: indexflag + integer, target, intent(out), optional :: distgridToArrayMap(:) + integer, target, intent(out), optional :: distgridToPackedArrayMap(:) + integer, target, intent(out), optional :: arrayToDistGridMap(:) + integer, target, intent(out), optional :: undistLBound(:) + integer, target, intent(out), optional :: undistUBound(:) + integer, target, intent(out), optional :: exclusiveLBound(:,:) + integer, target, intent(out), optional :: exclusiveUBound(:,:) + integer, target, intent(out), optional :: computationalLBound(:,:) + integer, target, intent(out), optional :: computationalUBound(:,:) + integer, target, intent(out), optional :: totalLBound(:,:) + integer, target, intent(out), optional :: totalUBound(:,:) + integer, target, intent(out), optional :: computationalLWidth(:,:) + integer, target, intent(out), optional :: computationalUWidth(:,:) + integer, target, intent(out), optional :: totalLWidth(:,:) + integer, target, intent(out), optional :: totalUWidth(:,:) + type(ESMF_DistGrid), intent(out), optional :: distgrid + integer, intent(out), optional :: dimCount + integer, intent(out), optional :: undistDimCount + integer, intent(out), optional :: replicatedDimCount + integer, intent(out), optional :: tileCount + integer, intent(out), optional :: minIndexPTile(:,:) + integer, intent(out), optional :: maxIndexPTile(:,:) + integer, intent(out), optional :: deToTileMap(:) + integer, intent(out), optional :: indexCountPDe(:,:) + type(ESMF_DELayout), intent(out), optional :: delayout + integer, intent(out), optional :: deCount + integer, intent(out), optional :: localDeCount + integer, intent(out), optional :: ssiLocalDeCount + integer, intent(out), optional :: localDeToDeMap(:) + integer, intent(out), optional :: localDeList(:) ! DEPRECATED ARGUMENT + logical, intent(out), optional :: isESMFAllocated + character(len=*), intent(out), optional :: name + type(ESMF_VM), intent(out), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get internal information. + +
+This interface works for any number of DEs per PET. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayGet() + subroutine ESMF_ArrayGetPLocalDePDim(array, dim, localDe, & + indexCount, indexList, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + integer, intent(in) :: dim + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: localDe + integer, intent(out), optional :: indexCount + integer, intent(out), optional :: indexList(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get internal information per local DE, per dim. + +
+This interface works for any number of DEs per PET. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayGet() + subroutine ESMF_ArrayGetFPtr<rank><type><kind>(array, localDe, & + farrayPtr, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: localDe + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Access Fortran array pointer to the specified DE-local memory allocation of + the Array object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayGet() + subroutine ESMF_ArrayGetLocalArray(array, localDe, localarray, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: localDe + type(ESMF_LocalArray), intent(inout) :: localarray + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Provide access to ESMF_LocalArray object that holds data for + the specified local DE. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayHalo(array, routehandle, & + routesyncflag, finishedflag, cancelledflag, checkflag, rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: array + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_RouteSync_Flag), intent(in), optional :: routesyncflag + logical, intent(out), optional :: finishedflag + logical, intent(out), optional :: cancelledflag + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed Array halo operation for array. + The array argument must match the respective Array + used during ESMF_ArrayHaloStore() in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+See ESMF_ArrayHaloStore() on how to precompute routehandle. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayHaloRelease(routehandle, noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with an Array halo operation. + After this call routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayHaloStore(array, routehandle, & + startregion, haloLDepth, haloUDepth, pipelineDepth, rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: array + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_StartRegion_Flag), intent(in), optional :: startregion + integer, intent(in), optional :: haloLDepth(:) + integer, intent(in), optional :: haloUDepth(:) + integer, intent(inout), optional :: pipelineDepth + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Store an Array halo operation over the data in array. By default, + i.e. without specifying startregion, haloLDepth and + haloUDepth, all elements in the total Array region that lie outside + the exclusive region will be considered potential destination elements for + halo. However, only those elements that have a corresponding halo source + element, i.e. an exclusive element on one of the DEs, will be updated under + the halo operation. Elements that have no associated source remain + unchanged under halo. + +
+Specifying startregion allows the shape of the effective halo region + to be changed from the inside. Setting this flag to + ESMF_STARTREGION_COMPUTATIONAL means that only elements outside + the computational region of the Array are considered for potential + destination elements for the halo operation. The default is + ESMF_STARTREGION_EXCLUSIVE. + +
+The haloLDepth and haloUDepth arguments allow to reduce + the extent of the effective halo region. Starting at the region specified + by startregion, the haloLDepth and haloUDepth + define a halo depth in each direction. Note that the maximum halo region is + limited by the total Array region, independent of the actual + haloLDepth and haloUDepth setting. The total Array region is + local DE specific. The haloLDepth and haloUDepth are interpreted + as the maximum desired extent, reducing the potentially larger region + available for the halo operation. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArrayHalo() on any Array that matches + array in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This call is collective across the current VM. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_ArrayIsCreated(array, rc) +RETURN VALUE: +
logical :: ESMF_ArrayIsCreated +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the array has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayLog(array, prefix, logMsgFlag, deepFlag, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: prefix + type(ESMF_LogMsg_Flag), intent(in), optional :: logMsgFlag + logical, intent(in), optional :: deepFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write information about array to the ESMF default Log. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayPrint(array, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Print internal information of the specified ESMF_Array object.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayRead(array, fileName, variableName, & + timeslice, iofmt, rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: array + character(*), intent(in) :: fileName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 Array data from file and put it into an ESMF_Array object. + For this API to be functional, the environment variable ESMF_PIO + should be set to either "internal" or "external" when the ESMF library is built. + Please see the section on Data I/O, 38.2. + +
+Limitations: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayRedist(srcArray, dstArray, routehandle, & + routesyncflag, finishedflag, cancelledflag, zeroregion, checkflag, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in), optional :: srcArray + type(ESMF_Array), intent(inout), optional :: dstArray + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_RouteSync_Flag), intent(in), optional :: routesyncflag + logical, intent(out), optional :: finishedflag + logical, intent(out), optional :: cancelledflag + type(ESMF_Region_Flag), intent(in), optional :: zeroregion + logical, intent(in), optional :: checkflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed Array redistribution from srcArray + to dstArray. + Both srcArray and dstArray must match the respective Arrays + used during ESMF_ArrayRedisttore() in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+The srcArray and dstArray arguments are optional in support of + the situation where srcArray and/or dstArray are not defined on + all PETs. The srcArray and dstArray must be specified on those + PETs that hold source or destination DEs, respectively, but may be omitted + on all other PETs. PETs that hold neither source nor destination DEs may + omit both arguments. + +
+It is erroneous to specify the identical Array object for srcArray and + dstArray arguments. + +
+See ESMF_ArrayRedistStore() on how to precompute + routehandle. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayRedistRelease(routehandle, noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with an Array redistribution. After this call + routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayRedistStore() + subroutine ESMF_ArrayRedistStore<type><kind>(srcArray, dstArray, & + routehandle, factor, srcToDstTransposeMap, & + ignoreUnmatchedIndices, pipelineDepth, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: srcArray + type(ESMF_Array), intent(inout) :: dstArray + type(ESMF_RouteHandle), intent(inout) :: routehandle + <type>(ESMF_KIND_<kind>),intent(in) :: factor + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: srcToDstTransposeMap(:) + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: pipelineDepth + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+ ESMF_ArrayRedistStore() is a collective method across all PETs of the + current Component. The interface of the method is overloaded, allowing + - in principle - each PET to call into ESMF_ArrayRedistStore() + through a different entry point. Restrictions apply as to which combinations + are sensible. All other combinations result in ESMF run time errors. The + complete semantics of the ESMF_ArrayRedistStore() method, as provided + through the separate entry points shown in 28.5.31 and + 28.5.33, is described in the following paragraphs as a whole. + +
+Store an Array redistribution operation from srcArray to dstArray. + Interface 28.5.31 allows PETs to specify a factor + argument. PETs not specifying a factor argument call into interface + 28.5.33. If multiple PETs specify the factor argument, + its type and kind, as well as its value must match across all PETs. If none + of the PETs specify a factor argument the default will be a factor of + 1. The resulting factor is applied to all of the source data during + redistribution, allowing scaling of the data, e.g. for unit transformation. + +
+Both srcArray and dstArray are interpreted as sequentialized + vectors. The sequence is defined by the order of DistGrid dimensions and the + order of tiles within the DistGrid or by user-supplied arbitrary sequence + indices. See section 28.2.18 for details on the definition + of sequence indices. + +
+Source Array, destination Array, and the factor may be of different + <type><kind>. Further, source and destination Arrays may differ in shape, + however, the number of elements must match. + +
+The default redistribution operation, when srcToDstTransposeMap is not + specified, corresponds to the identity mapping: each element of the + sequentialized source Array is copied to the sequentialized + destination Array element in order. + +
+If the srcToDstTransposeMap argument is provided it must be identical + across all PETs. The srcToDstTransposeMap allows source and destination + Array dimensions to be transposed during the redistribution. To support this + option, the number of source and destination Array dimensions must be equal + and the size of the associated dimensions must match. + See section 28.2.17 for more details about the + use of the srcToDstTransposeMap argument. + +
+It is erroneous to specify the identical Array object for srcArray and + dstArray arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArrayRedist() on any pair of Arrays that matches + srcArray and dstArray in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+
+This call is collective across the current VM. + +
+
+
+
+
+
+
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayRedistStore() + subroutine ESMF_ArrayRedistStore<type><kind>TP(srcArray, dstArray, & + routehandle, transposeRoutehandle, factor, & + srcToDstTransposeMap, ignoreUnmatchedIndices, pipelineDepth, rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: srcArray + type(ESMF_Array), intent(inout) :: dstArray + type(ESMF_RouteHandle), intent(inout) :: routehandle + type(ESMF_RouteHandle), intent(inout) :: transposeRoutehandle + <type>(ESMF_KIND_<kind>),intent(in) :: factor + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: srcToDstTransposeMap(:) + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: pipelineDepth + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ ESMF_ArrayRedistStore() is a collective method across all PETs of the + current Component. The interface of the method is overloaded, allowing + - in principle - each PET to call into ESMF_ArrayRedistStore() + through a different entry point. Restrictions apply as to which combinations + are sensible. All other combinations result in ESMF run time errors. The + complete semantics of the ESMF_ArrayRedistStore() method, as provided + through the separate entry points shown in 28.5.32 and + 28.5.34, is described in the following paragraphs as a whole. + +
+Store an Array redistribution operation from srcArray to dstArray. + Interface 28.5.32 allows PETs to specify a factor + argument. PETs not specifying a factor argument call into interface + 28.5.34. If multiple PETs specify the factor argument, + its type and kind, as well as its value must match across all PETs. If none + of the PETs specify a factor argument the default will be a factor of + 1. The resulting factor is applied to all of the source data during + redistribution, allowing scaling of the data, e.g. for unit transformation. + +
+Both srcArray and dstArray are interpreted as sequentialized + vectors. The sequence is defined by the order of DistGrid dimensions and the + order of tiles within the DistGrid or by user-supplied arbitrary sequence + indices. See section 28.2.18 for details on the definition + of sequence indices. + +
+Source Array, destination Array, and the factor may be of different + <type><kind>. Further, source and destination Arrays may differ in shape, + however, the number of elements must match. + +
+The default redistribution operation, when srcToDstTransposeMap is not + specified, corresponds to the identity mapping: each element of the + sequentialized source Array is copied to the sequentialized + destination Array element in order. + +
+If the srcToDstTransposeMap argument is provided it must be identical + across all PETs. The srcToDstTransposeMap allows source and destination + Array dimensions to be transposed during the redistribution. To support this + option, the number of source and destination Array dimensions must be equal + and the size of the associated dimensions must match. + See section 28.2.17 for more details about the + use of the srcToDstTransposeMap argument. + +
+It is erroneous to specify the identical Array object for srcArray and + dstArray arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArrayRedist() on any pair of Arrays that matches + srcArray and dstArray in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+
+This call is collective across the current VM. + +
+
+
+
+
+
+
+
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayRedistStore() + subroutine ESMF_ArrayRedistStoreNF(srcArray, dstArray, routehandle, & + srcToDstTransposeMap, ignoreUnmatchedIndices, & + pipelineDepth, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: srcArray + type(ESMF_Array), intent(inout) :: dstArray + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: srcToDstTransposeMap(:) + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: pipelineDepth + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+ ESMF_ArrayRedistStore() is a collective method across all PETs of the + current Component. The interface of the method is overloaded, allowing + - in principle - each PET to call into ESMF_ArrayRedistStore() + through a different entry point. Restrictions apply as to which combinations + are sensible. All other combinations result in ESMF run time errors. The + complete semantics of the ESMF_ArrayRedistStore() method, as provided + through the separate entry points shown in 28.5.31 and + 28.5.33, is described in the following paragraphs as a whole. + +
+Store an Array redistribution operation from srcArray to dstArray. + Interface 28.5.31 allows PETs to specify a factor + argument. PETs not specifying a factor argument call into interface + 28.5.33. If multiple PETs specify the factor argument, + its type and kind, as well as its value must match across all PETs. If none + of the PETs specify a factor argument the default will be a factor of + 1. The resulting factor is applied to all of the source data during + redistribution, allowing scaling of the data, e.g. for unit transformation. + +
+Both srcArray and dstArray are interpreted as sequentialized + vectors. The sequence is defined by the order of DistGrid dimensions and the + order of tiles within the DistGrid or by user-supplied arbitrary sequence + indices. See section 28.2.18 for details on the definition + of sequence indices. + +
+Source Array, destination Array, and the factor may be of different + <type><kind>. Further, source and destination Arrays may differ in shape, + however, the number of elements must match. + +
+The default redistribution operation, when srcToDstTransposeMap is not + specified, corresponds to the identity mapping: each element of the + sequentialized source Array is copied to the sequentialized + destination Array element in order. + +
+If the srcToDstTransposeMap argument is provided it must be identical + across all PETs. The srcToDstTransposeMap allows source and destination + Array dimensions to be transposed during the redistribution. To support this + option, the number of source and destination Array dimensions must be equal + and the size of the associated dimensions must match. + See section 28.2.17 for more details about the + use of the srcToDstTransposeMap argument. + +
+It is erroneous to specify the identical Array object for srcArray and + dstArray arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArrayRedist() on any pair of Arrays that matches + srcArray and dstArray in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This call is collective across the current VM. + +
+
+
+
+
+
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArrayRedistStore() + subroutine ESMF_ArrayRedistStoreNFTP(srcArray, dstArray, routehandle, & + transposeRoutehandle, srcToDstTransposeMap, & + ignoreUnmatchedIndices, pipelineDepth, rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: srcArray + type(ESMF_Array), intent(inout) :: dstArray + type(ESMF_RouteHandle), intent(inout) :: routehandle + type(ESMF_RouteHandle), intent(inout) :: transposeRoutehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: srcToDstTransposeMap(:) + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: pipelineDepth + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ ESMF_ArrayRedistStore() is a collective method across all PETs of the + current Component. The interface of the method is overloaded, allowing + - in principle - each PET to call into ESMF_ArrayRedistStore() + through a different entry point. Restrictions apply as to which combinations + are sensible. All other combinations result in ESMF run time errors. The + complete semantics of the ESMF_ArrayRedistStore() method, as provided + through the separate entry points shown in 28.5.32 and + 28.5.34, is described in the following paragraphs as a whole. + +
+Store an Array redistribution operation from srcArray to dstArray. + Interface 28.5.32 allows PETs to specify a factor + argument. PETs not specifying a factor argument call into interface + 28.5.34. If multiple PETs specify the factor argument, + its type and kind, as well as its value must match across all PETs. If none + of the PETs specify a factor argument the default will be a factor of + 1. The resulting factor is applied to all of the source data during + redistribution, allowing scaling of the data, e.g. for unit transformation. + +
+Both srcArray and dstArray are interpreted as sequentialized + vectors. The sequence is defined by the order of DistGrid dimensions and the + order of tiles within the DistGrid or by user-supplied arbitrary sequence + indices. See section 28.2.18 for details on the definition + of sequence indices. + +
+Source Array, destination Array, and the factor may be of different + <type><kind>. Further, source and destination Arrays may differ in shape, + however, the number of elements must match. + +
+The default redistribution operation, when srcToDstTransposeMap is not + specified, corresponds to the identity mapping: each element of the + sequentialized source Array is copied to the sequentialized + destination Array element in order. + +
+If the srcToDstTransposeMap argument is provided it must be identical + across all PETs. The srcToDstTransposeMap allows source and destination + Array dimensions to be transposed during the redistribution. To support this + option, the number of source and destination Array dimensions must be equal + and the size of the associated dimensions must match. + See section 28.2.17 for more details about the + use of the srcToDstTransposeMap argument. + +
+It is erroneous to specify the identical Array object for srcArray and + dstArray arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArrayRedist() on any pair of Arrays that matches + srcArray and dstArray in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This call is collective across the current VM. + +
+
+
+
+
+
+
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayScatter(array, farray, rootPet, tile, vm, rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: array + <type> (ESMF_KIND_<kind>), intent(in), target :: farray(<rank>) + integer, intent(in) :: rootPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: tile + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Scatter the data of farray located on rootPET + across an ESMF_Array object. A single farray must be + scattered across a single DistGrid tile in Array. The optional tile + argument allows selection of the tile. For Arrays defined on a single + tile DistGrid the default selection (tile 1) will be correct. The + shape of farray must match the shape of the tile in Array. + +
+If the Array contains replicating DistGrid dimensions data will be + scattered across all of the replicated pieces. + +
+This version of the interface implements the PET-based blocking paradigm: + Each PET of the VM must issue this call exactly once for all of its + DEs. The call will block until all PET-local data objects are accessible. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArraySet() + subroutine ESMF_ArraySetDefault(array, computationalLWidth, & + computationalUWidth, name, rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: computationalLWidth(:,:) + integer, intent(in), optional :: computationalUWidth(:,:) + character(len = *), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets adjustable settings in an ESMF_Array object. Arrays with + tensor dimensions will set values for all tensor components. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArraySet() + subroutine ESMF_ArraySetPLocalDe(array, localDe, rimSeqIndex, rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: array + integer, intent(in) :: localDe + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: rimSeqIndex(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets adjustable settings in an ESMF_Array object for a specific + localDe. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArraySMM(srcArray, dstArray, routehandle, & + routesyncflag, finishedflag, cancelledflag, zeroregion, termorderflag, & + checkflag, dynamicMask, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in), optional :: srcArray + type(ESMF_Array), intent(inout), optional :: dstArray + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_RouteSync_Flag), intent(in), optional :: routesyncflag + logical, intent(out), optional :: finishedflag + logical, intent(out), optional :: cancelledflag + type(ESMF_Region_Flag), intent(in), optional :: zeroregion + type(ESMF_TermOrder_Flag), intent(in), optional :: termorderflag + logical, intent(in), optional :: checkflag + type(ESMF_DynamicMask), target, intent(in), optional :: dynamicMask + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Execute a precomputed Array sparse matrix multiplication from srcArray + to dstArray. + Both srcArray and dstArray must match the respective Arrays + used during ESMF_ArraySMMStore() in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. See section + 37.2.5 for a more detailed discussion of RouteHandle + reusability. + +
+The srcArray and dstArray arguments are optional in support of + the situation where srcArray and/or dstArray are not defined on + all PETs. The srcArray and dstArray must be specified on those + PETs that hold source or destination DEs, respectively, but may be omitted + on all other PETs. PETs that hold neither source nor destination DEs may + omit both arguments. + +
+It is erroneous to specify the identical Array object for srcArray and + dstArray arguments. + +
+See ESMF_ArraySMMStore() on how to precompute + routehandle. See section 28.2.18 for details on the + operation ESMF_ArraySMM() performs. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArraySMMRelease(routehandle, noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Release resources associated with an Array sparse matrix multiplication. + After this call routehandle becomes invalid. + +
+
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArraySMMStore() + subroutine ESMF_ArraySMMStore<type><kind>(srcArray, dstArray, & + routehandle, factorList, factorIndexList, & + ignoreUnmatchedIndices, srcTermProcessing, pipelineDepth, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: srcArray + type(ESMF_Array), intent(inout) :: dstArray + type(ESMF_RouteHandle), intent(inout) :: routehandle + <type>(ESMF_KIND_<kind>), target, intent(in) :: factorList(:) + integer(ESMF_KIND_<kind>), intent(in) :: factorIndexList(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipelineDepth + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+ ESMF_ArraySMMStore() is a collective method across all PETs of the + current Component. The interface of the method is overloaded, allowing + - in principle - each PET to call into ESMF_ArraySMMStore() + through a different entry point. Restrictions apply as to which combinations + are sensible. All other combinations result in ESMF run time errors. The + complete semantics of the ESMF_ArraySMMStore() method, as provided + through the separate entry points shown in 28.5.40 and + 28.5.42, is described in the following paragraphs as a whole. + +
+Store an Array sparse matrix multiplication operation from srcArray + to dstArray. PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+Both srcArray and dstArray are interpreted as sequentialized + vectors. The sequence is defined by the order of DistGrid dimensions and + the order of tiles within the DistGrid or by user-supplied arbitrary + sequence indices. See section 28.2.18 for details on the + definition of sequence indices. + +
+Source and destination Arrays, as well as the supplied factorList + argument, may be of different <type><kind>. Further source and + destination Arrays may differ in shape and number of elements. + +
+It is erroneous to specify the identical Array object for srcArray and + dstArray arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArraySMM() on any pair of Arrays that matches + srcArray and dstArray in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+This call is collective across the current VM. + +
+
+
+
+
+
+The second dimension of factorIndexList steps through the list of + pairs, i.e. size(factorIndexList,2) == size(factorList). The first + dimension of factorIndexList is either of size 2 or size 4. + +
+In the size 2 format factorIndexList(1,:) specifies the + sequence index of the source element in the srcArray while + factorIndexList(2,:) specifies the sequence index of the + destination element in dstArray. For this format to be a valid + option source and destination Arrays must have matching number of + tensor elements (the product of the sizes of all Array tensor dimensions). + Under this condition an identity matrix can be applied within the space of + tensor elements for each sparse matrix factor. + +
+The size 4 format is more general and does not require a matching + tensor element count. Here the factorIndexList(1,:) specifies the + sequence index while factorIndexList(2,:) specifies the tensor + sequence index of the source element in the srcArray. Further + factorIndexList(3,:) specifies the sequence index and + factorIndexList(4,:) specifies the tensor sequence index of the + destination element in the dstArray. + +
+See section 28.2.18 for details on the definition of + Array sequence indices and tensor sequence indices. + +
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArraySMMStore() + subroutine ESMF_ArraySMMStore<type><kind>TP(srcArray, dstArray, & + routehandle, transposeRoutehandle, factorList, factorIndexList, & + ignoreUnmatchedIndices, srcTermProcessing, pipelineDepth, & + rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: srcArray + type(ESMF_Array), intent(inout) :: dstArray + type(ESMF_RouteHandle), intent(inout) :: routehandle + type(ESMF_RouteHandle), intent(inout) :: transposeRoutehandle + <type>(ESMF_KIND_<kind>), target, intent(in) :: factorList(:) + integer(ESMF_KIND_<kind>), intent(in) :: factorIndexList(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipelineDepth + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ ESMF_ArraySMMStore() is a collective method across all PETs of the + current Component. The interface of the method is overloaded, allowing + - in principle - each PET to call into ESMF_ArraySMMStore() + through a different entry point. Restrictions apply as to which combinations + are sensible. All other combinations result in ESMF run time errors. The + complete semantics of the ESMF_ArraySMMStore() method, as provided + through the separate entry points shown in 28.5.41 and + 28.5.43, is described in the following paragraphs as a whole. + +
+Store an Array sparse matrix multiplication operation from srcArray + to dstArray. PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+Both srcArray and dstArray are interpreted as sequentialized + vectors. The sequence is defined by the order of DistGrid dimensions and + the order of tiles within the DistGrid or by user-supplied arbitrary + sequence indices. See section 28.2.18 for details on the + definition of sequence indices. + +
+Source and destination Arrays, as well as the supplied factorList + argument, may be of different <type><kind>. Further source and + destination Arrays may differ in shape and number of elements. + +
+It is erroneous to specify the identical Array object for srcArray and + dstArray arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArraySMM() on any pair of Arrays that matches + srcArray and dstArray in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This method is overloaded for:
+
+ ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8,
+
+ ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8.
+
+
+This call is collective across the current VM. + +
+
+
+
+
+
+
+The second dimension of factorIndexList steps through the list of + pairs, i.e. size(factorIndexList,2) == size(factorList). The first + dimension of factorIndexList is either of size 2 or size 4. + +
+In the size 2 format factorIndexList(1,:) specifies the + sequence index of the source element in the srcArray while + factorIndexList(2,:) specifies the sequence index of the + destination element in dstArray. For this format to be a valid + option source and destination Arrays must have matching number of + tensor elements (the product of the sizes of all Array tensor dimensions). + Under this condition an identity matrix can be applied within the space of + tensor elements for each sparse matrix factor. + +
+The size 4 format is more general and does not require a matching + tensor element count. Here the factorIndexList(1,:) specifies the + sequence index while factorIndexList(2,:) specifies the tensor + sequence index of the source element in the srcArray. Further + factorIndexList(3,:) specifies the sequence index and + factorIndexList(4,:) specifies the tensor sequence index of the + destination element in the dstArray. + +
+See section 28.2.18 for details on the definition of + Array sequence indices and tensor sequence indices. + +
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArraySMMStore() + subroutine ESMF_ArraySMMStoreNF(srcArray, dstArray, routehandle, & + ignoreUnmatchedIndices, srcTermProcessing, pipelineDepth, & + rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: srcArray + type(ESMF_Array), intent(inout) :: dstArray + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipelineDepth + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+ ESMF_ArraySMMStore() is a collective method across all PETs of the + current Component. The interface of the method is overloaded, allowing + - in principle - each PET to call into ESMF_ArraySMMStore() + through a different entry point. Restrictions apply as to which combinations + are sensible. All other combinations result in ESMF run time errors. The + complete semantics of the ESMF_ArraySMMStore() method, as provided + through the separate entry points shown in 28.5.40 and + 28.5.42, is described in the following paragraphs as a whole. + +
+Store an Array sparse matrix multiplication operation from srcArray + to dstArray. PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+Both srcArray and dstArray are interpreted as sequentialized + vectors. The sequence is defined by the order of DistGrid dimensions and + the order of tiles within the DistGrid or by user-supplied arbitrary + sequence indices. See section 28.2.18 for details on the + definition of sequence indices. + +
+Source and destination Arrays, as well as the supplied factorList + argument, may be of different <type><kind>. Further source and + destination Arrays may differ in shape and number of elements. + +
+It is erroneous to specify the identical Array object for srcArray and + dstArray arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArraySMM() on any pair of Arrays that matches + srcArray and dstArray in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This call is collective across the current VM. + +
+
+
+
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArraySMMStore() + subroutine ESMF_ArraySMMStoreNFTP(srcArray, dstArray, routehandle, & + transposeRoutehandle, ignoreUnmatchedIndices, & + srcTermProcessing, pipelineDepth, rc) +ARGUMENTS: +
type(ESMF_Array), intent(inout) :: srcArray + type(ESMF_Array), intent(inout) :: dstArray + type(ESMF_RouteHandle), intent(inout) :: routehandle + type(ESMF_RouteHandle), intent(inout) :: transposeRoutehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipelineDepth + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ ESMF_ArraySMMStore() is a collective method across all PETs of the + current Component. The interface of the method is overloaded, allowing + - in principle - each PET to call into ESMF_ArraySMMStore() + through a different entry point. Restrictions apply as to which combinations + are sensible. All other combinations result in ESMF run time errors. The + complete semantics of the ESMF_ArraySMMStore() method, as provided + through the separate entry points shown in 28.5.41 and + 28.5.43, is described in the following paragraphs as a whole. + +
+Store an Array sparse matrix multiplication operation from srcArray + to dstArray. PETs that specify non-zero matrix coefficients must use + the <type><kind> overloaded interface and provide the factorList and + factorIndexList arguments. Providing factorList and + factorIndexList arguments with size(factorList) = (/0/) and + size(factorIndexList) = (/2,0/) or (/4,0/) indicates that a + PET does not provide matrix elements. Alternatively, PETs that do not + provide matrix elements may also call into the overloaded interface + without factorList and factorIndexList arguments. + +
+Both srcArray and dstArray are interpreted as sequentialized + vectors. The sequence is defined by the order of DistGrid dimensions and + the order of tiles within the DistGrid or by user-supplied arbitrary + sequence indices. See section 28.2.18 for details on the + definition of sequence indices. + +
+Source and destination Arrays, as well as the supplied factorList + argument, may be of different <type><kind>. Further source and + destination Arrays may differ in shape and number of elements. + +
+It is erroneous to specify the identical Array object for srcArray and + dstArray arguments. + +
+The routine returns an ESMF_RouteHandle that can be used to call + ESMF_ArraySMM() on any pair of Arrays that matches + srcArray and dstArray in type, kind, and + memory layout of the distributed dimensions. However, the size, + number, and index order of undistributed dimensions may be different. + See section 37.2.5 for a more detailed discussion of + RouteHandle reusability. + +
+This call is collective across the current VM. + +
+
+
+
+
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArraySMMStore() + subroutine ESMF_ArraySMMStoreFromFile(srcArray, dstArray, filename, & + routehandle, ignoreUnmatchedIndices, & + srcTermProcessing, pipelineDepth, rc) + + ! ARGUMENTS: + type(ESMF_Array), intent(in) :: srcArray + type(ESMF_Array), intent(inout) :: dstArray + character(len=*), intent(in) :: filename + type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipeLineDepth + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Compute an ESMF_RouteHandle using factors read from file. + +
+The arguments are: + +
+
+
+
+
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ArraySMMStore() + subroutine ESMF_ArraySMMStoreFromFileTP(srcArray, dstArray, filename, & + routehandle, transposeRoutehandle, ignoreUnmatchedIndices,& + srcTermProcessing, pipelineDepth, rc) + + ! ARGUMENTS: + type(ESMF_Array), intent(inout) :: srcArray + type(ESMF_Array), intent(inout) :: dstArray + character(len=*), intent(in) :: filename + type(ESMF_RouteHandle), intent(inout) :: routehandle + type(ESMF_RouteHandle), intent(inout) :: transposeRoutehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: ignoreUnmatchedIndices + integer, intent(inout), optional :: srcTermProcessing + integer, intent(inout), optional :: pipeLineDepth + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Compute an ESMF_RouteHandle using factors read from file. + +
+The arguments are: + +
+
+
+
+
+
+
+
+Note that partial sums may lead to bit-for-bit differences in the results. + See section 37.2.1 for an in-depth discussion of all + bit-for-bit reproducibility aspects related to route-based communication + methods. + +
+The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the srcTermProcessing parameter. The intent on the + srcTermProcessing argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + srcTermProcessing parameter, and the auto-tuning phase is skipped. + In this case the srcTermProcessing argument is not modified on + return. If the provided argument is , the srcTermProcessing + parameter is determined internally using the auto-tuning scheme. In this + case the srcTermProcessing argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + srcTermProcessing argument is omitted. + +
+
+Note that the pipeline depth has no effect on the bit-for-bit + reproducibility of the results. However, it may affect the performance + reproducibility of the exchange. + The ESMF_ArraySMMStore() method implements an auto-tuning scheme + for the pipelineDepth parameter. The intent on the + pipelineDepth argument is "inout" in order to + support both overriding and accessing the auto-tuning parameter. + If an argument is specified, it is used for the + pipelineDepth parameter, and the auto-tuning phase is skipped. + In this case the pipelineDepth argument is not modified on + return. If the provided argument is , the pipelineDepth + parameter is determined internally using the auto-tuning scheme. In this + case the pipelineDepth argument is re-set to the internally + determined value on return. Auto-tuning is also used if the optional + pipelineDepth argument is omitted. + +
+
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArraySync(array, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Synchronizes access to DEs across array to make sure PETs correctly + access the data for read and write when DEs are shared. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayValidate(array, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Validates that the Array is internally consistent. + The method returns an error code if problems are found. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArrayWrite(array, fileName, & + variableName, convention, purpose, & + overwrite, status, timeslice, iofmt, rc) +ARGUMENTS: +
type(ESMF_Array), intent(in) :: array + character(*), intent(in) :: fileName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(*), intent(in), optional :: variableName + character(*), intent(in), optional :: convention + character(*), intent(in), optional :: purpose + logical, intent(in), optional :: overwrite + type(ESMF_FileStatus_Flag), intent(in), optional :: status + integer, intent(in), optional :: timeslice + type(ESMF_IOFmt_Flag), intent(in), optional :: iofmt + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write Array data into a file. For this API to be functional, the + environment variable ESMF_PIO should be set to either "internal" or "external" when + the ESMF library is built. Please see the section on + Data I/O, 38.2. + +
+When convention and purpose arguments are specified, + a NetCDF variable can be created with user-specified dimension labels and + attributes. Dimension labels may be defined for both gridded and + ungridded dimensions. Dimension labels for gridded dimensions are specified + at the DistGrid level by attaching an ESMF Attribute package to it. The Attribute + package must contain an attribute named by the pre-defined ESMF parameter + ESMF_ATT_GRIDDED_DIM_LABELS. The corresponding value is an array of + character strings specifying the desired names of the dimensions. Likewise, + for ungridded dimensions, an Attribute package is attached at the Array level. + The name of the name must be ESMF_ATT_UNGRIDDED_DIM_LABELS. + +
+NetCDF attributes for the variable can also be specified. As with dimension labels, + an Attribute package is added to the Array with the desired names and values. + A value may be either a scalar character string, or a scalar or array of type + integer, real, or double precision. Dimension label attributes can co-exist with + variable attributes within a common Attribute package. + +
+Limitations: + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_SparseMatrixWrite(factorList, factorIndexList, fileName, & + rc) +ARGUMENTS: +
real(ESMF_KIND_R8), intent(in) :: factorList(:) + integer(ESMF_KIND_I4), intent(in) :: factorIndexList(:,:) + character(*), intent(in) :: fileName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write the factorList and factorIndexList into a NetCDF file. + The data is stored in SCRIP format documented under section + (12.9). + +
+Limitations: + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DynamicMaskSetR8R8R8(dynamicMask, dynamicMaskRoutine, & + handleAllElements, dynamicSrcMaskValue, & + dynamicDstMaskValue, rc) +ARGUMENTS: +
type(ESMF_DynamicMask), intent(out) :: dynamicMask + procedure(ESMF_DynamicMaskRoutineR8R8R8) :: dynamicMaskRoutine + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: handleAllElements + real(ESMF_KIND_R8), intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R8), intent(in), optional :: dynamicDstMaskValue + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Set an ESMF_DynamicMask object suitable for + destination element typekind ESMF_TYPEKIND_R8, + factor typekind ESMF_TYPEKIND_R8, and + source element typekind ESMF_TYPEKIND_R8. + +
+All values in dynamicMask will be reset by this call. + +
+See section 37.2.6 for a general discussion of dynamic masking. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DynamicMaskSetR8R8R8V(dynamicMask, dynamicMaskRoutine, & + handleAllElements, dynamicSrcMaskValue, & + dynamicDstMaskValue, rc) +ARGUMENTS: +
type(ESMF_DynamicMask), intent(out) :: dynamicMask + procedure(ESMF_DynamicMaskRoutineR8R8R8V) :: dynamicMaskRoutine + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: handleAllElements + real(ESMF_KIND_R8), intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R8), intent(in), optional :: dynamicDstMaskValue + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Set an ESMF_DynamicMask object suitable for + destination element typekind ESMF_TYPEKIND_R8, + factor typekind ESMF_TYPEKIND_R8, and + source element typekind ESMF_TYPEKIND_R8. + +
+All values in dynamicMask will be reset by this call. + +
+See section 37.2.6 for a general discussion of dynamic masking. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DynamicMaskSetR4R8R4(dynamicMask, dynamicMaskRoutine, & + handleAllElements, dynamicSrcMaskValue, & + dynamicDstMaskValue, rc) +ARGUMENTS: +
type(ESMF_DynamicMask), intent(out) :: dynamicMask + procedure(ESMF_DynamicMaskRoutineR4R8R4) :: dynamicMaskRoutine + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: handleAllElements + real(ESMF_KIND_R4), intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R4), intent(in), optional :: dynamicDstMaskValue + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Set an ESMF_DynamicMask object suitable for + destination element typekind ESMF_TYPEKIND_R4, + factor typekind ESMF_TYPEKIND_R8, and + source element typekind ESMF_TYPEKIND_R4. + +
+All values in dynamicMask will be reset by this call. + +
+See section 37.2.6 for a general discussion of dynamic masking. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DynamicMaskSetR4R8R4V(dynamicMask, dynamicMaskRoutine, & + handleAllElements, dynamicSrcMaskValue, & + dynamicDstMaskValue, rc) +ARGUMENTS: +
type(ESMF_DynamicMask), intent(out) :: dynamicMask + procedure(ESMF_DynamicMaskRoutineR4R8R4V) :: dynamicMaskRoutine + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: handleAllElements + real(ESMF_KIND_R4), intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R4), intent(in), optional :: dynamicDstMaskValue + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Set an ESMF_DynamicMask object suitable for + destination element typekind ESMF_TYPEKIND_R4, + factor typekind ESMF_TYPEKIND_R8, and + source element typekind ESMF_TYPEKIND_R4. + +
+All values in dynamicMask will be reset by this call. + +
+See section 37.2.6 for a general discussion of dynamic masking. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DynamicMaskSetR4R4R4(dynamicMask, dynamicMaskRoutine, & + handleAllElements, dynamicSrcMaskValue, & + dynamicDstMaskValue, rc) +ARGUMENTS: +
type(ESMF_DynamicMask), intent(out) :: dynamicMask + procedure(ESMF_DynamicMaskRoutineR4R4R4) :: dynamicMaskRoutine + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: handleAllElements + real(ESMF_KIND_R4), intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R4), intent(in), optional :: dynamicDstMaskValue + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Set an ESMF_DynamicMask object suitable for + destination element typekind ESMF_TYPEKIND_R4, + factor typekind ESMF_TYPEKIND_R4, and + source element typekind ESMF_TYPEKIND_R4. + +
+All values in dynamicMask will be reset by this call. + +
+See section 37.2.6 for a general discussion of dynamic masking. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DynamicMaskSetR4R4R4V(dynamicMask, dynamicMaskRoutine, & + handleAllElements, dynamicSrcMaskValue, & + dynamicDstMaskValue, rc) +ARGUMENTS: +
type(ESMF_DynamicMask), intent(out) :: dynamicMask + procedure(ESMF_DynamicMaskRoutineR4R4R4V) :: dynamicMaskRoutine + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: handleAllElements + real(ESMF_KIND_R4), intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R4), intent(in), optional :: dynamicDstMaskValue + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Set an ESMF_DynamicMask object suitable for + destination element typekind ESMF_TYPEKIND_R4, + factor typekind ESMF_TYPEKIND_R4, and + source element typekind ESMF_TYPEKIND_R4. + +
+All values in dynamicMask will be reset by this call. + +
+See section 37.2.6 for a general discussion of dynamic masking. + +
+The arguments are: +
+ + +
+The ESMF_LocalArray class provides a language independent +representation of data in array format. One of the major functions +of the LocalArray class is to bridge the Fortran/C/C++ language +difference that exists with respect to array representation. All +ESMF Field and Array data is internally stored in ESMF LocalArray +objects allowing transparent access from Fortran and C/C++. + +
+In the ESMF Fortran API the LocalArray becomes visible in those cases +where a local PET may be associated with multiple pieces of an Array, +e.g. if there are multiple DEs associated with a single PET. The Fortran +language standard does not provide an array of arrays construct, however +arrays of derived types holding arrays are possible. ESMF calls use +arguments that are of type ESMF_LocalArray with dimension +attributes where necessary. + +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + localarray1 = localarray2 +ARGUMENTS: +
type(ESMF_LocalArray) :: localarray1 + type(ESMF_LocalArray) :: localarray2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign localarray1 as an alias to the same ESMF LocalArray object in memory + as localarray2. If localarray2 is invalid, then localarray1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (localarray1 == localarray2) then ... endif + OR + result = (localarray1 == localarray2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_LocalArray), intent(in) :: localarray1 + type(ESMF_LocalArray), intent(in) :: localarray2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether localarray1 and localarray2 are valid aliases to the same ESMF + LocalArray object in memory. For a more general comparison of two ESMF LocalArrays, + going beyond the simple alias test, the ESMF_LocalArrayMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (localarray1 /= localarray2) then ... endif + OR + result = (localarray1 /= localarray2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_LocalArray), intent(in) :: localarray1 + type(ESMF_LocalArray), intent(in) :: localarray2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether localarray1 and localarray2 are not valid aliases to the + same ESMF LocalArray object in memory. For a more general comparison of two ESMF + LocalArrays, going beyond the simple alias test, the ESMF_LocalArrayMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocalArrayCreate() + function ESMF_LocalArrayCreateByTKR(typekind, rank, totalCount, & + totalLBound, totalUBound, rc) +RETURN VALUE: +
type(ESMF_LocalArray) :: ESMF_LocalArrayCreateByTKR +ARGUMENTS: +
type(ESMF_TypeKind_Flag), intent(in) :: typekind + integer, intent(in) :: rank + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: totalCount(:) + integer, intent(in), optional :: totalLBound(:) + integer, intent(in), optional :: totalUBound(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create a new ESMF_LocalArray and allocate data space, which remains + uninitialized. The return value is a new LocalArray. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocalArrayCreate() + function ESMF_LocalArrayCreateBySpec(arrayspec, totalCount, & + totalLBound, totalUBound, rc) +RETURN VALUE: +
type(ESMF_LocalArray) :: ESMF_LocalArrayCreateBySpec +ARGUMENTS: +
type(ESMF_ArraySpec), intent(in) :: arrayspec + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: totalCount(:) + integer, intent(in), optional :: totalLBound(:) + integer, intent(in), optional :: totalUBound(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create a new ESMF_LocalArray and allocate data space, which remains + uninitialized. The return value is a new LocalArray. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocalArrayCreate() + function ESMF_LocalArrayCreateCopy(localarray, rc) +RETURN VALUE: +
type(ESMF_LocalArray) :: ESMF_LocalArrayCreateCopy +ARGUMENTS: +
type(ESMF_LocalArray), intent(in) :: localarray + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Perform a deep copy of an existing ESMF_LocalArray object. The return + value is a new LocalArray. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocalArrayCreate() + function ESMF_LocalArrCreateByPtr<rank><type><kind>(farrayPtr, & + datacopyflag, totalCount, totalLBound, totalUBound, rc) +RETURN VALUE: +
type(ESMF_LocalArray) :: ESMF_LocalArrCreateByPtr<rank><type><kind> +ARGUMENTS: +
<type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(in), optional :: totalCount(:) + integer, intent(in), optional :: totalLBound(:) + integer, intent(in), optional :: totalUBound(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Creates an ESMF_LocalArray based on a Fortran array pointer. + Two cases must be distinguished. + +
+First, if farrayPtr is associated + the optional datacopyflag argument may be used to indicate whether the + associated data is to be copied or referenced. For associated farrayPtr + the optional totalCount, totalLBound and totalUBound arguments need + not be specified. However, all present arguments will be checked against + farrayPtr for consistency. + +
+Second, if farrayPtr is unassociated the optional argument datacopyflag + must not be specified. However, in this case a complete set of totalCount and + bounds information must be provided. Any combination of present totalCount + totalLBound and totalUBound arguments that provides a complete + specification is valid. All input information will be checked for + consistency. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LocalArrayDestroy(localarray, rc) +ARGUMENTS: +
type(ESMF_LocalArray), intent(inout) :: localarray + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroys an ESMF_LocalArray, releasing all resources associated + with the object. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocalArrayGet() + subroutine ESMF_LocalArrayGetDefault(localarray, & + typekind, rank, totalCount, totalLBound, totalUBound, isESMFAllocated, rc) +ARGUMENTS: +
type(ESMF_LocalArray), intent(in) :: localarray + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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(:) + logical, intent(out), optional :: isESMFAllocated + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns information about the ESMF_LocalArray. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocalArrayGet() + subroutine ESMF_LocalArrayGetData<rank><type><kind>(localarray, farrayPtr, & + datacopyflag, rc) +ARGUMENTS: +
type(ESMF_LocalArray) :: localarray + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Return a Fortran pointer to the data buffer, or return a Fortran pointer + to a new copy of the data. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_LocalArrayIsCreated(localarray, rc) +RETURN VALUE: +
logical :: ESMF_LocalArrayIsCreated +ARGUMENTS: +
type(ESMF_LocalArray), intent(in) :: localarray + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the localarray has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ + +
+ +
+ +
+ + +
+An ArraySpec is a very simple class that contains type, kind, and +rank information about an Array. This information is stored in two +parameters. TypeKind describes the data type of the elements +in the Array and their precision. Rank is the number of dimensions +in the Array. + +
+The only methods that are associated with the ArraySpec class are those +that allow you to set and retrieve this information. + +
+ +
+The ArraySpec is passed in as an argument at Field and +FieldBundle creation in order to describe an Array that will +be allocated or attached at a later time. There are any +number of situations in which this approach is useful. +One common example is a case in which the user wants to create +a very flexible export State with many diagnostic variables +predefined, but only a subset desired and consequently +allocated for a particular run. + +
+ +
+ +
+ +
+
+! !PROGRAM: ESMF_ArraySpecEx - ArraySpec manipulation examples +! +! !DESCRIPTION: +! +! This program shows examples of ArraySpec set and get usage +!----------------------------------------------------------------------------- +#include "ESMF.h" + + ! ESMF Framework module + use ESMF + use ESMF_TestMod + implicit none + + ! local variables + type(ESMF_ArraySpec) :: arrayDS + integer :: myrank + type(ESMF_TypeKind_Flag) :: mytypekind + + + ! return code + integer:: rc, result + character(ESMF_MAXSTR) :: testname + character(ESMF_MAXSTR) :: failMsg ++ +
+
+ ! initialize ESMF framework + call ESMF_Initialize(defaultlogfilename="ArraySpecEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+ +
+ +
+This example shows how to set values in an ESMF_ArraySpec. +
+
+ call ESMF_ArraySpecSet(arrayDS, rank=2, & + typekind=ESMF_TYPEKIND_R8, rc=rc) ++ +
+ +
+ +
+This example shows how to query an ESMF_ArraySpec. +
+
+ call ESMF_ArraySpecGet(arrayDS, rank=myrank, & + typekind=mytypekind, rc=rc) + print *, "Returned values from ArraySpec:" + print *, "rank =", myrank ++ +
+
+ ! finalize ESMF framework + call ESMF_Finalize(rc=rc) ++ +
+
+ end program ESMF_ArraySpecEx ++ +
+ + +
+ +
+
+ +
+The information contained in an ESMF_ArraySpec is used to create +ESMF_Array objects. + +
+ESMF_ArraySpec is a shallow class, and only set and get methods +are needed. They do not need to be created or destroyed. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + arrayspec1 = arrayspec2 +ARGUMENTS: +
type(ESMF_ArraySpec) :: arrayspec1 + type(ESMF_ArraySpec) :: arrayspec2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Set arrayspec1 equal to arrayspec2. This is the default + Fortran assignment, which creates a complete, independent copy of + arrayspec2 as arrayspec1. If arrayspec2 is an + invalid ESMF_ArraySpec object then arrayspec1 will be + equally invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (arrayspec1 == arrayspec2) then ... endif + OR + result = (arrayspec1 == arrayspec2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_ArraySpec), intent(in) :: arrayspec1 + type(ESMF_ArraySpec), intent(in) :: arrayspec2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (==) operator for the ESMF_ArraySpec class to return + .true. if arrayspec1 and arrayspec2 specify the same + type, kind and rank, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (arrayspec1 /= arrayspec2) then ... endif + OR + result = (arrayspec1 /= arrayspec2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_ArraySpec), intent(in) :: arrayspec1 + type(ESMF_ArraySpec), intent(in) :: arrayspec2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (/=) operator for the ESMF_ArraySpec class to return + .true. if arrayspec1 and arrayspec2 do not specify the + same type, kind or rank, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArraySpecGet(arrayspec, rank, typekind, rc) +ARGUMENTS: +
type(ESMF_ArraySpec), intent(in) :: arrayspec + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rank + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns information about the contents of an ESMF_ArraySpec. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArraySpecPrint(arrayspec, rc) +ARGUMENTS: +
type(ESMF_ArraySpec), intent(in) :: arrayspec + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Print ArraySpec internals.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArraySpecSet(arrayspec, rank, typekind, rc) +ARGUMENTS: +
type(ESMF_ArraySpec), intent(out) :: arrayspec + integer, intent(in) :: rank + type(ESMF_TypeKind_Flag), intent(in) :: typekind + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Creates a description of the data - the typekind, the rank, + and the dimensionality. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ArraySpecValidate(arrayspec, rc) +ARGUMENTS: +
type(ESMF_ArraySpec), intent(in) :: arrayspec + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Validates that the arrayspec is internally consistent. + The method returns an error code if problems are found. + +
+The arguments are: +
+ + +
+The ESMF Grid class is used to describe the geometry and discretization +of logically rectangular physical grids. It also contains the +description of the grid's underlying topology and the decomposition +of the physical grid across the available computational resources. +The most frequent use of the Grid class is to describe physical grids +in user code so that sufficient information is available to perform ESMF +methods such as regridding. + +
+
+ +Key Features |
+
Representation of grids formed by logically rectangular regions, +including uniform and rectilinear grids (e.g. lat-lon grids), +curvilinear grids (e.g. displaced pole grids), and grids formed +by connected logically rectangular regions (e.g. cubed sphere grids). | +
Support for 1D, 2D, 3D, and higher dimension grids. | +
Distribution of grids across computational resources for parallel +operations - users set which grid dimensions are distributed. | +
Grids can be created already distributed, so that no single +resource needs global information during the creation process. | +
Options to define periodicity and other edge connectivities either +explicitly or implicitly via shape shortcuts. | +
Options for users to define grid coordinates themselves or to call +prefabricated coordinate generation routines for standard grids. | +
Options for incremental construction of grids. | +
Options for using a set of pre-defined stagger locations or for setting +custom stagger locations. | +
+ +
+ESMF Grids are based on the concepts described in A Standard +Description of Grids Used in Earth System Models [Balaji 2006]. In this document +Balaji introduces the mosaic concept as a means of describing +a wide variety of Earth system model grids. A mosaic is +composed of grid tiles connected at their edges. Mosaic grids +includes simple, single tile grids as a special case. + +
+The ESMF Grid class is a representation of a mosaic grid. Each ESMF +Grid is constructed of one or more logically rectangular Tiles. +A Tile will usually have some physical significance (e.g. the region +of the world covered by one face of a cubed sphere grid). + +
+The piece of a Tile that resides on one DE (for simple cases, a DE +can be thought of as a processor - see section on the DELayout) +is called a LocalTile. For example, the six faces of a cubed +sphere grid are each Tiles, and each Tile can be divided into many +LocalTiles. + +
+Every ESMF Grid contains a DistGrid object, which defines the Grid's +index space, topology, distribution, and connectivities. It enables +the user to define the complex edge relationships of tripole and other +grids. The DistGrid can be created explicitly and passed into a Grid +creation routine, or it can be created implicitly if the user takes +a Grid creation shortcut. The DistGrid used +in Grid creation describes the properties of the Grid cells. In addition +to this one, the Grid internally creates DistGrids for each stagger location. +These stagger DistGrids are related to the original DistGrid, but may +contain extra padding to represent the extent of the index space of +the stagger. These DistGrids are what are used when a Field is created +on a Grid. + +
+ +
+The range of supported grids in ESMF can be defined by: + +
+ +
+The first set of these are a group of overloaded +calls broken up by the number of periodic dimensions they specify. With these the user can pick +the method which creates a Grid with the number of periodic dimensions they need, and then specify other connectivity +options via arguments to the method. The following is a description of these methods: + +
+ +
+
+
+
+
+
+
+More detailed information can be found in the API description of each. + +
+ +
+
+
+
+The second set of shortcut methods is a set of methods overloaded under the name ESMF_GridCreate(). These methods +allow the user to specify the connectivites at the end of each dimension, by using the ESMF_GridConn_Flag flag. The table below shows the ESMF_GridConn_Flag settings used to create +standard shapes in 2D using the ESMF_GridCreate() call. Two values +are specified for each dimension, one for the low end and one for +the high end of the dimension's index values. + +
+ +
+
+
2D Shape | +connflagDim1(1) | +connflagDim1(2) | +connflagDim2(1) | +connflagDim2(2) | +
Rectangle | +NONE | +NONE | +NONE | +NONE | +
Bipole Sphere | +POLE | +POLE | +PERIODIC | +PERIODIC | +
Tripole Sphere | +POLE | +BIPOLE | +PERIODIC | +PERIODIC | +
Cylinder | +NONE | +NONE | +PERIODIC | +PERIODIC | +
Torus | +PERIODIC | +PERIODIC | +PERIODIC | +PERIODIC | +
+
+
+
+If the user's grid shape is too complex for an ESMF shortcut routine, +or involves more than three dimensions, a DistGrid can be created +to specify the shape in detail. This DistGrid is then passed +into a Grid create call. + +
+ +
+ESMF Grids have several options for data distribution (also referred to +as decomposition). As ESMF Grids are cell based, these +options are all specified in terms of how the cells in the Grid +are broken up between DEs. + +
+The main distribution options are regular, irregular, and arbitrary. +A regular distribution is one in which the same number of +contiguous grid cells are assigned to each DE in the +distributed dimension. An irregular distribution is one in which +unequal numbers of contiguous grid cells are assigned to each +DE in the distributed dimension. An arbitrary distribution is +one in which any grid cell can be assigned to any DE. Any of these +distribution options can be applied to any of the grid shapes (i.e., +rectangle) or types (i.e., rectilinear). Support for arbitrary distribution +is limited in the current version of ESMF, see Section 31.3.7 for +an example of creating a Grid with an arbitrary distribution. + +
+Figure 13 illustrates options for distribution. + +
+ |
+A distribution can also be specified using the DistGrid, by passing +object into a Grid create call. + +
+ +
+ +
+ |
+Each of these coordinate types can be set for each of the standard grid shapes +described in section 31.1.3. + +
+The table below shows how examples of common single Tile grids fall +into this shape and coordinate taxonomy. Note that any +of the grids in the table can have a regular or arbitrary distribution. + +
+ +
+
+
+ | Uniform | +Rectilinear | +Curvilinear | +
Sphere | +Global uniform lat-lon grid | +Gaussian grid | +Displaced pole grid | +
Rectangle | +Regional uniform lat-lon grid | +Gaussian grid section | +Polar stereographic grid section | +
+ +
+There are two ways of specifying coordinates in ESMF. The +first way is for the user to set the coordinates. The second +way is to take a shortcut and have the framework generate +the coordinates. + +
+See Section 31.3.13 for more description and examples of +setting coordinates. + +
+ +
+Staggering is a finite difference technique in which the values +of different physical quantities are placed at different locations +within a grid cell. + +
+The ESMF Grid class supports a variety of stagger locations, including +cell centers, corners, and edge centers. The default stagger location in +ESMF is the cell center, and cell counts in Grid are based on this assumption. +Combinations of the 2D ESMF stagger locations are sufficient to specify any of the +Arakawa staggers. ESMF also supports staggering in 3D and higher dimensions. +There are shortcuts for standard staggers, and interfaces through which users +can create custom staggers. + +
+As a default the ESMF Grid class provides symmetric staggering, so +that cell centers are enclosed by cell perimeter (e.g. corner) +stagger locations. This means the coordinate arrays for stagger +locations other than the center will have an additional element of +padding in order to enclose the cell center locations. +However, to achieve other types of staggering, the user may alter +or eliminate this padding by using the appropriate options when adding +coordinates to a Grid. + +
+In the current release, only the cell center stagger location is supported for an +arbitrarily distributed grid. For examples and a full description of the stagger interface +see Section 31.3.13. + +
+ +
+Masking is the process whereby parts of a Grid can be marked to be +ignored during an operation. For a description of how to set mask information in +the Grid, see here 31.3.17. For a description of how masking works +in regridding, see here 24.2.10. + +
+ +
+DESCRIPTION:
+
+
+The ESMF_GridCreateShapeTile command has three specific arguments
+connflagDim1, connflagDim2, and connflagDim3. These can be used
+to setup different types of connections at the ends of each dimension
+of a Tile. Each of these parameters is a two element array. The first
+element is the connection type at the minimum end of the dimension
+and the second is the connection type at the maximum end. The default
+value for all the connections is ESMF_GRIDCONN_NONE, specifying no
+connection.
+
+
+The type of this flag is: + +
+type(ESMF_GridConn_Flag) + +
+The valid values are: +
+
+
+
+ +
+DESCRIPTION:
+
+The ESMF Grid can contain other kinds of data besides coordinates.
+This data is referred to as Grid “items”. Some items may be used
+by ESMF for calculations involving the Grid. The following
+are the valid values of ESMF_GridItem_Flag.
+
+
+The type of this flag is: + +
+type(ESMF_GridItem_Flag) + +
+The valid values are:
+
+
Item Label | +Type Restriction | +Type Default | +ESMF Uses | +Controls | +
ESMF_GRIDITEM_MASK | +ESMF_TYPEKIND_I4 | +ESMF_TYPEKIND_I4 | +YES | +Masking in Regrid | +
ESMF_GRIDITEM_AREA | +NONE | +ESMF_TYPEKIND_R8 | +YES | +Conservation in Regrid | +
+ +
+
+
+
+NOTE: One important thing to consider when setting areas in the Grid using ESMF_GRIDITEM_AREA, + ESMF doesn't currently do unit conversion on areas. If these areas are going to be used + in a process that also involves the areas of another Grid or Mesh (e.g. conservative regridding), then + it is the user's responsibility to make sure that the area units are consistent between the two sides. + If ESMF calculates an area on the surface of a sphere, then it is in units of square radians. If + it calculates the area for a Cartesian grid, then it is in the same units as the coordinates, but squared. + +
+ +
+DESCRIPTION:
+
+ This type is used to indicate the level to which two grids match.
+
+
+The type of this flag is: + +
+type(ESMF_GridMatch_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+The ESMF Grid class can exist in two states. These states are
+present so that the library code can detect if a Grid has been
+appropriately setup for the task at hand. The following
+are the valid values of ESMF_GRIDSTATUS.
+
+
+The type of this flag is: + +
+type(ESMF_GridStatus_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+This type describes the type of connection that occurs at the pole when a Grid is
+created with ESMF_GridCreate1PeriodicDim().
+
+
+The type of this flag is: + +
+type(ESMF_PoleKind_Flag) + +
+The valid values are: +
+
+
+ +
+DESCRIPTION:
+
+ In the ESMF Grid class, data can be located at different positions in a
+ Grid cell. When setting or retrieving coordinate data the stagger location is
+ specified to tell the Grid method from where in the cell to get the data.
+ Although the user may define their own custom stagger locations,
+ ESMF provides a set of predefined locations for ease of use. The
+following are the valid predefined stagger locations.
+
+
+ +
+
+
+
+
+The 2D predefined stagger locations (illustrated in figure 15) are:
+
+ +
+
+
+
+
+The 3D predefined stagger locations (illustrated in figure 16) are:
+
+This section describes the use of the ESMF Grid class. It first discusses +the more user friendly shape specific interface to the Grid. +During this discussion it covers creation and options, +adding stagger locations, coordinate data access, and other grid +functionality. After this initial phase the document discusses +the more advanced options which the user can employ should they +need more customized interaction with the Grid class. + +
+ +
+ +
+ +
+ +
+The set of methods ESMF_GridCreateNoPeriDim(), ESMF_GridCreate1PeriDim(), + ESMF_GridCreate2PeriDim(), and ESMF_GridCreate() are shortcuts + for building 2D or 3D single tile logically rectangular Grids. + These methods support all three types of distributions described in + Section 31.1.4: regular, irregular and arbitrary. + +
+The ESMF Grid is cell based and so for all distribution + options the methods take as input the number of cells to describe + the total index space and the number of cells to specify distribution. + +
+To create a Grid + with a regular distribution the user specifies the global + maximum and minimum ranges of the Grid cell index space (maxIndex and + minIndex), and the number of pieces in which to partition + each dimension (via a regDecomp argument). + ESMF then divides the index space as evenly as possible + into the specified number of pieces. If there are cells + left over then they are distributed one per DE starting from + the first DE until they are gone. + +
+If minIndex is + not specified, then the bottom of the Grid cell index range is assumed + to be (1,1,...,1). If regDecomp is not specified, then + by default ESMF creates a distribution that partitions the + grid cells in the first dimension (e.g. NPx1x1...1) as evenly + as possible by the number of PETs NP. + The remaining dimensions are not partitioned. + The dimension of the Grid is the size of maxIndex. + The following is an example of creating a 10x20x30 3D grid + where the first dimensions is broken into 2 pieces, the second + is broken into 4 pieces, and the third is not divided (i.e. every DE will + have length 30 in the 3rd dimension). +
+
+ grid3D=ESMF_GridCreateNoPeriDim(regDecomp=(/2,4,1/), maxIndex=(/10,20,30/), & + rc=rc) ++ +
+Irregular distribution requires the user to specify the + exact number of Grid cells per DE in each dimension. In the + ESMF_GridCreateNoPeriDim() call the countsPerDEDim1, + countsPerDim2, and countsPerDim3 + arguments are used to specify a rectangular distribution + containing size(countsPerDEDim1) by size(countsPerDEDim2) by + size(countsPerDEDim3) DEs. The entries in each of these arrays + specify the number of grid cells per DE in that dimension. + The dimension of the grid is determined by the presence of + countsPerDEDim3. If it's present the Grid + will be 3D. If just countsPerDEDim1 and + countsPerDEDim2 are specified the Grid + will be 2D. + +
+The following call illustrates the creation of + a 10x20 two dimensional rectangular Grid distributed across six DEs + that are arranged 2x3. In the first dimension there are 3 grid + cells on the first DE and 7 cells on the second DE. The second + dimension has 3 DEs with 11,2, and 7 cells, respectively. +
+
+ grid2D=ESMF_GridCreateNoPeriDim(countsPerDEDim1=(/3,7/), & + countsPerDEDim2=(/11,2,7/), rc=rc) ++ +
+To add a distributed third dimension of size 30, broken up into + two groups of 15, the above call would be altered as follows. +
+
+ grid3d=ESMF_GridCreateNoPeriDim(countsPerDEDim1=(/3,7/), & + countsPerDEDim2=(/11,2,7/), countsPerDEDim3=(/15,15/), rc=rc) ++ +
+To make a third dimension distributed across only 1 DE, then + countsPerDEDim3 in the call should only have a single term. +
+
+ grid3D=ESMF_GridCreateNoPeriDim(countsPerDEDim1=(/3,7/), & + countsPerDEDim2=(/11,2,7/), countsPerDEDim3=(/30/), rc=rc) ++ +
+The petMap parameter may be used to specify on to which specific PETs + the DEs in the Grid are assigned. Each entry in petMap specifies to which PET the corresponding + DE should be assigned. For example, petMap(3,2)=4 tells the Grid + create call to put the DE located at column 3 row 2 on PET 4. + Note that this parameter is only available for the + regular and irregular distribution types. The petMap + array is a 3D array, for a 3D Grid each of its dimensions correspond to a + Grid dimension. If the Grid is 2D, then the first two dimensions correspond + to Grid dimensions and the last dimension should be of size 1. + The size of each petMap dimension is + the number of DE's along that dimension in the Grid. For a + regular Grid, the size is equal to the number in regDecomp + (i.e. size(petMap,d)=regDecomp(d) for all dimensions d in the Grid). For + an irregular Grid the size is equal to the number of items in + the corresponding countsPerDEDim variable (i.e. + size(petMap,d)=size(countsPerDEDimd) for all dimensions d in the Grid). + The following example demonstrates how to specify the PET to DE association + for an ESMF_GridCreateNoPeriDim() call. + + +
+
+ ! allocate memory for petMap + allocate( petMap(2,2,1) ) + + ! Set petMap + petMap(:,1,1) = (/3,2/) ! DE (1,1,1) on PET 3 and DE (2,1,1) on PET 2 + petMap(:,2,1) = (/1,0/) ! DE (1,2,1) on PET 1 and DE (2,2,1) on PET 0 + + + ! Let the 3D grid be be distributed only in the first two dimensions. + grid2D=ESMF_GridCreateNoPeriDim(countsPerDEDim1=(/3,7/), & + countsPerDEDim2=(/7,6/), petMap=petMap, rc=rc) ++ +
+To create an grid with arbitrary distribution, the user specifies the global minimum and maximum + ranges of the index space with the + arguments minIndex and maxIndex, the total number of cells and their index space locations + residing on the local PET through a localArbIndexCount and a localArbIndex + argument. localArbIndex is a 2D array with size (localArbIndexCount, n) where n is the total number + dimensions distributed arbitrarily. + Again, if minIndex is not specified, then the bottom of the + index range is assumed to be (1,1,...). + The dimension of the Grid is equal to the size of maxIndex. + If n (number of arbitrarily distributed dimension) is less than the grid dimension, an optional + argument distDim is used to specify which of the grid dimension is arbitrarily distributed. + If not given, the first n dimensions are assumed to be distributed. + +
+The following example creates a 2D Grid of dimensions 5x5, and places + the diagonal elements (i.e. indices (i,i) where i goes from 1 to 5) + on the local PET. The remaining PETs would individually declare + the remainder of the Grid locations. +
+
+ ! allocate memory for localArbIndex + allocate( localArbIndex(5,2) ) + ! Set local indices + localArbIndex(1,:)=(/1,1/) + localArbIndex(2,:)=(/2,2/) + localArbIndex(3,:)=(/3,3/) + localArbIndex(4,:)=(/4,4/) + localArbIndex(5,:)=(/5,5/) + + ! Create a 2D Arbitrarily distributed Grid + grid2D=ESMF_GridCreateNoPeriDim(maxIndex=(/5,5/), & + arbIndexList=localArbIndex, arbIndexCount=5, rc=rc) ++ +
+To create a 3D Grid of dimensions 5x6x5 with the first and the third dimensions distributed arbitrarily, + distDim is used. +
+
+ ! Create a 3D Grid with the 1st and 3rd dimension arbitrarily distributed + grid3D=ESMF_GridCreateNoPeriDim(maxIndex=(/5,6,5/), & + arbIndexList=localArbIndex, arbIndexCount=5, & + distDim=(/1,3/), rc=rc) ++ +
+ +
+The following is an example of creating a simple rectilinear grid + and loading in a set of coordinates. It illustrates a straightforward use + of the ESMF_GridCreateNoPeriDim() call described in the previous section. + This code creates a 10x20 2D grid with uniformly spaced coordinates varying from (10,10) to (100,200). + The grid is partitioned using a regular distribution. The first dimension + is divided into two pieces, and the second dimension is divided into 3. + This example assumes that the code is being run with a 1-1 mapping between + PETs and DEs because we are only accessing the first DE on each PET (localDE=0). + Because we have 6 DEs (2x3), this example would only work when run on 6 PETs. + The Grid is created with global indices. After Grid creation the + local bounds and native Fortran arrays are retrieved and the + coordinates are set by the user. + +
+
+ !------------------------------------------------------------------- + ! Create the Grid: Allocate space for the Grid object, define the + ! topology and distribution of the Grid, and specify that it + ! will have global indices. Note that here aperiodic bounds are + ! specified by the argument name. In this call the minIndex hasn't + ! been set, so it defaults to (1,1,...). The default is to + ! divide the index range as equally as possible among the DEs + ! specified in regDecomp. This behavior can be changed by + ! specifying decompFlag. + !------------------------------------------------------------------- + grid2D=ESMF_GridCreateNoPeriDim( & + ! Define a regular distribution + maxIndex=(/10,20/), & ! define index space + regDecomp=(/2,3/), & ! define how to divide among DEs + coordSys=ESMF_COORDSYS_CART, & + ! Specify mapping of coords dim to Grid dim + coordDep1=(/1/), & ! 1st coord is 1D and depends on 1st Grid dim + coordDep2=(/2/), & ! 2nd coord is 1D and depends on 2nd Grid dim + indexflag=ESMF_INDEX_GLOBAL, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Allocate coordinate storage and associate it with the center + ! stagger location. Since no coordinate values are specified in + ! this call no coordinate values are set yet. + !------------------------------------------------------------------- + call ESMF_GridAddCoord(grid2D, & + staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Get the pointer to the first coordinate array and the bounds + ! of its global indices on the local DE. + !------------------------------------------------------------------- + call ESMF_GridGetCoord(grid2D, coordDim=1, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + computationalLBound=lbnd, computationalUBound=ubnd, & + farrayPtr=coordX, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Calculate and set coordinates in the first dimension [10-100]. + !------------------------------------------------------------------- + do i=lbnd(1),ubnd(1) + coordX(i) = i*10.0 + enddo + + !------------------------------------------------------------------- + ! Get the pointer to the second coordinate array and the bounds of + ! its global indices on the local DE. + !------------------------------------------------------------------- + call ESMF_GridGetCoord(grid2D, coordDim=2, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + computationalLBound=lbnd, computationalUBound=ubnd, & + farrayPtr=coordY, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Calculate and set coordinates in the second dimension [10-200] + !------------------------------------------------------------------- + do j=lbnd(1),ubnd(1) + coordY(j) = j*10.0 + enddo ++ +
+ +
+The following is an example of creating a simple rectilinear grid + with a periodic dimension and loading in a set of coordinates. It illustrates a straightforward use + of the ESMF_GridCreate1PeriDim() call described in the previous section. + This code creates a 360x180 2D grid with uniformly spaced coordinates varying from (1,1) to (360,180). + The grid is partitioned using a regular distribution. The first dimension + is divided into two pieces, and the second dimension is divided into 3. + This example assumes that the code is being run with a 1-1 mapping between + PETs and DEs because we are only accessing the first DE on each PET (localDE=0). + Because we have 6 DEs (2x3), this example would only work when run on 6 PETs. + The Grid is created with global indices. After Grid creation the + local bounds and native Fortran arrays are retrieved and the + coordinates are set by the user. + +
+
+ !------------------------------------------------------------------- + ! Create the Grid: Allocate space for the Grid object, define the + ! topology and distribution of the Grid, and specify that it + ! will have global indices. Note that here a single periodic connection + ! is specified by the argument name. In this call the minIndex hasn't + ! been set, so it defaults to (1,1,...). The default is to + ! divide the index range as equally as possible among the DEs + ! specified in regDecomp. This behavior can be changed by + ! specifying decompFlag. Since the coordinate system is + ! not specified, it defaults to ESMF_COORDSYS_SPH_DEG. + !------------------------------------------------------------------- + grid2D=ESMF_GridCreate1PeriDim( & + ! Define a regular distribution + maxIndex=(/360,180/), & ! define index space + regDecomp=(/2,3/), & ! define how to divide among DEs + ! Specify mapping of coords dim to Grid dim + coordDep1=(/1/), & ! 1st coord is 1D and depends on 1st Grid dim + coordDep2=(/2/), & ! 2nd coord is 1D and depends on 2nd Grid dim + indexflag=ESMF_INDEX_GLOBAL, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Allocate coordinate storage and associate it with the center + ! stagger location. Since no coordinate values are specified in + ! this call no coordinate values are set yet. + !------------------------------------------------------------------- + call ESMF_GridAddCoord(grid2D, & + staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Get the pointer to the first coordinate array and the bounds + ! of its global indices on the local DE. + !------------------------------------------------------------------- + call ESMF_GridGetCoord(grid2D, coordDim=1, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + computationalLBound=lbnd, computationalUBound=ubnd, & + farrayPtr=coordX, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Calculate and set coordinates in the first dimension [10-100]. + !------------------------------------------------------------------- + do i=lbnd(1),ubnd(1) + coordX(i) = i*1.0 + enddo + + !------------------------------------------------------------------- + ! Get the pointer to the second coordinate array and the bounds of + ! its global indices on the local DE. + !------------------------------------------------------------------- + call ESMF_GridGetCoord(grid2D, coordDim=2, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + computationalLBound=lbnd, computationalUBound=ubnd, & + farrayPtr=coordY, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Calculate and set coordinates in the second dimension [10-200] + !------------------------------------------------------------------- + do j=lbnd(1),ubnd(1) + coordY(j) = j*1.0 + enddo ++ +
+The remaining examples in this section will use the irregular + distribution because of its greater generality. To create code similar to these, but + using a regular distribution, replace the countsPerDEDim arguments + in the Grid create with the appropriate maxIndex and regDecomp arguments. + +
+ +
+This example serves as an illustration of the difference between using + a regular and irregular distribution. It repeats the previous example + except using an irregular distribution to give the user more control + over how the cells are divided between the DEs. As before, this code + creates a 10x20 2D Grid with uniformly spaced coordinates varying from (10,10) to (100,200). + In this example, the Grid is partitioned using an irregular distribution. The first dimension + is divided into two pieces, the first with 3 Grid cells per + DE and the second with 7 Grid cells per DE. In the second dimension, + the Grid is divided into 3 pieces, with 11, 2, and 7 cells per DE respectively. + This example assumes that the code is being run with a 1-1 mapping between + PETs and DEs because we are only accessing the first DE on each PET (localDE=0). + Because we have 6 DEs (2x3), this example would only work when run on 6 PETs. + The Grid is created with global indices. After Grid creation the + local bounds and native Fortran arrays are retrieved and the + coordinates are set by the user. + +
+
+ !------------------------------------------------------------------- + ! Create the Grid: Allocate space for the Grid object, define the + ! topology and distribution of the Grid, and specify that it + ! will have global coordinates. Note that aperiodic bounds are + ! indicated by the method name. In this call the minIndex hasn't + ! been set, so it defaults to (1,1,...). + !------------------------------------------------------------------- + grid2D=ESMF_GridCreateNoPeriDim( & + ! Define an irregular distribution + countsPerDEDim1=(/3,7/), & + countsPerDEDim2=(/11,2,7/), & + ! Specify mapping of coords dim to Grid dim + coordDep1=(/1/), & ! 1st coord is 1D and depends on 1st Grid dim + coordDep2=(/2/), & ! 2nd coord is 1D and depends on 2nd Grid dim + indexflag=ESMF_INDEX_GLOBAL, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Allocate coordinate storage and associate it with the center + ! stagger location. Since no coordinate values are specified in + ! this call no coordinate values are set yet. + !------------------------------------------------------------------- + call ESMF_GridAddCoord(grid2D, & + staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Get the pointer to the first coordinate array and the bounds + ! of its global indices on the local DE. + !------------------------------------------------------------------- + call ESMF_GridGetCoord(grid2D, coordDim=1, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + computationalLBound=lbnd, computationalUBound=ubnd, & + farrayPtr=coordX, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Calculate and set coordinates in the first dimension [10-100]. + !------------------------------------------------------------------- + do i=lbnd(1),ubnd(1) + coordX(i) = i*10.0 + enddo + + !------------------------------------------------------------------- + ! Get the pointer to the second coordinate array and the bounds of + ! its global indices on the local DE. + !------------------------------------------------------------------- + call ESMF_GridGetCoord(grid2D, coordDim=2, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + computationalLBound=lbnd, computationalUBound=ubnd, & + farrayPtr=coordY, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Calculate and set coordinates in the second dimension [10-200] + !------------------------------------------------------------------- + do j=lbnd(1),ubnd(1) + coordY(j) = j*10.0 + enddo ++ +
+ +
+The following is an example of creating a simple curvilinear Grid and + loading in a set of coordinates. It creates a 10x20 + 2D Grid where the coordinates vary along every dimension. + The Grid is partitioned using an irregular distribution. The first dimension + is divided into two pieces, the first with 3 Grid cells per + DE and the second with 7 Grid cells per DE. In the second dimension, + the Grid is divided into 3 pieces, with 11, 2, and 7 cells per DE respectively. + This example assumes that the code is being run with a 1-1 mapping between + PETs and DEs because we are only accessing the first DE on each PET (localDE=0). + Because we have 6 DEs (2x3), this example would only work when run on 6 PETs. + The Grid is created with global indices. After Grid creation the + local bounds and native Fortran arrays are retrieved and the + coordinates are set by the user. + +
+
+ !------------------------------------------------------------------- + ! Create the Grid: Allocate space for the Grid object, define the + ! distribution of the Grid, and specify that it + ! will have global indices. Note that aperiodic bounds are + ! indicated by the method name. If periodic bounds were desired they + ! could be specified by using the ESMF_GridCreate1PeriDim() call. + ! In this call the minIndex hasn't been set, so it defaults to (1,1,...). + !------------------------------------------------------------------- + grid2D=ESMF_GridCreateNoPeriDim( & + ! Define an irregular distribution + countsPerDEDim1=(/3,7/), & + countsPerDEDim2=(/11,2,7/), & + ! Specify mapping of coords dim to Grid dim + coordDep1=(/1,2/), & ! 1st coord is 2D and depends on both Grid dim + coordDep2=(/1,2/), & ! 2nd coord is 2D and depends on both Grid dim + indexflag=ESMF_INDEX_GLOBAL, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Allocate coordinate storage and associate it with the center + ! stagger location. Since no coordinate values are specified in + ! this call no coordinate values are set yet. + !------------------------------------------------------------------- + call ESMF_GridAddCoord(grid2D, & + staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Get the pointer to the first coordinate array and the bounds + ! of its global indices on the local DE. + !------------------------------------------------------------------- + call ESMF_GridGetCoord(grid2D, coordDim=1, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + computationalLBound=lbnd, computationalUBound=ubnd, & + farrayPtr=coordX2D, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Calculate and set coordinates in the first dimension [10-100]. + !------------------------------------------------------------------- + do j=lbnd(2),ubnd(2) + do i=lbnd(1),ubnd(1) + coordX2D(i,j) = i+j + enddo + enddo + + !------------------------------------------------------------------- + ! Get the pointer to the second coordinate array and the bounds of + ! its global indices on the local DE. + !------------------------------------------------------------------- + call ESMF_GridGetCoord(grid2D, coordDim=2, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + computationalLBound=lbnd, computationalUBound=ubnd, & + farrayPtr=coordY2D, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Calculate and set coordinates in the second dimension [10-200] + !------------------------------------------------------------------- + do j=lbnd(2),ubnd(2) + do i=lbnd(1),ubnd(1) + coordY2D(i,j) = j-i/100.0 + enddo + enddo ++ +
+ +
+This example demonstrates how a user can build a rectilinear + horizontal Grid with a non-distributed vertical dimension. The Grid + contains both the center and corner stagger locations (i.e. Arakawa + B-Grid). In contrast to the previous examples, this example doesn't + assume that the code is being run with a 1-1 mapping between + PETs and DEs. It should work when run on any number of PETs. + +
+
+ !------------------------------------------------------------------- + ! Create the Grid: Allocate space for the Grid object. The + ! Grid is defined to be 180 Grid cells in the first dimension + ! (e.g. longitude), 90 Grid cells in the second dimension + ! (e.g. latitude), and 40 Grid cells in the third dimension + ! (e.g. height). The first dimension is decomposed over 4 DEs, + ! the second over 3 DEs, and the third is not distributed. + ! The connectivities in each dimension are set to aperiodic + ! by this method. In this call the minIndex hasn't been set, + ! so it defaults to (1,1,...). + !------------------------------------------------------------------- + grid3D=ESMF_GridCreateNoPeriDim( & + ! Define an irregular distribution + countsPerDEDim1=(/45,75,40,20/), & + countsPerDEDim2=(/30,40,20/), & + countsPerDEDim3=(/40/), & + ! Specify mapping of coords dim to Grid dim + coordDep1=(/1/), & ! 1st coord is 1D and depends on 1st Grid dim + coordDep2=(/2/), & ! 2nd coord is 1D and depends on 2nd Grid dim + coordDep3=(/3/), & ! 3rd coord is 1D and depends on 3rd Grid dim + indexflag=ESMF_INDEX_GLOBAL, & ! Use global indices + rc=rc) ++ +
+
+ + + !------------------------------------------------------------------- + ! Allocate coordinate storage for both center and corner stagger + ! locations. Since no coordinate values are specified in this + ! call no coordinate values are set yet. + !------------------------------------------------------------------- + call ESMF_GridAddCoord(grid3D, & + staggerloc=ESMF_STAGGERLOC_CENTER_VCENTER, rc=rc) ++ +
+
+ call ESMF_GridAddCoord(grid3D, & + staggerloc=ESMF_STAGGERLOC_CORNER_VCENTER, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Get the number of DEs on this PET, so that the program + ! can loop over them when accessing data. + !------------------------------------------------------------------- + call ESMF_GridGet(grid3D, localDECount=localDECount, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Loop over each localDE when accessing data + !------------------------------------------------------------------- + do lDE=0,localDECount-1 + + !------------------------------------------------------------------ + ! Fill in the coordinates for the corner stagger location first. + !------------------------------------------------------------------ + !---------------------------------------------------------------- + ! Get the local bounds of the global indexing for the first + ! coordinate array on the local DE. If the number of PETs + ! is less than the total number of DEs then the rest of this + ! example would be in a loop over the local DEs. Also get the + ! pointer to the first coordinate array. + !---------------------------------------------------------------- + call ESMF_GridGetCoord(grid3D, coordDim=1, localDE=lDE, & + staggerLoc=ESMF_STAGGERLOC_CORNER_VCENTER, & + computationalLBound=lbnd_corner, & + computationalUBound=ubnd_corner, & + farrayPtr=cornerX, rc=rc) ++ +
+
+ !---------------------------------------------------------------- + ! Calculate and set coordinates in the first dimension. + !---------------------------------------------------------------- + do i=lbnd_corner(1),ubnd_corner(1) + cornerX(i) = (i-1)*(360.0/180.0) + enddo + + !---------------------------------------------------------------- + ! Get the local bounds of the global indexing for the second + ! coordinate array on the local DE. Also get the pointer to the + ! second coordinate array. + !---------------------------------------------------------------- + call ESMF_GridGetCoord(grid3D, coordDim=2, localDE=lDE, & + staggerLoc=ESMF_STAGGERLOC_CORNER_VCENTER, & + computationalLBound=lbnd_corner, & + computationalUBound=ubnd_corner, & + farrayPtr=cornerY, rc=rc) ++ +
+
+ !---------------------------------------------------------------- + ! Calculate and set coordinates in the second dimension. + !---------------------------------------------------------------- + do j=lbnd_corner(1),ubnd_corner(1) + cornerY(j) = (j-1)*(180.0/90.0) + enddo + + !---------------------------------------------------------------- + ! Get the local bounds of the global indexing for the third + ! coordinate array on the local DE, and the pointer to the array. + !---------------------------------------------------------------- + call ESMF_GridGetCoord(grid3D, coordDim=3, localDE=lDE, & + staggerloc=ESMF_STAGGERLOC_CENTER_VCENTER, & + computationalLBound=lbnd, computationalUBound=ubnd,& + farrayPtr=cornerZ, rc=rc) ++ +
+
+ !---------------------------------------------------------------- + ! Calculate and set the vertical coordinates + !---------------------------------------------------------------- + do k=lbnd(1),ubnd(1) + cornerZ(k) = 4000.0*( (1./39.)*(k-1) )**2 + enddo + + !------------------------------------------------------------------ + ! Now fill the coordinates for the center stagger location with + ! the average of the corner coordinate location values. + !------------------------------------------------------------------ + !---------------------------------------------------------------- + ! Get the local bounds of the global indexing for the first + ! coordinate array on the local DE, and the pointer to the array. + !---------------------------------------------------------------- + call ESMF_GridGetCoord(grid3D, coordDim=1, localDE=lDE, & + staggerloc=ESMF_STAGGERLOC_CENTER_VCENTER, & + computationalLBound=lbnd, computationalUBound=ubnd, & + farrayPtr=centerX, rc=rc) ++ +
+
+ !---------------------------------------------------------------- + ! Calculate and set coordinates in the first dimension. + !---------------------------------------------------------------- + do i=lbnd(1),ubnd(1) + centerX(i) = 0.5*(i-1 + i)*(360.0/180.0) + enddo + + !---------------------------------------------------------------- + ! Get the local bounds of the global indexing for the second + ! coordinate array on the local DE, and the pointer to the array. + !---------------------------------------------------------------- + call ESMF_GridGetCoord(grid3D, coordDim=2, localDE=lDE, & + staggerloc=ESMF_STAGGERLOC_CENTER_VCENTER, & + computationalLBound=lbnd, computationalUBound=ubnd, & + farrayPtr=centerY, rc=rc) ++ +
+
+ !---------------------------------------------------------------- + ! Calculate and set coordinates in the second dimension. + !---------------------------------------------------------------- + do j=lbnd(1),ubnd(1) + centerY(j) = 0.5*(j-1 + j)*(180.0/90.0) + enddo + + !---------------------------------------------------------------- + ! Get the local bounds of the global indexing for the third + ! coordinate array on the local DE, and the pointer to the array. + !---------------------------------------------------------------- + call ESMF_GridGetCoord(grid3D, coordDim=3, localDE=lDE, & + staggerloc=ESMF_STAGGERLOC_CENTER_VCENTER, & + computationalLBound=lbnd, computationalUBound=ubnd,& + farrayPtr=centerZ, rc=rc) ++ +
+
+ !---------------------------------------------------------------- + ! Calculate and set the vertical coordinates + !---------------------------------------------------------------- + do k=lbnd(1),ubnd(1) + centerZ(k) = 4000.0*( (1./39.)*(k-1) )**2 + enddo + + !------------------------------------------------------------------- + ! End of loop over DEs + !------------------------------------------------------------------- + enddo ++ +
+ +
+There are more restrictions in defining an arbitrarily distributed grid. + First, there is always one DE per PET. Secondly, only local index (ESMF_INDEX_LOCAL) + is supported. Third, only one stagger location, i.e. ESMF_STAGGERLOC_CENTER is allowed + and last there is no extra paddings on the edge of the grid. + +
+This example demonstrates how a user can build a 3D grid with its rectilinear + horizontal Grid distributed arbitrarily and a non-distributed vertical dimension. + +
+
+ !------------------------------------------------------------------- + ! Set up the local index array: Assuming the grid is 360x180x10. First + ! calculate the localArbIndexCount and localArbIndex array for each PET + ! based on the total number of PETs. The cells are evenly distributed in + ! all the PETs. If the total number of cells are not divisible by the + ! total PETs, the remaining cells are assigned to the last PET. The + ! cells are card dealt to each PET in y dimension first, + ! i.e. (1,1) -> PET 0, (1,2)-> PET 1, (1,3)-> PET 2, and so forth. + !------------------------------------------------------------------- + xdim = 360 + ydim = 180 + zdim = 10 + localArbIndexCount = (xdim*ydim)/petCount + remain = (xdim*ydim)-localArbIndexCount*petCount + if (localPet == petCount-1) localArbIndexCount = localArbIndexCount+remain + + allocate(localArbIndex(localArbIndexCount,2)) + ind = localPet + do i=1, localArbIndexCount + localArbIndex(i,1)=mod(ind,ydim)+1 + localArbIndex(i,2)=ind/ydim + 1 + ind = ind + petCount + enddo + if (localPet == petCount-1) then + ind = xdim*ydim-remain+1 + do i=localArbIndexCount-remain+1,localArbIndexCount + localArbIndex(i,1)=mod(ind,ydim)+1 + localArbIndex(i,2)=ind/ydim+1 + ind = ind + 1 + enddo + endif + + !------------------------------------------------------------------- + ! Create the Grid: Allocate space for the Grid object. + ! the minIndex hasn't been set, so it defaults to (1,1,...). The + ! default coordDep1 and coordDep2 are (/ESMF_DIM_ARB/) where + ! ESMF_DIM_ARB represents the collapsed dimension for the + ! arbitrarily distributed grid dimensions. For the undistributed + ! grid dimension, the default value for coordDep3 is (/3/). The + ! default values for coordDepX in the arbitrary distribution are + ! different from the non-arbitrary distributions. + !------------------------------------------------------------------- + grid3D=ESMF_GridCreateNoPeriDim( & + maxIndex = (/xdim, ydim, zdim/), & + arbIndexList = localArbIndex, & + arbIndexCount = localArbIndexCount, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Allocate coordinate storage for the center stagger location, the + ! only stagger location supported for the arbitrary distribution. + !------------------------------------------------------------------- + call ESMF_GridAddCoord(grid3D, & + staggerloc=ESMF_STAGGERLOC_CENTER_VCENTER, rc=rc) ++ +
+
+ !------------------------------------------------------------------ + ! Fill in the coordinates for the center stagger location. There is + ! always one DE per PET, so localDE is always 0 + !------------------------------------------------------------------ + call ESMF_GridGetCoord(grid3D, coordDim=1, localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CENTER, & + computationalLBound=lbnd, & + computationalUBound=ubnd, & + farrayPtr=centerX, rc=rc) ++ +
+
+ !---------------------------------------------------------------- + ! Calculate and set coordinates in the first dimension. + !---------------------------------------------------------------- + do i=lbnd(1),ubnd(1) + centerX(i) = (localArbIndex(i,1)-0.5)*(360.0/xdim) + enddo + + + !---------------------------------------------------------------- + ! Get the local bounds of the global indexing for the second + ! coordinate array on the local DE, and the pointer to the array. + !---------------------------------------------------------------- + call ESMF_GridGetCoord(grid3D, coordDim=2, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + computationalLBound=lbnd, computationalUBound=ubnd, & + farrayPtr=centerY, rc=rc) ++ +
+
+ !---------------------------------------------------------------- + ! Calculate and set coordinates in the second dimension. + !---------------------------------------------------------------- + do j=lbnd(1),ubnd(1) + centerY(j) = (localArbIndex(j,2)-0.5)*(180.0/ydim)-90.0 + enddo + + !---------------------------------------------------------------- + ! Get the local bounds of the global indexing for the third + ! coordinate array on the local DE, and the pointer to the array. + !---------------------------------------------------------------- + call ESMF_GridGetCoord(grid3D, coordDim=3, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + computationalLBound=lbnd, computationalUBound=ubnd,& + farrayPtr=centerZ, rc=rc) ++ +
+
+ !---------------------------------------------------------------- + ! Calculate and set the vertical coordinates + !---------------------------------------------------------------- + do k=lbnd(1),ubnd(1) + centerZ(k) = 4000.0*( (1./zdim)*(k-1))**2 + enddo ++ +
+ +
+ESMF supports the creation of a 2D curvilinear Grid using the coordinates + defined in a SCRIP format Grid file [13]. The grid contained in the + file must be a 2D logically rectangular grid with grid_rank in the file set + to 2. The center coordinates variables grid_center_lat and grid_center_lon in the file + are placed in the ESMF_STAGGERLOC_CENTER location. If the parameter addCornerStagger + in the ESMF_GridCreate call is set to .true., then + the variables grid_corner_lat and grid_corner_lon in the file + are used to set the ESMF_STAGGERLOC_CORNER coordinates, otherwise they are ignored. + The values in the grid_imask variable in the file are used to set the ESMF_GRIDITEM_MASK in the Grid. + +
+The following example code shows you how to create a 2D Grid with both center and corner coordinates + using a SCRIP file and a row only regular distribution: +
+
+ grid2D = ESMF_GridCreate(filename="data/T42_grid.nc", & + fileFormat=ESMF_FILEFORMAT_SCRIP, & + regDecomp=(/PetCount,1/), addCornerStagger=.true., rc=rc) ++ +
+where T42_grid.nc is a 2D global grid of size (128x64) and the resulting Grid is distributed + by partitioning the rows evenly over all the PETs. + +
+ESMF also support the creation of a 2D Grid from the SCRIP format Grid file using a user specified + ESMF_DistGrid. The following example code demonstrates the creation of an Grid object using a pre-defined + DistGrid. The resulting Grid is the same as the one created above: +
+
+ distgrid = ESMF_DistGridCreate((/1,1/), (/128,64/), & + regDecomp=(/PetCount,1/), rc=rc) + grid2D = ESMF_GridCreate(filename="data/T42_grid.nc", & + fileFormat=ESMF_FILEFORMAT_SCRIP, & + distGrid=distgrid, addCornerStagger=.true., rc=rc) ++ +
+ +
+ESMF Grids can be created incrementally. To do this, + the user first calls ESMF_GridEmptyCreate() to allocate the shell of + a Grid. Next, we use the ESMF_GridEmptyComplete() + call that fills in the Grid and does an internal commit to make it usable. + For consistency's sake the ESMF_GridSetCommitShapeTile() + call must occur on the same or a subset of the PETs as the + ESMF_GridEmptyCreate() call. The + ESMF_GridEmptyComplete() call uses the VM for + the context in which it's executed and the "empty" Grid contains + no information about the VM in which its create was run. This + means that if the ESMF_GridEmptyComplete() call occurs + in a subset of the PETs in which the ESMF_GridEmptyCreate() was + executed that the Grid is created only in that subset. Inside the subset + the Grid will be fine, but outside the subset the Grid objects will + still be "empty" and not usable. The following example uses the + incremental technique to create a rectangular 10x20 Grid with coordinates at + the center and corner stagger locations. + +
+
+!--------------------------------------------------------------------------- +! IN THE PARENT COMPONENT: +! Create an empty Grid in the parent component for use in a child component. +! The parent may be defined on more PETs than the child component. +! The child's [vm or pet list] is passed into the create call so that +! the Grid is defined on the appropriate subset of the parent's PETs. +!--------------------------------------------------------------------------- + grid2D=ESMF_GridEmptyCreate(rc=rc) ++ +
+
+!--------------------------------------------------------------------------- +! IN THE CHILD COMPONENT: +! Set the Grid topology. Here we define an irregularly distributed +! rectangular Grid. +!--------------------------------------------------------------------------- + call ESMF_GridEmptyComplete(grid2D, & + countsPerDEDim1=(/6,4/), & + countsPerDEDim2=(/10,3,7/), rc=rc) ++ +
+
+!--------------------------------------------------------------------------- +! Add Grid coordinates at the cell center location. +!--------------------------------------------------------------------------- + call ESMF_GridAddCoord(grid2D, staggerLoc=ESMF_STAGGERLOC_CENTER, rc=rc) ++ +
+
+!--------------------------------------------------------------------------- +! Add Grid coordinates at the corner stagger location. +!--------------------------------------------------------------------------- + call ESMF_GridAddCoord(grid2D, staggerLoc=ESMF_STAGGERLOC_CORNER, rc=rc) ++ +
+ +
+This example creates a multi-tile Grid to represent a cubed sphere grid. + Each of the six tiles making up the cubed sphere has 45 elements on + each side, so the total number of elements is 45x45x6=12150. Each tile is + decomposed using a regular decomposition. The first two tiles are decomposed into + 2x2 blocks each and the remaining 4 tiles are decomposed into 1x2 block. + A total of 16 DEs are used. + +
+In this example, both the center and corner coordinates will be added to the grid. +
+
+ ! Set up decomposition for each tile + allocate(decomptile(2,6)) + decomptile(:,1)=(/2,2/) ! Tile 1 + decomptile(:,2)=(/2,2/) ! Tile 2 + decomptile(:,3)=(/1,2/) ! Tile 3 + decomptile(:,4)=(/1,2/) ! Tile 4 + decomptile(:,5)=(/1,2/) ! Tile 5 + decomptile(:,6)=(/1,2/) ! Tile 6 + + ! Create cubed sphere grid + grid2D = ESMF_GridCreateCubedSphere(tileSize=45, regDecompPTile=decomptile, & + staggerLocList=(/ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER/), rc=rc) ++ +
+ +
+This example creates the same cubed sphere grid with the same regular + decomposition as in 31.3.10 with a few differences. + First, the coordinates of the grid are of type ESMF_TYPEKIND_R4 + instead of the default ESMF_TYPEKIND_R8. Secondly, the coordinate + system is ESMF_COORDSYS_SPH_RAD instead of the default ESMF_COORDSYS_SPH_DEG. + Lastly, the grid was then + transformed using Schmidt Transformation algorithm on an arbitrary + target point and a streatching factor. An optional argument TransformArgs of + type ESMF_CubedSphereTransform_Args is used to pass the Schmidt + Transform arguments. ESMF_CubedSphereTransform_Args is defined as + follows: +
+ type ESMF_CubedSphereTransform_Args + real(ESMF_KIND_R8) :: stretch_factor, target_lat, target_lon + end type ++ +
+Note target_lat and target_lon are in radians. +
+
+ transformArgs%stretch_factor = 0.5; + transformArgs%target_lon = 0.0; ! in radians + transformArgs%target_lat = 1.3; ! in radians + grid2D = ESMF_GridCreateCubedSphere(tileSize=45, regDecompPTile=decomptile, & + staggerLocList = (/ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER/), & + coordTypeKind = ESMF_TYPEKIND_R4, & + coordSys = ESMF_COORDSYS_SPH_RAD, & + transformArgs=transformArgs, & + rc=rc) ++ +
+ +
+This example creates a six-tile Grid to represent a cubed sphere grid defined + in a GRIDSPEC Mosaic file C48_mosaic.nc. The GRIDSPEC mosaic file format is defined in + the document GRIDSPEC: A standard for the description of grids used in Earth System models +by V. Balaji, Alistair Adcroft and Zhi Liang. + +
+The mosaic file contains the following information: + +
+
+ netcdf C48_mosaic { + dimensions: + ntiles = 6 ; + ncontact = 12 ; + string = 255 ; + variables: + char mosaic(string) ; + mosaic:standard_name = "grid_mosaic_spec" ; + mosaic:children = "gridtiles" ; + mosaic:contact_regions = "contacts" ; + mosaic:grid_descriptor = "" ; + char gridlocation(string) ; + gridlocation:standard_name = "grid_file_location" ; + char gridfiles(ntiles, string) ; + char gridtiles(ntiles, string) ; + char contacts(ncontact, string) ; + contacts:standard_name = "grid_contact_spec" ; + contacts:contact_type = "boundary" ; + contacts:alignment = "true" ; + contacts:contact_index = "contact_index" ; + contacts:orientation = "orient" ; + char contact_index(ncontact, string) ; + contact_index:standard_name = "starting_ending_point_index_of_contact" ; + + // global attributes: + :grid_version = "0.2" ; + :code_version = "$Name: testing $" ; + data: + + mosaic = "C48_mosaic" ; + + gridlocation = "/archive/z1l/tools/test_20091028/output_all/" ; + + gridfiles = + "horizontal_grid.tile1.nc", + "horizontal_grid.tile2.nc", + "horizontal_grid.tile3.nc", + "horizontal_grid.tile4.nc", + "horizontal_grid.tile5.nc", + "horizontal_grid.tile6.nc" ; + + gridtiles = + "tile1", + "tile2", + "tile3", + "tile4", + "tile5", + "tile6" ; + + contacts = + "C48_mosaic:tile1::C48_mosaic:tile2", + "C48_mosaic:tile1::C48_mosaic:tile3", + "C48_mosaic:tile1::C48_mosaic:tile5", + "C48_mosaic:tile1::C48_mosaic:tile6", + "C48_mosaic:tile2::C48_mosaic:tile3", + "C48_mosaic:tile2::C48_mosaic:tile4", + "C48_mosaic:tile2::C48_mosaic:tile6", + "C48_mosaic:tile3::C48_mosaic:tile4", + "C48_mosaic:tile3::C48_mosaic:tile5", + "C48_mosaic:tile4::C48_mosaic:tile5", + "C48_mosaic:tile4::C48_mosaic:tile6", + "C48_mosaic:tile5::C48_mosaic:tile6" ; + + contact_index = + "96:96,1:96::1:1,1:96", + "1:96,96:96::1:1,96:1", + "1:1,1:96::96:1,96:96", + "1:96,1:1::1:96,96:96", + "1:96,96:96::1:96,1:1", + "96:96,1:96::96:1,1:1", + "1:96,1:1::96:96,96:1", + "96:96,1:96::1:1,1:96", + "1:96,96:96::1:1,96:1", + "1:96,96:96::1:96,1:1", + "96:96,1:96::96:1,1:1", + "96:96,1:96::1:1,1:96" ; + } ++ +
+A dummy variable with its standard_name attribute set to grid_mosaic_spec is required. + The children attribute of this dummy variable provides the variable name that contains the tile names and the + contact_region attribute points to the variable name that defines a list of tile pairs that are connected + to each other. For a Cubed Sphere grid, there are six tiles and 12 connections. The contacts variable + has three required attributes: standard_name, contact_type, and contact_index. startand_name + has to be set to grid_contact_spec. contact_type has to be boundary. ESMF does not support + overlapping contact regions. contact_index defines the variable name that contains the information how the + two adjacent tiles are connected to each other. The contact_index variable contains 12 entries. Each entry + contains the index of four points that defines the two edges that contact to + each other from the two neighboring tiles. Assuming the four points are A, B, C, and D. + A and B defines the edge of tile 1 and C and D defines the edge of tile2. A is the same point + as C and B is the same as D. (Ai, Aj) is the index for point A. The entry looks like this: +
+ Ai:Bi,Aj:Bj::Ci:Di,Cj:Dj ++ +
+The associated tile file names are defined in variable gridfiles and the directory path is defined in + variable gridlocation. + The gridlocation can be overwritten with an optional arguemnt TileFilePath. Each tile is + decomposed using a regular decomposition. The first two tiles are decomposed into + 2x2 blocks each and the remaining 4 tiles are decomposed into 1x2 block. + A total of 16 DEs are used. + +
+ESMF_GridCreateMosaic() first reads in the mosaic file and defines the tile connections in the + ESMF_DistGrid using the information + defined in variables contacts and contact_index. Then it reads in the coordinates defined in + the tile files if the optional argument staggerLocList is provided. The coordinates defined in the tile file are a + supergrid. A supergrid contains all the stagger locations in one grid. + It contains the corner, edge and center coordinates all in one 2D array. + In this example, there are 48 elements in each side of a tile, therefore, the size of the supergrid is + 48*2+1=97, i.e. 97x97. + +
+Here is the header of one of the tile files: + +
+
+ netcdf horizontal_grid.tile1 { + dimensions: + string = 255 ; + nx = 96 ; + ny = 96 ; + nxp = 97 ; + nyp = 97 ; + variables: + char tile(string) ; + tile:standard_name = "grid_tile_spec" ; + tile:geometry = "spherical" ; + tile:north_pole = "0.0 90.0" ; + tile:projection = "cube_gnomonic" ; + tile:discretization = "logically_rectangular" ; + tile:conformal = "FALSE" ; + double x(nyp, nxp) ; + x:standard_name = "geographic_longitude" ; + x:units = "degree_east" ; + double y(nyp, nxp) ; + y:standard_name = "geographic_latitude" ; + y:units = "degree_north" ; + double dx(nyp, nx) ; + dx:standard_name = "grid_edge_x_distance" ; + dx:units = "meters" ; + double dy(ny, nxp) ; + dy:standard_name = "grid_edge_y_distance" ; + dy:units = "meters" ; + double area(ny, nx) ; + area:standard_name = "grid_cell_area" ; + area:units = "m2" ; + double angle_dx(nyp, nxp) ; + angle_dx:standard_name = "grid_vertex_x_angle_WRT_geographic_east" ; + angle_dx:units = "degrees_east" ; + double angle_dy(nyp, nxp) ; + angle_dy:standard_name = "grid_vertex_y_angle_WRT_geographic_north" ; + angle_dy:units = "degrees_north" ; + char arcx(string) ; + arcx:standard_name = "grid_edge_x_arc_type" ; + arcx:north_pole = "0.0 90.0" ; + + // global attributes: + :grid_version = "0.2" ; + :code_version = "$Name: testing $" ; + :history = "/home/z1l/bin/tools_20091028/make_hgrid --grid_type gnomonic_ed --nlon 96" ; + } ++ +
+The tile file not only defines the coordinates at all staggers, it also has a complete specification of + distances, angles, and areas. In ESMF, we currently only use the geographic_longitude and geographic_latitude + variables. +
+
+ ! Set up decomposition for each tile + allocate(decomptile(2,6)) + decomptile(:,1)=(/2,2/) ! Tile 1 + decomptile(:,2)=(/2,2/) ! Tile 2 + decomptile(:,3)=(/1,2/) ! Tile 3 + decomptile(:,4)=(/1,2/) ! Tile 4 + decomptile(:,5)=(/1,2/) ! Tile 5 + decomptile(:,6)=(/1,2/) ! Tile 6 + + ! Create cubed sphere grid without reading in the coordinates + grid2D = ESMF_GridCreateMosaic(filename='data/C48_mosaic.nc', & + tileFilePath='./data/', regDecompPTile=decomptile, rc=rc) ++ +
+
+ ! Create cubed sphere grid and read in the center and corner stagger coordinates + ! from the tile files + + grid2D = ESMF_GridCreateMosaic(filename='data/C48_mosaic.nc', & + staggerLocList=(/ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER/), & + tileFilePath='./data/', regDecompPTile=decomptile, rc=rc) ++ +
+
+ ! Create cubed sphere grid and read in the edge staggers' coordinates + ! from the tile files, set the coordTypeKind to ESMF_TYPEKIND_R4 + + grid2D = ESMF_GridCreateMosaic(filename='data/C48_mosaic.nc', & + staggerLocList=(/ESMF_STAGGERLOC_EDGE1, ESMF_STAGGERLOC_EDGE2/), & + coordTypeKind = ESMF_TYPEKIND_R4, & + tileFilePath='./data/', regDecompPTile=decomptile, rc=rc) ++ +
+ +
+A useful finite difference technique is to place different physical + quantities at different locations within a grid cell. This + staggering of the physical variables on the mesh is introduced so + that the difference of a field is naturally defined at the location of + another variable. This method was first formalized by Mesinger and Arakawa + (1976). + +
+To support the staggering of variables, the Grid provides + the idea of stagger locations. + Stagger locations refer to the places in a Grid cell that + can contain coordinates or other data and once a Grid is associated with a + Field object, field data. Typically Grid data can be located + at the cell center, at the cell corners, or at the cell faces, in 2D, 3D, and + higher dimensions. (Note that any Arakawa stagger can be constructed + of a set of Grid stagger locations.) There are predefined stagger locations + (see Section 31.2.6), or, + should the user wish to specify their own, there + is also a set of methods for generating custom locations + (See Section 31.3.25). + Users can put Grid data (e.g. coordinates) + at multiple stagger locations in a Grid. In addition, the user can create a Field + at any of the stagger locations in a Grid. + +
+By default the Grid data array at the center stagger location + starts at the bottom index of the Grid (default (1,1..,1)) and extends + up to the maximum cell index in the Grid (e.g. given by the maxIndex argument). + Other stagger locations also start at the bottom index of the Grid, however, + they can extend to +1 element beyond the center in some dimensions to allow + for the extra space to surround the center elements. See Section 31.3.25 + for a description of this extra space and how to adjust if it necessary. + There are ESMF_GridGet subroutines (e.g. ESMF_GridGetCoord() or ESMF_GridGetItem()) + which can be used to retrieve the stagger bounds for the piece of Grid data + on a particular DE. + +
+ +
+The primary type of data the Grid is responsible for storing is coordinates. + The coordinate values in a Grid can be employed by the user in calculations or + to describe the geometry of a Field. The Grid coordinate values are also used by + ESMF_FieldRegridStore() when calculating the interpolation + matrix between two Fields. The user can allocate coordinate arrays without setting coordinate values + using the ESMF_GridAddCoord() call. (See Section 31.3.16 for a discussion of + setting/getting coordinate values.) When adding or accessing + coordinate data, the stagger location is specified to tell the Grid method + where in the cell to get the data. The different stagger locations may also have slightly different + index ranges and sizes. Please see Section 31.3.13 for a discussion of + Grid stagger locations. + +
+The following example adds coordinate storage to the corner stagger location in a Grid using one + of the predefined stagger locations. +
+
+ call ESMF_GridAddCoord(grid2D, staggerLoc=ESMF_STAGGERLOC_CORNER, rc=rc) ++ +
+Note only the center stagger location ESMF_STAGGERLOC_CENTER is supported + in an arbitrarily distributed Grid. + +
+ +
+To specify how the coordinate arrays are mapped to the + index dimensions the arguments coordDep1, + coordDep2, and coordDep3 are used, each + of which is a Fortran array. The values of the elements + in a coordDep array specify which index dimension + the corresponding coordinate dimension + maps to. For example, coordDep1=(/1,2/) means that + the first dimension of coordinate 1 maps to index + dimension 1 and the second maps to index dimension 2. + For a grid with non-arbitrary distribution, the default + values for coordDep1, coordDep2 and coordDep3 + are /1,2..,gridDimCount/. This default + thus specifies a curvilinear grid. + +
+The following call demonstrates the creation of a + 10x20 2D rectilinear grid where the first coordinate + component is mapped to the second index dimension + (i.e. is of size 20) and the second coordinate component + is mapped to the first index dimension (i.e. is of size + 10). +
+
+ grid2D=ESMF_GridCreateNoPeriDim(countsPerDEDim1=(/5,5/), & + countsPerDEDim2=(/7,7,6/), & + coordDep1=(/2/), & + coordDep2=(/1/), rc=rc) ++ +
+The following call demonstrates the creation of a + 10x20x30 2D plus 1 curvilinear grid where + coordinate component 1 and 2 are still 10x20, but + coordinate component 3 is mapped just to the + third index dimension. +
+
+ grid2D=ESMF_GridCreateNoPeriDim(countsPerDEDim1=(/6,4/), & + countsPerDEDim2=(/10,7,3/), countsPerDEDim3=(/30/), & + coordDep1=(/1,2/), coordDep2=(/1,2/), & + coordDep3=(/3/), rc=rc) ++ +
+By default the local piece of the array on each PET starts at + (1,1,..), however, the indexing for each grid coordinate array + on each DE may be shifted to the global indices by using the indexflag. + For example, the following call switches the grid to use global indices. +
+
+ grid2D=ESMF_GridCreateNoPeriDim(countsPerDEDim1=(/6,4/), & + countsPerDEDim2=(/10,7,3/), indexflag=ESMF_INDEX_GLOBAL, rc=rc) ++ +
+For an arbitrarily distributed grid, the default value of a coordinate + array dimension is ESMF_DIM_ARB if the index dimension is arbitrarily + distributed and is n where n is the index dimension itself when it is not + distributed. The following call is equivalent to the example in + Section 31.3.7 +
+
+ grid3D=ESMF_GridCreateNoPeriDim( & + maxIndex = (/xdim, ydim, zdim/), & + arbIndexList = localArbIndex, & + arbIndexCount = localArbIndexCount, & + coordDep1 = (/ESMF_DIM_ARB/), & + coordDep2 = (/ESMF_DIM_ARB/), & + coordDep3 = (/3/), & + rc=rc) ++ +
+The following call uses non-default coordDep1, coordDep2, + and coordDep3 to create a 3D curvilinear grid with its horizontal + dimensions arbitrarily distributed. +
+
+ grid3D=ESMF_GridCreateNoPeriDim( & + maxIndex = (/xdim, ydim, zdim/), & + arbIndexList = localArbIndex, & + arbIndexCount = localArbIndexCount, & + coordDep1 = (/ESMF_DIM_ARB, 3/), & + coordDep2 = (/ESMF_DIM_ARB, 3/), & + coordDep3 = (/ESMF_DIM_ARB, 3/), & + rc=rc) ++ +
+ +
+Once a Grid has been created, the user has several options to access + the Grid coordinate data. The first of these, ESMF_GridSetCoord(), + enables the user to use ESMF Arrays to set data + for one stagger location across the whole Grid. + For example, the following sets the coordinates in the first dimension + (e.g. x) for the corner stagger location to + those in the ESMF Array arrayCoordX. +
+
+ call ESMF_GridSetCoord(grid2D, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + coordDim=1, array=arrayCoordX, rc=rc) ++ +
+The method ESMF_GridGetCoord() allows the user + to obtain a reference to an ESMF Array which + contains the coordinate data for a stagger location in a Grid. The user + can then employ any of the standard ESMF_Array tools to operate + on the data. The following copies the coordinates from the second + component of the corner and puts it into the ESMF Array arrayCoordY. +
+
+ call ESMF_GridGetCoord(grid2D, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + coordDim=2, & + array=arrayCoordY, rc=rc) ++ +
+Alternatively, the call ESMF_GridGetCoord() gets a Fortran pointer to + the coordinate data. The user can then operate on this array in the usual + manner. The following call gets a reference to the + Fortran array which holds the data for the second coordinate (e.g. y). +
+
+ call ESMF_GridGetCoord(grid2D, coordDim=2, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CORNER, farrayPtr=coordY2D, rc=rc) ++ +
+ +
+The ESMF Grids contain the ability to store other kinds of + data beyond coordinates. These kinds of data are referred to + as "items". Although the user is free to use this + data as they see fit, the user should be aware that + this data may also be used by other parts of ESMF (e.g. the + ESMF_GRIDITEM_MASK item is used in regridding). + Please see Section 31.2.2 for a list of valid + items. + +
+Like coordinates items are also created on stagger locations. + When adding or accessing item data, the stagger location is specified to tell the Grid method + where in the cell to get the data. The different stagger locations may also have slightly different + index ranges and sizes. Please see Section 31.3.13 for a discussion of + Grid stagger locations. The user can + allocate item arrays without setting item values using the ESMF_GridAddItem() call. + (See Section 31.3.18 for a discussion of setting/getting item values.) + +
+The following example adds mask item storage to the corner stagger location in a grid. +
+
+ call ESMF_GridAddItem(grid2D, staggerLoc=ESMF_STAGGERLOC_CORNER, & + itemflag=ESMF_GRIDITEM_MASK, rc=rc) ++ +
+ +
+
+ call ESMF_GridSetItem(grid2D, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + itemflag=ESMF_GRIDITEM_MASK, array=arrayMask, rc=rc) ++ +
+The method ESMF_GridGetItem() allows the user + to get a reference to the Array which + contains item data for a stagger location on a Grid. The user + can then employ any of the standard ESMF_Array tools to operate + on the data. The following gets the mask data from the corner + and puts it into the ESMF Array arrayMask. +
+
+ call ESMF_GridGetItem(grid2D, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + itemflag=ESMF_GRIDITEM_MASK, & + array=arrayMask, rc=rc) ++ +
+Alternatively, the call ESMF_GridGetItem() gets a Fortran pointer to + the item data. The user can then operate on this array in the usual + manner. The following call gets a reference to the + Fortran array which holds the data for the mask data. +
+
+ call ESMF_GridGetItem(grid2D, localDE=0, & + staggerloc=ESMF_STAGGERLOC_CORNER, & + itemflag=ESMF_GRIDITEM_MASK, farrayPtr=mask2D, rc=rc) ++ +
+ +
+Like an Array or a Field, the index space of each + stagger location in the Grid contains an exclusive region, a + computational region and a total region. Please + see Section 28.2.6 + for an in depth description of these regions. + +
+The exclusive region is the index space defined by the + distgrid of each stagger location of the Grid. This region + is the region which is owned by the DE and is the region + operated on by communication methods such as ESMF_FieldRegrid(). + The exclusive region for a stagger location is based on the + exclusive region defined by the DistGrid used to create the Grid. + The size of the stagger exclusive region is the index space for the + Grid cells, plus the stagger padding. + +
+The default stagger padding depends on the topology of the Grid. + For an unconnected dimension the stagger padding is a width + of 1 on the upper side (i.e. gridEdgeUWidth=(1,1,1,1...)). + For a periodic dimension there is no stagger padding. + By adjusting gridEdgeLWidth and gridEdgeUWidth, the + user can set the stagger padding for the whole Grid and + thus the exclusive region can be adjusted at will around the + index space corresponding to the cells. The user can + also use staggerEdgeLWidth and staggerEdgeUWidth to + adjust individual stagger location padding within the + Grid's padding (Please see Section 31.3.26 for + further discussion of customizing the stagger padding). + +
+
+Figure 17 shows an example of a Grid exclusive region for the + ESMF_STAGGERLOC_CORNER stagger with default + stagger padding. This exclusive region would be for a Grid generated by either of the + following calls: +
+
+ grid2D=ESMF_GridCreateNoPeriDim(regDecomp=(/2,4/), maxIndex=(/5,15/), & + indexflag=ESMF_INDEX_GLOBAL, rc=rc) ++ +
+
+ grid2D=ESMF_GridCreateNoPeriDim(countsPerDEDim1=(/4,4,4,3/), & + countsPerDEDim2=(/3,2/), indexflag=ESMF_INDEX_GLOBAL, rc=rc) ++ +
+Each rectangle in this diagram represents a DE and the numbers along the sides + are the index values of the locations in the DE. Note that the exclusive region + has one extra index location in each dimension than the number of cells + because of the padding for the larger corner stagger location. + +
+The computational region is a user-settable region which can be used + to distinguish a particular area for computation. The Grid doesn't + currently contain functionality to let the user set the computational + region so it defaults to the exclusive region. However, if the + user sets an Array holding different computational bounds into the + Grid then that Array's computational bounds will be used. + +
+The total region is the outermost boundary of the memory allocated + on each DE to hold the data for the stagger location on that DE. This region + can be as small as the exclusive region, but may be larger to + include space for halos, memory padding, etc. The total region is + what is enlarged to include space for halos, and the total region + must be large enough to contain the maximum halo operation on the + Grid. The Grid doesn't currently contain functionality to let the + user set the total region so it defaults to the exclusive region. + However, if the + user sets an Array holding different total bounds into the + Grid then that Array's total bounds will be used. + +
+The user can retrieve a set of bounds for each index space region + described above: exclusive bounds, computational bounds, + and total bounds. Note that although some of these are similar + to bounds provided by ESMF_Array subroutines + (see Section 28.2.6) + the format here is different. The Array bounds are only for + distributed dimensions and are ordered to correspond + to the dimension order in the associated DistGrid. The bounds + provided by the Grid are ordered according to the order of dimensions of the data + in question. This means that the bounds provided should be usable + "as is" to access the data. + +
+Each of the three types of bounds refers to the maximum and minimum + per dimension of the index ranges of a particular region. The parameters + referring to the maximums contain a 'U' for upper. The parameters referring + to the minimums contain an 'L' for lower. The bounds and associated + quantities are almost always given on a per DE basis. The three types of + bounds exclusiveBounds, computationalBounds, and totalBounds refer + to the ranges of the exclusive region, the computational region, and the + total region. Each of these bounds also has a corresponding count parameter + which gives the number of items across that region (on a DE) in each dimension. + (e.g. totalCount(d)=totallUBound(i)-totalLBound(i)+1). Width parameters + give the spacing between two different types of region. The + computationalWidth argument gives the spacing between the exclusive + region and the computational region. The totalWidth argument gives the + spacing between the total region and the computational region. Like the + other bound information these are typically on a per DE basis, for example + specifying totalLWidth=(1,1) makes the bottom of the total + region one lower in each dimension than the computational region on + each DE. The exceptions to the per DE rule are + staggerEdgeWidth, and gridEdgeWidth + which give the spacing only on the DEs along the boundary of the Grid. + +
+All the above bound discussions only apply to the grid with non-arbitrary distributions, + i.e., regular or irregular distributions. For an arbitrarily distributed grid, + only center stagger location is supported and there is no padding around the grid. + Thus, the exclusive bounds, the total bounds and the computational bounds are identical + and staggerEdgeWidth, and gridEdgeWidth are all zeros. + +
+ +
+When operating on coordinates the user may often wish to + retrieve the bounds of the piece of coordinate data on + a particular local DE. This is useful for iterating through the + data to set coordinates, retrieve coordinates, or do calculations. + The method ESMF_GridGetCoord allows the user + to retrieve bound information for a particular coordinate + array. + +
+As described in the previous section there are three types of bounds the user can + get: exclusive bounds, computational bounds, + and total bounds. The bounds + provided by ESMF_GridGetCoordBounds are for both distributed + and undistributed dimensions and are ordered according to the + order of dimensions in the coordinate. This means that the bounds + provided should be usable + "as is" to access data in the coordinate array. In the case + of factorized coordinate Arrays where a coordinate may + have a smaller dimension than its associated Grid, then + the dimension of the coordinate's bounds are the dimension of + the coordinate, not the Grid. + +
+The following is an example of retrieving the bounds for localDE 0 for the first + coordinate array from the corner stagger location. +
+
+ call ESMF_GridGetCoordBounds(grid2D, coordDim=1, localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + exclusiveLBound=elbnd, exclusiveUBound=eubnd, & + computationalLBound=clbnd, computationalUBound=cubnd, & + totalLBound=tlbnd, totalUBound=tubnd, rc=rc) ++ +
+ +
+When operating on data stored at a particular stagger + in a Grid the user may find it useful to be able + to retrieve the bounds of the data on a particular local DE. + This is useful for iterating through the + data for computations or allocating arrays to hold the data. + The method ESMF_GridGet allows the user + to retrieve bound information for a particular stagger location. + +
+As described in Section 31.3.19 there are three types of bounds + the user can typically get, however, the Grid doesn't hold data at + a stagger location (that is the job of the Field), and so + no Array is contained there and so no total region exists, so the + user may only retrieve exclusive and computational bounds from + a stagger location. The bounds + provided by ESMF_GridGet are ordered according to the + order of dimensions in the Grid. + +
+The following is an example of retrieving the bounds for localDE 0 + from the corner stagger location. +
+
+ call ESMF_GridGet(grid2D, localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + exclusiveLBound=elbnd, exclusiveUBound=eubnd, & + computationalLBound=clbnd, computationalUBound=cubnd, rc=rc) ++ +
+ +
+In addition to the per DE information that can be accessed about + a stagger location there is some global information that can + accessed by using ESMF_GridGet without specifying a + localDE. One of the uses of this information is to create + an ESMF Array to hold data for a stagger location. + +
+The information currently available from a stagger + location is the distgrid. The distgrid gives the + distgrid which describes the size and distribution of the elements in the stagger location. + +
+The following is an example of retrieving information for localDE 0 + from the corner stagger location. +
+
+ ! Get info about staggerloc + call ESMF_GridGet(grid2D, staggerLoc=ESMF_STAGGERLOC_CORNER, & + distgrid=staggerDistgrid, & + rc=rc) ++ +
+ +
+In order to create an Array to correspond to a Grid stagger location + several pieces of information need to be obtained from both the + Grid and the stagger location in the Grid. + +
+The information that needs to be obtained from the Grid + is the distgridToGridMap to ensure that the new Array + has its dimensions are mapped correctly to the Grid. These + are obtained using the ESMF_GridGet method. + +
+The information that needs to be obtained from the stagger + location is the distgrid that describes the size and distribution + of the elements in the stagger location. This information can + be obtained using the stagger location specific ESMF_GridGet method. + +
+The following is an example of using information from a 2D Grid with non-arbitrary + distribution to create an Array corresponding to a stagger location. + +
+
+ ! Get info from Grid + call ESMF_GridGet(grid2D, distgridToGridMap=distgridToGridMap, rc=rc) ++ +
+
+ ! Get info about staggerloc + call ESMF_GridGet(grid2D, staggerLoc=ESMF_STAGGERLOC_CORNER, & + distgrid=staggerDistgrid, & + rc=rc) ++ +
+
+ ! construct ArraySpec + call ESMF_ArraySpecSet(arrayspec, rank=2, typekind=ESMF_TYPEKIND_R8, rc=rc) ++ +
+
+ ! Create an Array based on info from grid + array=ESMF_ArrayCreate(arrayspec=arrayspec, & + distgrid=staggerDistgrid, distgridToArrayMap=distgridToGridMap, & + rc=rc) ++ +
+Creating an Array for a Grid with arbitrary distribution is different. + For a 2D Grid with both dimension arbitrarily distributed, the Array dimension + is 1. For a 3D Grid with two arbitrarily distributed dimensions and one + undistributed dimension, the Array dimension is 2. In general, + if the Array does not have any ungridded dimension, the Array dimension + should be 1 plus the number of undistributed dimensions of the Grid. + +
+The following is an example of creating an Array for a 3D Grid with 2 + arbitrarily distributed dimensions such as the one defined in Section 31.3.7. +
+
+ ! Get distGrid from Grid + call ESMF_GridGet(grid3D, distgrid=distgrid, rc=rc) ++ +
+
+ ! construct ArraySpec + call ESMF_ArraySpecSet(arrayspec, rank=2, typekind=ESMF_TYPEKIND_R8, rc=rc) ++ +
+
+ ! Create an Array based on the presence of distributed dimensions + array=ESMF_ArrayCreate(arrayspec=arrayspec,distgrid=distgrid, rc=rc) ++ +
+ +
+Besides the shortcut methods for creating a Grid object such as + ESMF_GridCreateNoPeriDim(), there is + a set of methods which give the user more control over the + specifics of the grid. The following describes the more + general interface, using DistGrid. + The basic idea is to first create an ESMF DistGrid object describing + the distribution and shape of the Grid, and then to employ that to either directly + create the Grid or first create Arrays and then create the Grid from those. + This method gives the user maximum control over the topology and distribution of the Grid. + See the DistGrid documentation in Section 36.1 for an + in-depth description of its interface and use. + +
+As an example, the following call constructs + a 10x20 Grid with a lower bound of (1,2). +
+
+ ! Create DistGrid + distgrid2D = ESMF_DistGridCreate(minIndex=(/1,2/), maxIndex=(/11,22/), & + rc=rc) ++ +
+
+ ! Create Grid + grid3D=ESMF_GridCreate(distGrid=distgrid2D, rc=rc) ++ +
+To alter which dimensions are distributed, the distgridToGridMap + argument can be used. The distgridToGridMap is used to set + which dimensions of the Grid are mapped to the dimensions + described by maxIndex. In other words, it describes how the dimensions of + the underlying default DistGrid are mapped to the Grid. Each entry + in distgridToGridMap contains the Grid dimension to which the corresponding + DistGrid dimension should be mapped. + The following example illustrates the creation of a Grid where the largest + dimension is first. To accomplish this the two dimensions are swapped. + +
+
+ ! Create DistGrid + distgrid2D = ESMF_DistGridCreate(minIndex=(/1,2/), maxIndex=(/11,22/), & + rc=rc) ++ +
+
+ ! Create Grid + grid2D=ESMF_GridCreate(distGrid=distgrid2D, distgridToGridMap=(/2,1/), & + rc=rc) ++ +
+ +
+Although ESMF provides a set of predefined stagger locations (See Section 31.2.6), + the user may need one outside this set. This section describes the construction of + custom stagger locations. + +
+To completely specify a stagger for an arbitrary number of dimensions, we define the + stagger location in terms of a set of cartesian coordinates. The cell is represented + by a n-dimensional cube with sides of length 2, and the coordinate origin located at + the center of the cell. The geometry of the cell is for reference purposes only, + and does not literally represent the actual shape of the cell. Think of this method + instead as an easy way to specify a part (e.g. center, corner, face) of a higher + dimensional cell which is extensible to any number of dimensions. + +
+To illustrate this approach, consider a 2D cell. In 2 dimensions + the cell is represented by a square. An xy axis is placed at its center, with the + positive x-axis oriented East and the positive y-axis oriented North. + The resulting coordinate for the lower left corner is at , and upper right + corner at . + However, because our staggers are symmetric they don't need to distinguish between + the , and the , so we only need to concern ourselves with the first quadrant of + this cell. We only need to use the , and the , and many of the cell locations + collapse together (e.g. we only need to represent one corner). See figure 18 + for an illustration of these concepts. + +
+
+The cell center is represented by the coordinate pair indicating the origin. + The cell corner is in each direction, giving a coordinate pair of . + The edges are each in one dimension and in the other indicating that + they're even with the center in one dimension and offset in the other. + +
+For three dimensions, the vertical component of the stagger location can be added by + simply adding an additional coordinate. The three dimensional generalization of the + cell center becomes and the cell corner becomes . The rest of + the 3D stagger locations are combinations of offsets from the center. + +
+To generalize this to dimensions, to represent a dimensional stagger + location. A set of and is used to specify for each dimension + whether a stagger location is aligned with the cell center in that dimension (), + or offset by in that dimension (). Using this scheme we can represent + any symmetric stagger location. + +
+To construct a custom stagger location in ESMF the subroutine + ESMF_StaggerLocSet() is used to specify, + for each dimension, whether the stagger is located at the interior (0) + or on the boundary (1) of the cell. This method allows users + to construct stagger locations for which + there is no predefined value. In this example, it's used to + set the 4D center and 4D corner locations. + +
+
+ ! Set Center + call ESMF_StaggerLocSet(staggerLoc,loc=(/0,0,0,0/),rc=rc) ++ +
+
+ call ESMF_GridAddCoord(grid4D, staggerLoc=staggerLoc, rc=rc) ++ +
+
+ ! Set Corner + call ESMF_StaggerLocSet(staggerLoc,loc=(/1,1,1,1/),rc=rc) ++ +
+
+ call ESMF_GridAddCoord(grid4D, staggerLoc=staggerLoc, rc=rc) ++ +
+ +
+There is an added complication with the data (e.g. coordinates) stored at stagger locations in + that they can require different amounts of storage depending + on the underlying Grid type. + +
+
+Consider the example 2D grid in figure 19, where the dots represent the cell corners + and the “+” represents the cell centers. For the corners to completely + enclose the cell centers (symmetric stagger), the number of corners in each + dimension needs to be one greater then the number of cell centers. In the above + figure, there are two rows and three columns of cell centers. To enclose the + cell centers, there must be three rows and four columns of cell corners. + This is true in general for Grids without periodicity or + other connections. In fact, for a symmetric stagger, given that the center + location requires n x m storage, the corresponding corner location + requires n+1 x m+1, and the edges, depending on the side, require n+1 x m or + m+1 x n. In order to add the extra storage, a new DistGrid is + created at each stagger location. This Distgrid is similar to the DistGrid + used to create the Grid, but has an extra set of elements added to hold the + index locations for the stagger padding. + By default, when the coordinate arrays are created, one extra + layer of padding is added to the index space to create symmetric staggers + (i.e. the center location is surrounded). The default is to add this padding + on the positive side, and to only add this padding where needed + (e.g. no padding for the center, padding + on both dimensions for the corner, in only one dimension for the + edge in 2D.) There are two ways for the user to change + these defaults. + +
+One way is to use the GridEdgeWidth or GridAlign arguments + when creating a Grid. These arguments can be used to change the default padding + around the Grid cell index space. This extra padding is used by default + when setting the padding for a stagger location. + +
+The gridEdgeLWidth and + gridEdgeUWidth arguments are both 1D arrays of the + same size as the Grid dimension. The entries in the arrays + give the extra offset from the outer boundary of + the grid cell index space. The following example shows the + creation of a Grid with all the extra space to hold stagger padding + on the negative side of a Grid. This is the reverse of + the default behavior. The resulting Grid will have + an exclusive region which extends from to + , however, the cell center stagger location + will still extend from to . +
+
+ grid2D=ESMF_GridCreateNoPeriDim(minIndex=(/1,1/),maxIndex=(/10,10/), & + gridEdgeLWidth=(/1,1/), gridEdgeUWidth=(/0,0/), rc=rc) ++ +
+To indicate how the data in a Grid's stagger locations are aligned with the + cell centers, the optional gridAlign parameter + may be used. This parameter indicates which stagger elements + in a cell share the same index values as the cell center. + For example, in a 2D cell, it would indicate which of the four corners has + the same index value as the center. To set gridAlign, + the values -1,+1 are used to indicate the alignment in + each dimension. This parameter is mostly + informational, however, if the gridEdgeWidth parameters + are not set then its value determines where the default padding + is placed. If not specified, then the default is to align all + staggers to the most negative, so the padding is on the positive side. + The following code illustrates creating a Grid aligned to the reverse of + default (with everything to the positive side). This creates a + Grid identical to that created in the previous example. +
+
+ grid2D=ESMF_GridCreateNoPeriDim(minIndex=(/1,1/),maxIndex=(/10,10/), & + gridAlign=(/1,1/), rc=rc) ++ +
+The gridEdgeWidth and gridAlign arguments both + allow the user to set the default padding to be used + by stagger locations in a Grid. By default, stagger locations + allocated in a Grid set their stagger padding based on these + values. A stagger location's padding in each dimension is + equal to the value of gridEdgeWidth (or the value implied + by gridAlign), unless the stagger location is centered + in a dimension in which case the stagger padding is 0. For example, + the cell center stagger location has 0 stagger padding in all + dimensions, whereas the edge stagger location lower padding + is equal to gridEdgeLWidth and the upper padding is equal + to gridEdgeUWidth in one dimension, but both are 0 in the other, + centered, dimension. If the user wishes to set the stagger padding + individually for each stagger location they may use the + staggerEdgeWidth and staggerAlign arguments. + +
+The staggerEdgeLWidth and + staggerEdgeUWidth arguments are both 1D arrays of the + same size as the Grid dimension. The entries in the arrays + give the extra offset from the Grid cell index space + for a stagger location. The following example shows the + addition of two stagger locations. The + corner location has no extra boundary and the + center has a single layer of extra padding on + the negative side and none on the positive. This is the reverse of + the default behavior. +
+
+ grid2D=ESMF_GridCreate(distgrid=distgrid2D, & + gridEdgeLWidth=(/1,1/), gridEdgeUWidth=(/0,0/), rc=rc) ++ +
+
+ call ESMF_GridAddCoord(grid2D, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + staggerEdgeLWidth=(/0,0/), staggerEdgeUWidth=(/0,0/), rc=rc) ++ +
+
+ call ESMF_GridAddCoord(grid2D, & + staggerLoc=ESMF_STAGGERLOC_CENTER, & + staggerEdgeLWidth=(/1,1/), staggerEdgeUWidth=(/0,0/), rc=rc) ++ +
+To indicate how the data at a particular stagger location is aligned with the + cell center, the optional staggerAlign parameter + may be used. This parameter indicates which stagger elements + in a cell share the same index values as the cell center. + For example, in a 2D cell, it would indicate which of the four corners has + the same index value as the center. To set staggerAlign, + the values -1,+1 are used to indicate the alignment in + each dimension. If a stagger location is + centered in a dimension (e.g. an edge in 2D), then that + dimension is ignored in the alignment. This parameter is mostly + informational, however, if the staggerEdgeWidth parameters + are not set then its value determines where the default padding + is placed. If not specified, then the default is to align all + staggers to the most negative, so the padding is on the positive side. + The following code illustrates aligning the positive (northeast in 2D) + corner with the center. +
+
+ call ESMF_GridAddCoord(grid2D, & + staggerLoc=ESMF_STAGGERLOC_CORNER, staggerAlign=(/1,1/), rc=rc) ++ +
+ + +
+ +
+
+
+
+
+ +
+The ESMF_Grid class depends upon the ESMF_DistGrid class +for the specification of its topology. That is, when +creating a Grid, first an ESMF_DistGrid is created to describe the +appropriate index space topology. This decision was +made because it seemed redundant to have a system for doing this +in both classes. It also seems most appropriate for +the machinary for topology creation to be located at the lowest +level possible so that it can be used by other +classes (e.g. the ESMF_Array class). Because of this, however, +the authors recommend that as a natural part of the +implementation of subroutines to generate standard grid shapes +(e.g. ESMF_GridGenSphere) a set of standard +topology generation subroutines be implemented (e.g. ESMF_DistGridGenSphere) for users who want to create a standard topology, but a custom geometry. + +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + grid1 = grid2 +ARGUMENTS: +
type(ESMF_Grid) :: grid1 + type(ESMF_Grid) :: grid2 ++STATUS: + +
+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: +
+ +
+ +
+ +
+
+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: + +
+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 + must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+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: + +
+DESCRIPTION:
+
+
+
+Test whether grid1 and grid2 are 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: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridAddCoord() + subroutine ESMF_GridAddCoordNoValues(grid, staggerloc, & + staggerEdgeLWidth, staggerEdgeUWidth, staggerAlign, & + staggerLBound,rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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: + +
+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 staggerEdgeLWidth, etc. allow the user to adjust the + padding on the coordinate arrays. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridAddItem() + subroutine ESMF_GridAddItemNoValues(grid, itemflag, & + staggerloc, itemTypeKind, staggerEdgeLWidth, staggerEdgeUWidth, & + staggerAlign, staggerLBound,rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + type (ESMF_GridItem_Flag),intent(in) :: itemflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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: + +
+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 staggerEdgeLWidth, etc. allow the user to adjust the + padding on the item array. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate() + function ESMF_GridCreateCopyFromNewDG(grid, distgrid, & + name, copyAttributes, routehandle, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateCopyFromNewDG +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + type(ESMF_DistGrid), intent(in) :: distgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len=*), intent(in), optional :: name + logical, intent(in), optional :: copyAttributes + type(ESMF_RouteHandle),intent(out), optional :: routehandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This call allows the user to copy an existing ESMF Grid, but with a new distribution. + All internal data from the old Grid (coords, items) are redistributed to the new Grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate() + function ESMF_GridCreateCopyFromReg(grid, & + regDecomp, decompFlag, name, copyAttributes, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateCopyFromReg +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: regDecomp(:) + type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) + character (len=*), intent(in), optional :: name + logical, intent(in), optional :: copyAttributes + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This method creates a copy of an existing Grid, the new Grid is + regularly distributed (see Figure 13). + To specify the new distribution, the user passes in an array + (regDecomp) specifying the number of DEs to divide each + dimension into. The array decompFlag indicates how the division into DEs is to + occur. The default is to divide the range as evenly as possible. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate() + function ESMF_GridCreateEdgeConnI(minIndex, & + countsPerDEDim1,countsPerDeDim2, & + 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(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 13). + 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. Currently this call only + supports creating 2D or 3D Grids. A 2D Grid can be specified using the + countsPerDEDim1 and countsPerDEDim2 arguments. A 3D Grid can + be specified by also using the optional countsPerDEDim3 argument. + The index of each array element in these arguments corresponds to + a DE number. The array value at the index is the number of grid + cells on the DE in that dimension. + +
+Section 31.3.4 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: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate() + function ESMF_GridCreateEdgeConnR(regDecomp, decompFlag, & + minIndex, maxIndex, & + 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(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 13). + To specify the distribution, the user passes in an array + (regDecomp) specifying the number of DEs to divide each + dimension into. The array decompFlag indicates how the division into DEs is to + occur. The default is to divide the range as evenly as possible. Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate() + function ESMF_GridCreateEdgeConnA(minIndex, maxIndex, & + arbIndexCount, arbIndexList, & + 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(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 13). + 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 localArbIndexCount and the second dimension is the number of distributed + dimensions. + +
+distDim specifies which grid dimensions are arbitrarily distributed. The + size of distDim has to agree with the size of the second dimension of + localArbIndex. + +
+Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate() + function ESMF_GridCreateFrmDistGrid(distgrid, & + distgridToGridMap, & + coordSys, coordTypeKind, coordDimCount, coordDimMap, & + gridEdgeLWidth, gridEdgeUWidth, gridAlign, & + gridMemLBound, indexflag, name, vm, 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 + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This is the most general form of creation for an 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 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 + distgrid. The distgridToGridMap argument + specifies how the Grid dimensions are mapped to the distgrid. + The coordDimCount and 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 ESMF_GridAddCoord() must be called + before adding coordinate values.) + +
+The arguments are: +
+ +
+ +
+ +
+
+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 arbitrarily distributed 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 distgrid. The indexArray(2,dimCount), + argument is required to specifies the topology of the grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate() + function ESMF_GridCreateFrmNCFileDG(filename, fileformat, distgrid, & + isSphere, polekindflag, addCornerStagger, coordTypeKind, addUserArea, indexflag, & + addMask, varname, coordNames, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateFrmNCFileDG +ARGUMENTS: +
+ character(len=*), intent(in) :: filename + type(ESMF_FileFormat_Flag), intent(in), optional :: fileformat + type(ESMF_DistGrid), intent(in) :: distgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: isSphere + type(ESMF_PoleKind_Flag), intent(in), optional :: polekindflag(2) + logical, intent(in), optional :: addCornerStagger + type(ESMF_TypeKind_Flag),intent(in), optional :: coordTypeKind + logical, intent(in), optional :: addUserArea + type(ESMF_Index_Flag), intent(in), optional :: indexflag + logical, intent(in), optional :: addMask + character(len=*), intent(in), optional :: varname + character(len=*), intent(in), optional :: coordNames(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This function creates a ESMF_Grid object using the grid definition from + a grid file in NetCDF that is either in the SCRIP format or in the CF convention. + To specify the distribution, the user passes in a distGrid. + The grid defined in the file has to be a 2D logically rectangular grid. + This function first call ESMF_GridCreateFrmNCFile() to create a ESMF_Grid + object using a pre-calculated block distribution, then redistribute the Grid to + create a new Grid object using the user specified distGrid. + +
+This call is collective across the current VM. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate() + function ESMF_GridCreateFrmNCFile(filename, fileformat, regDecomp, & + decompflag, delayout, isSphere, polekindflag, addCornerStagger, coordTypeKind, & + addUserArea, indexflag, addMask, varname, coordNames, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateFrmNCFile +ARGUMENTS: +
+ character(len=*), intent(in) :: filename + type(ESMF_FileFormat_Flag), intent(in), optional :: fileformat + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: regDecomp(:) + type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) + type(ESMF_DELayout), intent(in), optional :: delayout + logical, intent(in), optional :: isSphere + type(ESMF_PoleKind_Flag), intent(in), optional :: polekindflag(2) + logical, intent(in), optional :: addCornerStagger + type(ESMF_TypeKind_Flag),intent(in), optional :: coordTypeKind + logical, intent(in), optional :: addUserArea + type(ESMF_Index_Flag), intent(in), optional :: indexflag + logical, intent(in), optional :: addMask + character(len=*), intent(in), optional :: varname + character(len=*), intent(in), optional :: coordNames(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This function creates a ESMF_Grid object using the grid definition from + a grid file in NetCDF that is either in the SCRIP format or in the CF convention. + To specify the distribution, the user passes in an array + (regDecomp) specifying the number of DEs to divide each + dimension into. The array decompflag indicates how the division into DEs is to + occur. The default is to divide the range as evenly as possible. + The grid defined in the file has to be a 2D logically rectangular + grid. + +
+This call is collective across the current VM. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate1PeriDim() + function ESMF_GridCreate1PeriDimI(minIndex, & + countsPerDEDim1,countsPerDeDim2, & + countsPerDEDim3, & + polekindflag, periodicDim, poleDim, & + coordSys, coordTypeKind, & + coordDep1, coordDep2, coordDep3, & + gridEdgeLWidth, gridEdgeUWidth, gridAlign, & + gridMemLBound, indexflag, petMap, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreate1PeriDimI +ARGUMENTS: +
integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: countsPerDEDim1(:) + integer, intent(in) :: countsPerDEDim2(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: countsPerDEDim3(:) + type(ESMF_PoleKind_Flag), intent(in), optional :: polekindflag(2) + integer, intent(in), optional :: periodicDim + integer, intent(in), optional :: poleDim + 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 13) with one 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. Currently this call only + supports creating 2D or 3D Grids. A 2D Grid can be specified using the + countsPerDEDim1 and countsPerDEDim2 arguments. A 3D Grid can + be specified by also using the optional countsPerDEDim3 argument. + The index of each array element in these arguments corresponds to + a DE number. The array value at the index is the number of grid + cells on the DE in that dimension. + +
+Section 31.3.4 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: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate1PeriDim() + function ESMF_GridCreate1PeriDimR(regDecomp, decompFlag, & + minIndex, maxIndex, & + polekindflag, periodicDim, poleDim, & + coordSys, coordTypeKind, & + coordDep1, coordDep2, coordDep3, & + gridEdgeLWidth, gridEdgeUWidth, gridAlign, & + gridMemLBound, indexflag, petMap, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreate1PeriDimR +ARGUMENTS: +
integer, intent(in), optional :: regDecomp(:) + type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) + integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: maxIndex(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_PoleKind_Flag), intent(in), optional :: polekindflag(2) + integer, intent(in), optional :: periodicDim + integer, intent(in), optional :: poleDim + 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 13) with one periodic dimension. + To specify the distribution, the user passes in an array + (regDecomp) specifying the number of DEs to divide each + dimension into. The array decompFlag indicates how the division into DEs is to + occur. The default is to divide the range as evenly as possible. Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate1PeriDim() + function ESMF_GridCreate1PeriDimA(minIndex, maxIndex, & + arbIndexCount, arbIndexList, & + polekindflag, periodicDim, poleDim, & + coordSys, coordTypeKind, & + coordDep1, coordDep2, coordDep3, & + distDim, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreate1PeriDimA +ARGUMENTS: +
integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: maxIndex(:) + integer, intent(in) :: arbIndexCount + integer, intent(in) :: arbIndexList(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_PoleKind_Flag), intent(in), optional :: polekindflag(2) + integer, intent(in), optional :: periodicDim + integer, intent(in), optional :: poleDim + 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 13) with one periodic dimension. + 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 localArbIndexCount and the second dimension is the number of distributed + dimensions. + +
+distDim specifies which grid dimensions are arbitrarily distributed. The + size of distDim has to agree with the size of the second dimension of + localArbIndex. + +
+Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate2PeriDim() + function ESMF_GridCreate2PeriDimI(minIndex, & + countsPerDEDim1,countsPerDeDim2, & + countsPerDEDim3, & + coordSys, coordTypeKind, & + coordDep1, coordDep2, coordDep3, & + gridEdgeLWidth, gridEdgeUWidth, gridAlign, & + gridMemLBound, indexflag, petMap, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreate2PeriDimI +ARGUMENTS: +
integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: countsPerDEDim1(:) + integer, intent(in) :: countsPerDEDim2(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: countsPerDEDim3(:) + 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 13) with two periodic dimensions. + 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. Currently this call only + supports creating 2D or 3D Grids. A 2D Grid can be specified using the + countsPerDEDim1 and countsPerDEDim2 arguments. A 3D Grid can + be specified by also using the optional countsPerDEDim3 argument. + The index of each array element in these arguments corresponds to + a DE number. The array value at the index is the number of grid + ! cells on the DE in that dimension. + +
+Section 31.3.4 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: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate2PeriDim() + function ESMF_GridCreate2PeriDimR(regDecomp, decompFlag, & + minIndex, maxIndex, & + coordSys, coordTypeKind, & + coordDep1, coordDep2, coordDep3, & + gridEdgeLWidth, gridEdgeUWidth, gridAlign, & + gridMemLBound, indexflag, petMap, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreate2PeriDimR +ARGUMENTS: +
integer, intent(in), optional :: regDecomp(:) + type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) + integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: maxIndex(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 13) with two periodic dimensions. + To specify the distribution, the user passes in an array + (regDecomp) specifying the number of DEs to divide each + dimension into. The array decompFlag indicates how the division into DEs is to + occur. The default is to divide the range as evenly as possible. Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate2PeriDim() + function ESMF_GridCreate2PeriDimA(minIndex, maxIndex, & + arbIndexCount, arbIndexList, & + coordSys, coordTypeKind, & + coordDep1, coordDep2, coordDep3, & + distDim, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreate2PeriDimA +ARGUMENTS: +
integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: maxIndex(:) + integer, intent(in) :: arbIndexCount + integer, intent(in) :: arbIndexList(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 13) with two periodic dimensions. + 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 localArbIndexCount and the second dimension is the number of distributed + dimensions. + +
+distDim specifies which grid dimensions are arbitrarily distributed. The + size of distDim has to agree with the size of the second dimension of + localArbIndex. + +
+Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreateNoPeriDim() + function ESMF_GridCreateNoPeriDimI(minIndex, & + countsPerDEDim1,countsPerDeDim2, & + countsPerDEDim3, & + coordSys, coordTypeKind, & + coordDep1, coordDep2, coordDep3, & + gridEdgeLWidth, gridEdgeUWidth, gridAlign, & + gridMemLBound, indexflag, petMap, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateNoPeriDimI +ARGUMENTS: +
integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: countsPerDEDim1(:) + integer, intent(in) :: countsPerDEDim2(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: countsPerDEDim3(:) + 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 13) 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. Currently this call only + supports creating 2D or 3D Grids. A 2D Grid can be specified using the + countsPerDEDim1 and countsPerDEDim2 arguments. A 3D Grid can + be specified by also using the optional countsPerDEDim3 argument. + The index of each array element in these arguments corresponds to + a DE number. The array value at the index is the number of grid + cells on the DE in that dimension. + +
+Section 31.3.4 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: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreateNoPeriDim() + function ESMF_GridCreateNoPeriDimR(regDecomp, decompFlag, & + minIndex, maxIndex, & + coordSys, coordTypeKind, & + coordDep1, coordDep2, coordDep3, & + gridEdgeLWidth, gridEdgeUWidth, gridAlign, & + gridMemLBound, indexflag, petMap, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateNoPeriDimR +ARGUMENTS: +
integer, intent(in), optional :: regDecomp(:) + type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) + integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: maxIndex(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 13) with no periodic dimension. + To specify the distribution, the user passes in an array + (regDecomp) specifying the number of DEs to divide each + dimension into. The array decompFlag indicates how the division into DEs is to + occur. The default is to divide the range as evenly as possible. Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreateNoPeriodic() + function ESMF_GridCreateNoPeriDimA(minIndex, maxIndex, & + arbIndexCount, arbIndexList, & + coordSys, coordTypeKind, & + coordDep1, coordDep2, coordDep3, & + distDim, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateNoPeriDimA +ARGUMENTS: +
integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: maxIndex(:) + integer, intent(in) :: arbIndexCount + integer, intent(in) :: arbIndexList(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 13) with no periodic dimension. + 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 localArbIndexCount and the second dimension is the number of distributed + dimensions. + +
+distDim specifies which grid dimensions are arbitrarily distributed. The + size of distDim has to agree with the size of the second dimension of + localArbIndex. + +
+Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate1PeriDimUfrm() + function ESMF_GridCreate1PeriDimUfrmR(minIndex, maxIndex, & + minCornerCoord, maxCornerCoord, & + regDecomp, decompFlag, & + polekindflag, coordSys, staggerLocList, & + ignoreNonPeriCoord, petMap, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreate1PeriDimUfrmR +ARGUMENTS: +
integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: maxIndex(:) + real(ESMF_KIND_R8), intent(in) :: minCornerCoord(:) + real(ESMF_KIND_R8), intent(in) :: maxCornerCoord(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: regDecomp(:) + type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) + type(ESMF_PoleKind_Flag), intent(in), optional :: polekindflag(2) + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + type(ESMF_StaggerLoc), intent(in), optional :: staggerLocList(:) + logical, intent(in), optional :: ignoreNonPeriCoord + 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 13) with one periodic dimension. + The periodic dimension in the resulting grid will be dimension 1. + The dimension with the poles at either end (i.e. the pole dimension) + will be dimension 2. + +
+The grid will have its coordinates uniformly spread between the + ranges specified by the user. The coordinates are ESMF_TYPEKIND_R8. + Currently, this method only fills the center stagger with coordinates, and + the minCornerCoord and maxCornerCoord arguments give the boundaries of + the center stagger. + +
+To specify the distribution, the user passes in an array + (regDecomp) specifying the number of DEs to divide each + dimension into. The array decompFlag indicates how the division into DEs is to + occur. The default is to divide the range as evenly as possible. Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+The following arguments have been set to non-typical values and so + there is a reasonable possibility that they may change in the future + to be inconsistent with other Grid create interfaces: + +
+The arguments coordDep1, coordDep2, and coordDep3 have internally + been set to 1, 2, and 3 respectively. + This was done because this call creates a uniform grid and so only 1D arrays + are needed to hold the coordinates. This means the coordinate arrays + will be 1D. + +
+The argument indexFlag has internally been set to ESMF_INDEX_GLOBAL. This + means that the grid created from this function will have a global index space. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreate1PeriDimUfrm() + function ESMF_GridCreate1PeriDimUfrmB(minIndex, maxIndex, & + minCornerCoord, maxCornerCoord, & + deBlockList, deLabelList, & + polekindflag, coordSys, staggerLocList, & + ignoreNonPeriCoord, petMap, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreate1PeriDimUfrmB +ARGUMENTS: +
integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: maxIndex(:) + real(ESMF_KIND_R8), intent(in) :: minCornerCoord(:) + real(ESMF_KIND_R8), intent(in) :: maxCornerCoord(:) + integer, intent(in) :: deBlockList(:,:,:) + integer, intent(in), optional :: deLabelList(:) + type(ESMF_PoleKind_Flag), intent(in), optional :: polekindflag(2) + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + type(ESMF_StaggerLoc), intent(in), optional :: staggerLocList(:) + logical, intent(in), optional :: ignoreNonPeriCoord + 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 13) with one periodic dimension. + The periodic dimension in the resulting grid will be dimension 1. + The dimension with the poles at either end (i.e. the pole dimension) + will be dimension 2. + +
+The grid will have its coordinates uniformly spread between the + ranges specified by the user. The coordinates are ESMF_TYPEKIND_R8. + Currently, this method only fills the center stagger with coordinates, and + the minCornerCoord and maxCornerCoord arguments give the boundaries of + the center stagger. + +
+To specify the distribution, the user passes in an array + (deBlockList) specifying index space blocks for each DE. + +
+The following arguments have been set to non-typical values and so + there is a reasonable possibility that they may change in the future + to be inconsistent with other Grid create interfaces: + +
+The arguements coordDep1, coordDep2, and coordDep3 have internally + been set to 1, 2, and 3 respectively. + This was done because this call creates a uniform grid and so only 1D arrays + are needed to hold the coordinates. This means the coordinate arrays + will be 1D. + +
+The argument indexFlag has internally been set to ESMF_INDEX_GLOBAL. This + means that the grid created from this function will have a global index space. + +
+The arguments are: +
+ +---------------------------------------> 2nd index + | 1 2 + | 1 minIndex(1) maxIndex(1) + | 2 minIndex(2) maxIndex(2) + | . minIndex(.) maxIndex(.) + | . + v + 1st index ++ It is required that there be no overlap between the LR segments + defined by deBlockList. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreateNoPeriDimUfrm() + function ESMF_GridCreateNoPeriDimUfrmR(minIndex, maxIndex, & + minCornerCoord, maxCornerCoord, & + regDecomp, decompFlag, & + coordSys, staggerLocList, petMap, name, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateNoPeriDimUfrmR +ARGUMENTS: +
integer, intent(in), optional :: minIndex(:) + integer, intent(in) :: maxIndex(:) + real(ESMF_KIND_R8), intent(in) :: minCornerCoord(:) + real(ESMF_KIND_R8), intent(in) :: maxCornerCoord(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: regDecomp(:) + type(ESMF_Decomp_Flag), intent(in), optional :: decompflag(:) + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + type(ESMF_StaggerLoc), intent(in), optional :: staggerLocList(:) + 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 13) with no periodic dimension. + +
+The resulting grid will have its coordinates uniformly spread between the + ranges specified by the user. The coordinates are ESMF_TYPEKIND_R8. + Currently, this method only fills the center stagger with coordinates, and + the minCornerCoord and maxCornerCoord arguments give the boundaries of + the center stagger. + +
+To specify the distribution, the user passes in an array + (regDecomp) specifying the number of DEs to divide each + dimension into. The array decompFlag indicates how the division into DEs is to + occur. The default is to divide the range as evenly as possible. Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+The following arguments have been set to non-typical values and so + there is a reasonable possibility that they may change in the future + to be inconsistent with other Grid create interfaces: + +
+The arguements coordDep1, coordDep2, and coordDep3 have internally + been set to 1, 2, and 3 respectively. + This was done because this call creates a uniform grid and so only 1D arrays + are needed to hold the coordinates. This means the coordinate arrays + will be 1D. + +
+The argument indexFlag has internally been set to ESMF_INDEX_GLOBAL. This + means that the grid created from this function will have a global index space. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreateCubedSphere() + function ESMF_GridCreateCubedSphereReg(tileSize,& + regDecompPTile, decompflagPTile, & + coordSys, coordTypeKind, & + deLabelList, staggerLocList, & + delayout, indexflag, name, transformArgs, coordCalcFlag, & + rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateCubedSphereReg +ARGUMENTS: +
integer, intent(in) :: tilesize + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: regDecompPTile(:,:) + type(ESMF_Decomp_Flag), target, intent(in), optional :: decompflagPTile(:,:) + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind + integer, intent(in), optional :: deLabelList(:) + type(ESMF_StaggerLoc), intent(in), optional :: staggerLocList(:) + type(ESMF_DELayout), intent(in), optional :: delayout + type(ESMF_Index_Flag), intent(in), optional :: indexflag + character(len=*), intent(in), optional :: name + type(ESMF_CubedSphereTransform_Args), intent(in), optional :: transformArgs + type(ESMF_CubedSphereCalc_Flag),intent(in), optional :: coordCalcFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a six-tile ESMF_Grid for a Cubed Sphere grid using regular decomposition. Each tile can + have different decomposition. The grid coordinates are generated based on the algorithm used by GEOS-5, + The tile resolution is defined by tileSize. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridCreateCubedSphere() + function ESMF_GridCreateCubedSphereIReg(tileSize, & + countsPerDEDim1PTile, countsPerDEDim2PTile, & + & + coordSys, coordTypeKind, & + deLabelList, staggerLocList, & + delayout, indexflag, name, transformArgs, coordCalcFlag, & + rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateCubedSphereIReg +ARGUMENTS: +
integer, intent(in) :: tilesize + integer, intent(in) :: countsPerDEDim1PTile(:,:) + integer, intent(in) :: countsPerDEDim2PTile(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind + integer, intent(in), optional :: deLabelList(:) + type(ESMF_StaggerLoc), intent(in), optional :: staggerLocList(:) + type(ESMF_DELayout), intent(in), optional :: delayout + type(ESMF_Index_Flag), intent(in), optional :: indexflag + character(len=*), intent(in), optional :: name + type(ESMF_CubedSphereTransform_Args), intent(in), optional :: transformArgs + type(ESMF_CubedSphereCalc_Flag),intent(in), optional :: coordCalcFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a six-tile ESMF_Grid for a Cubed Sphere grid using irregular decomposition. Each tile can + have different decomposition. The grid coordinates are generated based on the algorithm used by GEOS-5, + The tile resolution is defined by tileSize. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
function ESMF_GridCreateMosaicReg(filename,regDecompPTile, decompflagPTile, & + coordTypeKind, deLabelList, staggerLocList, delayout, indexflag, name, tileFilePath, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateMosaicReg +ARGUMENTS: +
character(len=*), intent(in) :: filename + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: regDecompPTile(:,:) + type(ESMF_Decomp_Flag), target, intent(in), optional :: decompflagPTile(:,:) + type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind + integer, intent(in), optional :: deLabelList(:) + type(ESMF_StaggerLoc), intent(in), optional :: staggerLocList(:) + type(ESMF_DELayout), intent(in), optional :: delayout + type(ESMF_Index_Flag), intent(in), optional :: indexflag + character(len=*), intent(in), optional :: name + character(len=*), intent(in), optional :: tileFilePath + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a multiple-tile ESMF_Grid based on the definition from a GRIDSPEC Mosaic file and its associated + tile files using regular decomposition. Each tile can have different decomposition. The tile connections + are defined in a GRIDSPEC format Mosaic file. + And each tile's coordination is defined in a separate NetCDF file. The coordinates defined + in the tile file is so-called "Super Grid". In other words, the dimensions of the coordinate variables are + (2*xdim+1, 2*ydim+1) if (xdim, ydim) is the size of the tile. The Super Grid combines the corner, + the edge and the center coordinates in one big array. A Mosaic file may contain just one tile. If a Mosaic contains + multiple tiles. Each tile is a logically rectangular lat/lon grid. Currently, all the tiles have to be the same size. + We will remove this limitation in the future release. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_GridCreateMosaicIReg(filename, & + countsPerDEDim1PTile, countsPerDEDim2PTile, & + & + coordTypeKind, & + deLabelList, staggerLocList, & + delayout, indexflag, name, tileFilePath, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridCreateMosaicIReg +ARGUMENTS: +
character(len=*), intent(in) :: filename + integer, intent(in) :: countsPerDEDim1PTile(:,:) + integer, intent(in) :: countsPerDEDim2PTile(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_TypeKind_Flag), intent(in), optional :: coordTypeKind + integer, intent(in), optional :: deLabelList(:) + type(ESMF_StaggerLoc), intent(in), optional :: staggerLocList(:) + type(ESMF_DELayout), intent(in), optional :: delayout + type(ESMF_Index_Flag), intent(in), optional :: indexflag + character(len=*), intent(in), optional :: name + character(len=*), intent(in), optional :: tileFilePath + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a multiple-tile ESMF_Grid based on the definition from a GRIDSPEC Mosaic file and its associated + tile files using irregular decomposition. Each tile can have different decomposition. The tile connections + are defined in a GRIDSPEC format Mosaic file. + And each tile's coordination is defined in a separate NetCDF file. The coordinates defined + in the tile file is so-called "Super Grid". In other words, the dimensions of the coordinate variables are + (2*xdim+1, 2*ydim+1) if (xdim, ydim) is the size of the tile. The Super Grid combines the corner, + the edge and the center coordinates in one big array. A Mosaic file may contain just one tile. If a Mosaic contains + multiple tiles. Each tile is a logically rectangular lat/lon grid. Currently, all the tiles have to be the same size. + We will remove this limitation in the future release. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridDestroy(grid, noGarbage, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(inout) :: grid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroys an ESMF_Grid object and related internal structures. + This call does destroy internally created DistGrid and DELayout classes, + for example those created by ESMF_GridCreateShapeTile(). It also + destroys internally created coordinate/item Arrays, for example those + created by ESMF_GridAddCoord(). However, if the user uses an + externally created class, for example creating an Array and setting it + using ESMF_GridSetCoord(), then that class is not destroyed by + this method. + +
+By default a small remnant of the object is kept in memory in order to + prevent problems with dangling aliases. The default garbage collection + mechanism can be overridden with the noGarbage argument. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridEmptyComplete() + subroutine ESMF_GridEmptyCompleteEConnI(grid, minIndex, & + countsPerDEDim1,countsPerDeDim2, & + 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(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 ESMF_GridEmptyCreate(). + It then completes the grid to form a single tile, irregularly distributed grid + (see Figure 13). 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. Currently this call only + supports creating 2D or 3D Grids. A 2D Grid can be specified using the + countsPerDEDim1 and countsPerDEDim2 arguments. A 3D Grid can + be specified by also using the optional countsPerDEDim3 argument. + The index of each array element in these arguments corresponds to + a DE number. The array value at the index is the number of grid + cells on the DE in that dimension. + +
+Section 31.3.4 shows an example + of using an irregular distribution 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 ESMF_GridEmptyComplete() call + should be executed in the same set or a subset of the PETs in which the + 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: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridEmptyComplete() + subroutine ESMF_GridEmptyCompleteEConnR(grid, regDecomp, decompFlag, & + minIndex, maxIndex, & + 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(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 ESMF_GridEmptyCreate(). + It then completes the grid to form a single tile, regularly distributed grid + (see Figure 13). + To specify the distribution, the user passes in an array + (regDecomp) specifying the number of DEs to divide each + dimension into. The array decompFlag indicates how the division into DEs is to + occur. The default is to divide the range as evenly as possible. Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+For consistency's sake the ESMF_GridEmptyComplete() call + should be executed in the same set or a subset of the PETs in which the + 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: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridEmptyComplete() + subroutine ESMF_GridEmptyCompleteEConnA(grid, minIndex, maxIndex, & + arbIndexCount, arbIndexList, & + 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(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 ESMF_GridEmptyCreate(). + It then completes the grid to form a single tile, arbitrarily distributed grid + (see Figure 13). + 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 localArbIndexCount and the second dimension is the number of distributed + dimensions. + +
+distDim specifies which grid dimensions are arbitrarily distributed. The + size of distDim has to agree with the size of the second dimension of + localArbIndex. + +
+Currently this call + only supports creating a 2D or 3D Grid, and thus, for example, maxIndex must be of size 2 or 3. + +
+For consistency's sake the ESMF_GridEmptyComplete() call + should be executed in the same set or a subset of the PETs in which the + 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: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_GridEmptyCreate(vm, rc) +RETURN VALUE: +
type(ESMF_Grid) :: ESMF_GridEmptyCreate +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Partially create an ESMF_Grid object. This function allocates + an ESMF_Grid object, but doesn't allocate any coordinate storage or other + internal structures. The ESMF_GridEmptyComplete() calls + can be used to set the values in the grid object and to construct the + internal structure. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridGet() + subroutine ESMF_GridGetDefault(grid, coordTypeKind, & + dimCount, tileCount, staggerlocCount, localDECount, distgrid, & + distgridToGridMap, coordSys, coordDimCount, coordDimMap, arbDim, & + rank, arbDimCount, gridEdgeLWidth, gridEdgeUWidth, gridAlign, & + indexFlag, status, name, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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(:) + type(ESMF_CoordSys_Flag), intent(out), optional :: coordSys + 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: + +
+DESCRIPTION:
+
+
+
+Gets various types of information about a grid. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridGet() + subroutine ESMF_GridGetPLocalDe(grid, localDE, & + isLBound,isUBound, arbIndexCount, arbIndexList, tile, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + integer, intent(in) :: localDE + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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 :: tile + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This call gets information about a particular local DE in a Grid. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridGet() + subroutine ESMF_GridGetPLocalDePSloc(grid, staggerloc, localDE, & + exclusiveLBound, exclusiveUBound, exclusiveCount, & + computationalLBound, computationalUBound, computationalCount, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + type (ESMF_StaggerLoc), intent(in) :: staggerloc + integer, intent(in) :: localDE + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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: + +
+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. 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 ESMF_GridAddCoord hasn't yet + been called on the stagger location). + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridGet() + subroutine ESMF_GridGetPSloc(grid, staggerloc, & + distgrid, & + staggerEdgeLWidth, staggerEdgeUWidth, & + staggerAlign, staggerLBound, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + type (ESMF_StaggerLoc), intent(in) :: staggerloc + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DistGrid), intent(out), optional :: distgrid + integer, intent(out), optional :: staggerEdgeLWidth(:) + integer, intent(out), optional :: staggerEdgeUWidth(:) + integer, intent(out), optional :: staggerAlign(:) + integer, intent(out), optional :: staggerLBound(:) + integer, intent(out), optional :: rc ++STATUS: + +
+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: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridGet() + subroutine ESMF_GridGetPSlocPTile(grid, tile, staggerloc, & + minIndex, maxIndex, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + integer, intent(in) :: tile + type (ESMF_StaggerLoc), intent(in) :: staggerloc + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, target, intent(out), optional :: minIndex(:) + integer, target, intent(out), optional :: maxIndex(:) + integer, intent(out), optional :: rc ++STATUS: + +
+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: +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridGetCoord<rank><type><kind>(grid, coordDim, & + staggerloc, localDE, farrayPtr, datacopyflag, & + exclusiveLBound, exclusiveUBound, exclusiveCount, & + computationalLBound, computationalUBound, computationalCount, & + totalLBound, totalUBound, totalCount, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + integer, intent(in) :: coordDim + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type (ESMF_StaggerLoc) intent(in), optional :: staggerloc + integer, intent(in), optional :: localDE + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + 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(:) + integer, intent(out), optional :: rc ++STATUS: + +
+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 ESMF_GetCoord() interface that returns coordinate + values in an ESMF_Array instead. That interface supports the retrieval of + coordinates up to 7D. + +
+Supported values for the farrayPtr argument are: +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridGetCoord() + subroutine ESMF_GridGetCoordIntoArray(grid, coordDim, staggerloc, & + array, 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 + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+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 ESMF_GridAddCoord or + ESMF_GridSetCoord. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridGetCoord() + subroutine ESMF_GridGetCoordR4(grid, staggerloc, localDE, & + index, coord, 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(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Given a specific index location in a Grid, this method returns the full set + of coordinates from that index location. This method should work no matter what + the factorization of the Grid's coordinate components. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridGetCoord() + subroutine ESMF_GridGetCoordR8(grid, staggerloc, localDE, & + index, coord, 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(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Given a specific index location in a Grid, this method returns the full set + of coordinates from that index location. This method should work no matter what + the factorization of the Grid's coordinate components. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridGetCoord() + subroutine ESMF_GridGetCoordInfo(grid, & + staggerloc, isPresent, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type (ESMF_StaggerLoc), intent(in), optional :: staggerloc + logical, intent(out), optional :: isPresent + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This method allows the user to get information about the coordinates on a given + stagger. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridGetCoordBounds(grid, coordDim, & + staggerloc, localDE, exclusiveLBound, exclusiveUBound, & + exclusiveCount, computationalLBound, computationalUBound , & + computationalCount, totalLBound, totalUBound, totalCount, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + integer, intent(in) :: coordDim + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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: + +
+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, + totalLBound and totalUBound should match the bounds of the Fortran array + retrieved by ESMF_GridGetCoord. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridGetItem<rank><type><kind>(grid, itemflag, & + staggerloc, localDE, farrayPtr, datacopyflag, & + exclusiveLBound, exclusiveUBound, exclusiveCount, & + computationalLBound, computationalUBound, computationalCount, & + totalLBound, totalUBound, totalCount, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + type (ESMF_GridItem_Flag),intent(in) :: itemflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type (ESMF_StaggerLoc), intent(in), optional :: staggerloc + integer, intent(in), optional :: localDE + <type> (ESMF_KIND_<kind>), pointer :: farrayPtr(<rank>) + type(ESMF_DataCopy_Flag),intent(in), optional :: datacopyflag + 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(:) + integer, intent(out), optional :: rc ++STATUS: + +
+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 ESMF_GetItem() interface that returns coordinate + values in an ESMF_Array instead. That interface supports the retrieval of + coordinates up to 7D. + +
+Supported values for the farrayPtr argument are: +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridGetItem() + subroutine ESMF_GridGetItemIntoArray(grid, itemflag, staggerloc, & + array, 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 + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+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 ESMF_GridAddItem or + ESMF_GridSetItem. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridGetItem() + subroutine ESMF_GridGetItemInfo(grid, itemflag, & + staggerloc, isPresent, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + type (ESMF_GridItem_Flag), intent(in) :: itemflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type (ESMF_StaggerLoc), intent(in), optional :: staggerloc + logical, intent(out), optional :: isPresent + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This method allows the user to get information about a given item on a given + stagger. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridGetItemBounds(grid, itemflag, & + 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 + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + 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: + +
+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, + totalLBound and totalUBound should match the bounds of the Fortran array + retrieved by ESMF_GridGetItem. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_GridIsCreated(grid, rc) +RETURN VALUE: +
logical :: ESMF_GridIsCreated +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the grid has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_GridMatch(grid1, grid2, globalflag, rc) +RETURN VALUE: +
type(ESMF_GridMatch_Flag) :: ESMF_GridMatch +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid1 + type(ESMF_Grid), intent(in) :: grid2 + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: globalflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Check if grid1 and 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 31.2.3. + Please also note that by default this call is not collective and only + returns the match for the piece of the Grids on the local PET. In this case, + it is possible for this call to return a different match on different PETs + for the same Grids. To do a global match operation set the globalflag + argument to .true.. In this case, the call becomes collective across the + current VM, ensuring the same result is returned on all PETs. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridRedist(srcGrid, dstGrid, routehandle, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: srcGrid + type(ESMF_Grid), intent(inout) :: dstGrid + type(ESMF_RouteHandle),intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call is companion to the ESMF_GridCreate() that allows the user to copy an + existing ESMF Grid, but with a new distribution. The ESMF_GridRedist() allows + the user to repeatedly redistribute the coordinates from srcGrid to dstGrid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridSetCoordFromArray(grid, coordDim, staggerloc, & + array, 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 + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This method sets the passed in Array as the holder of the coordinate + data for stagger location staggerloc and coordinate coord. This method + can be used in place of ESMF_GridAddCoord(). In fact, if the Grid + location already contains an Array for this coordinate, then this one + replaces it. For this method to replace ESMF_GridAddCoord() and produce + a valid set of coordinates, then this method must be used to set + an Array for each coordDim ranging from 1 to the dimCount of the passed in Grid. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GridSetItem() + subroutine ESMF_GridSetItemFromArray(grid, itemflag, staggerloc, & + array, 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 + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This method sets the passed in Array as the holder of the item data + for stagger location staggerloc and item itemflag. If the location + already contains an Array, then this one overwrites it. This method can + be used as a replacement for ESMF_GridAddItem(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GridValidate(grid, rc) +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Validates that the 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 + ESMF_GRIDSTATUS_COMPLETE. This means that + if a Grid was created with the ESMF_GridEmptyCreate + method, it must also have been finished with + 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: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_StaggerLocGet() + subroutine ESMF_StaggerLocGetDim(staggerloc, dim, loc, & + rc) +ARGUMENTS: +
type (ESMF_StaggerLoc), intent(in) :: staggerloc + integer, intent(in) :: dim + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, optional, intent(out) :: loc + integer, optional :: rc ++DESCRIPTION: +
+Gets the position of a particular dimension of a cell staggerloc + The argument loc will be only be 0,1. + If loc is 0 it means the position + should be in the center in that dimension. If loc is +1 then + for the dimension, the position should be on the positive side of the cell. + Please see Section 31.3.25 for diagrams. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_StaggerLocSet() + subroutine ESMF_StaggerLocSetAllDim(staggerloc, loc, rc) +ARGUMENTS: +
type (ESMF_StaggerLoc), intent(inout) :: staggerloc + integer, intent(in) :: loc(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets a custom staggerloc to a position in a cell by using the array + 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 31.3.25 + for diagrams and further discussion of custom stagger locations. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_StaggerLocSet() + subroutine ESMF_StaggerLocSetDim(staggerloc, dim, loc, & + rc) +ARGUMENTS: +
type (ESMF_StaggerLoc), intent(inout) :: staggerloc + integer, intent(in) :: dim + integer, intent(in) :: loc + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets a particular dimension of a custom staggerloc to a position in a cell + by using the variable loc. The variable loc should only be 0,1. + If loc is 0 it means the position + should be in the center in that dimension. If loc is +1 then + for the dimension, the position should be on the positive side of the cell. + Please see Section 31.3.25 + for diagrams and further discussion of custom stagger locations. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_StaggerLocString(staggerloc, string, & + rc) +ARGUMENTS: +
type(ESMF_StaggerLoc), intent(in) :: staggerloc + character (len = *), intent(out) :: string + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, optional, intent(out) :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Return an ESMF_StaggerLoc as a printable string. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_StaggerLocPrint(staggerloc, rc) +ARGUMENTS: +
type (ESMF_StaggerLoc), intent(in) :: staggerloc + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, optional, intent(out) :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Print the internal data members of an ESMF_StaggerLoc object.
+
+
+The arguments are: +
+ + +
+A location stream (LocStream) can be used to represent the locations of +a set of data points. For example, in the data assimilation world, +LocStreams can be used to represent a set of observations. The values +of the data points are stored within a Field or FieldBundle created +using the LocStream. + +
+The locations are generally described using Cartesian (x, y, z), or +(lat, lon, radius) coordinates. The coordinates are stored using +constructs called keys. A Key is essentially a list of point +descriptors, one for each data point. They may hold other information +besides the coordinates - a mask, for example. They may also hold a +second set of coordinates. Keys are referenced by name - see +32.2.1 and 32.2.2 for specific +keynames required in regridding. Each key must contain the same +number of elements as there are data points in the LocStream. While +there is no assumption in the ordering of the points, the order +chosen must be maintained in each of the keys. + +
+LocStreams can be very large. Data assimilation systems might use +LocStreams with up to observations, so efficiency is critical. +LocStreams can be created from file, see 32.4.14. + +
+Common operations involving LocStreams are similar to those involving Grids. +For example, LocStreams allow users to: + +
+ +
+A LocStream differs from a Grid in that no topological structure is +maintained between the points +(e.g. the class contains no information about which point is the neighbor +of which other point). + +
+A LocStream is similar to a Mesh in that both are collections of irregularly positioned +points. However, the two structures differ because a Mesh also has connectivity: +each data point represents either a center or corner of a cell. There is no requirement that the +points in a LocStream have connectivity, in fact there is no requirement that any two points +have any particular spatial relationship at all. + +
+ +
+DESCRIPTION:
+
+For ESMF to be able to use coordinates specified in a LocStream key (e.g. in regridding)
+they need to be named with the appropriate identifiers. The particular identifiers depend
+on the coordinate system (i.e. coordSys argument) used to create the LocStream containing
+the keys. ESMF regridding expects these keys to be of type ESMF_TYPEKIND_R8.
+
+
+The valid values are:
+
+
Coordinate System | +dimension 1 | +dimension 2 | +dimension 3 (if used) | +
ESMF_COORDSYS_SPH_DEG | +ESMF:Lon | +ESMF:Lat | +ESMF:Radius | +
ESMF_COORDSYS_SPH_RAD | +ESMF:Lon | +ESMF:Lat | +ESMF:Radius | +
ESMF_COORDSYS_CART | +ESMF:X | +ESMF:Y | +ESMF:Z | +
+ +
+DESCRIPTION:
+
+Points within a LocStream can be marked and then potentially ignored during certain
+operations, like regridding. This masking information must be contained in a key
+named with the appropriate identifier. ESMF regridding expects this key to be
+of type ESMF_TYPEKIND_I4.
+
+
+The valid value is: +
+ +
+ +
+ +
+The following is an example of creating a LocStream object. + After creation, key data is added, and a Field is created to hold data + (temperature) at each location. + +
+
+ !------------------------------------------------------------------- + ! Get parallel information. Here petCount is the total number of + ! running PETs, and localPet is the number of this particular PET. + !------------------------------------------------------------------- + call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Allocate and set example location information. Locations on a PET + ! are wrapped around sphere. Each PET occupies a different latitude + ! ranging from +50.0 to -50.0. + !------------------------------------------------------------------- + numLocations = 20 + allocate(lon(numLocations)) + allocate(lat(numLocations)) + + do i=1,numLocations + lon(i)=360.0*i/numLocations + lat(i)=100*REAL(localPet,ESMF_KIND_R8)/REAL(petCount,ESMF_KIND_R8)-50.0 + enddo + + !------------------------------------------------------------------- + ! Allocate and set example Field data + !------------------------------------------------------------------- + allocate(temperature(numLocations)) + + do i=1,numLocations + temperature(i)= 300 - abs(lat(i)) + enddo + + !------------------------------------------------------------------- + ! Create the LocStream: Allocate space for the LocStream object, + ! define the number and distribution of the locations. + !------------------------------------------------------------------- + locstream=ESMF_LocStreamCreate(name="Temperature Measurements", & + localCount=numLocations, & + coordSys=ESMF_COORDSYS_SPH_DEG, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Add key data, referencing a user data pointer. By changing the + ! datacopyflag to ESMF_DATACOPY_VALUE an internally allocated copy of the + ! user data may also be set. + !------------------------------------------------------------------- + call ESMF_LocStreamAddKey(locstream, & + keyName="ESMF:Lat", & + farray=lat, & + datacopyflag=ESMF_DATACOPY_REFERENCE, & + keyUnits="Degrees", & + keyLongName="Latitude", rc=rc) ++ +
+
+ call ESMF_LocStreamAddKey(locstream, & + keyName="ESMF:Lon", & + farray=lon, & + datacopyflag=ESMF_DATACOPY_REFERENCE, & + keyUnits="Degrees", & + keyLongName="Longitude", rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Create a Field on the Location Stream. In this case the + ! Field is created from a user array, but any of the other + ! Field create methods (e.g. from ArraySpec) would also apply. + !------------------------------------------------------------------- + field_temperature=ESMF_FieldCreate(locstream, & + temperature, & + name="temperature", & + rc=rc) ++ +
+ +
+The following is an example of creating a LocStream object. + After creation, key data is internally allocated, + the pointer is retrieved, and the data is set. + A Field is also created on the LocStream to hold data + (temperature) at each location. + +
+
+ !------------------------------------------------------------------- + ! Get parallel information. Here petCount is the total number of + ! running PETs, and localPet is the number of this particular PET. + !------------------------------------------------------------------- + call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc) ++ +
+
+ numLocations = 20 + + !------------------------------------------------------------------- + ! Create the LocStream: Allocate space for the LocStream object, + ! define the number and distribution of the locations. + !------------------------------------------------------------------- + locstream=ESMF_LocStreamCreate(name="Temperature Measurements", & + localCount=numLocations, & + coordSys=ESMF_COORDSYS_SPH_DEG, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Add key data (internally allocating memory). + !------------------------------------------------------------------- + call ESMF_LocStreamAddKey(locstream, & + keyName="ESMF:Lat", & + KeyTypeKind=ESMF_TYPEKIND_R8, & + keyUnits="Degrees", & + keyLongName="Latitude", rc=rc) ++ +
+
+ call ESMF_LocStreamAddKey(locstream, & + keyName="ESMF:Lon", & + KeyTypeKind=ESMF_TYPEKIND_R8, & + keyUnits="Degrees", & + keyLongName="Longitude", rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Get key data. + !------------------------------------------------------------------- + call ESMF_LocStreamGetKey(locstream, & + keyName="ESMF:Lat", & + farray=lat, & + rc=rc) ++ +
+
+ call ESMF_LocStreamGetKey(locstream, & + keyName="ESMF:Lon", & + farray=lon, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Set example location information. Locations on a PET are wrapped + ! around sphere. Each PET occupies a different latitude ranging + ! from +50.0 to -50.0. + !------------------------------------------------------------------- + do i=1,numLocations + lon(i)=360.0*i/numLocations + lat(i)=100*REAL(localPet,ESMF_KIND_R8)/REAL(petCount,ESMF_KIND_R8)-50.0 + enddo + + + !------------------------------------------------------------------- + ! Allocate and set example Field data + !------------------------------------------------------------------- + allocate(temperature(numLocations)) + do i=1,numLocations + temperature(i)= 300 - abs(lat(i)) + enddo + + !------------------------------------------------------------------- + ! Create a Field on the Location Stream. In this case the + ! Field is created from a user array, but any of the other + ! Field create methods (e.g. from ArraySpec) would also apply. + !------------------------------------------------------------------- + field_temperature=ESMF_FieldCreate(locstream, & + temperature, & + name="temperature", & + rc=rc) ++ +
+ +
+The following is an example of using the LocStream create from background + Grid capability. Using this capability, the newly created LocStream + is a copy of the old LocStream, but with a new distribution. The new LocStream + is distributed such that if the coordinates of a location in the LocStream lie + within a Grid cell, then that location is put on the same PET as the Grid cell. + +
+
+ !------------------------------------------------------------------- + ! Get parallel information. Here petCount is the total number of + ! running PETs, and localPet is the number of this particular PET. + !------------------------------------------------------------------- + call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Create the LocStream: Allocate space for the LocStream object, + ! define the number and distribution of the locations. + !------------------------------------------------------------------- + numLocations = 20 + locstream=ESMF_LocStreamCreate(name="Temperature Measurements", & + localCount=numLocations, & + coordSys=ESMF_COORDSYS_SPH_DEG, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Add key data (internally allocating memory). + !------------------------------------------------------------------- + call ESMF_LocStreamAddKey(locstream, & + keyName="ESMF:Lon", & + KeyTypeKind=ESMF_TYPEKIND_R8, & + keyUnits="Degrees", & + keyLongName="Longitude", rc=rc) ++ +
+
+ call ESMF_LocStreamAddKey(locstream, & + keyName="ESMF:Lat", & + KeyTypeKind=ESMF_TYPEKIND_R8, & + keyUnits="Degrees", & + keyLongName="Latitude", rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Get Fortran arrays which hold the key data, so that it can be set. + !------------------------------------------------------------------- + call ESMF_LocStreamGetKey(locstream, & + keyName="ESMF:Lon", & + farray=lon, & + rc=rc) ++ +
+
+ call ESMF_LocStreamGetKey(locstream, & + keyName="ESMF:Lat", & + farray=lat, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Set example location information. Locations on a PET are wrapped + ! around sphere. Each PET occupies a different latitude ranging + ! from +50.0 to -50.0. + !------------------------------------------------------------------- + do i=1,numLocations + lon(i)=360.0*i/numLocations + lat(i)=100*REAL(localPet,ESMF_KIND_R8)/REAL(petCount,ESMF_KIND_R8)-50.0 + enddo + + !------------------------------------------------------------------- + ! Create a Grid to use as the background. The Grid is + ! GridLonSize by GridLatSize with the default distribution + ! (The first dimension split across the PETs). The coordinate range + ! is 0 to 360 in longitude and -90 to 90 in latitude. Note that we + ! use indexflag=ESMF_INDEX_GLOBAL for the Grid creation. At this time + ! this is required for a Grid to be usable as a background Grid. + ! Note that here the points are treated as cartesian. + !------------------------------------------------------------------- + grid=ESMF_GridCreateNoPeriDim(maxIndex=(/GridLonSize,GridLatSize/), & + coordSys=ESMF_COORDSYS_SPH_DEG, & + indexflag=ESMF_INDEX_GLOBAL, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Allocate the corner stagger location in which to put the coordinates. + ! (The corner stagger must be used for the Grid to be usable as a + ! background Grid.) + !------------------------------------------------------------------- + call ESMF_GridAddCoord(grid, staggerloc=ESMF_STAGGERLOC_CORNER, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Get access to the Fortran array pointers that hold the Grid + ! coordinate information and then set the coordinates to be uniformly + ! distributed around the globe. + !------------------------------------------------------------------- + call ESMF_GridGetCoord(grid, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + coordDim=1, computationalLBound=clbnd, & + computationalUBound=cubnd, & + farrayPtr=farrayPtrLonC, rc=rc) ++ +
+
+ call ESMF_GridGetCoord(grid, & + staggerLoc=ESMF_STAGGERLOC_CORNER, & + coordDim=2, farrayPtr=farrayPtrLatC, rc=rc) ++ +
+
+ do i1=clbnd(1),cubnd(1) + do i2=clbnd(2),cubnd(2) + ! Set Grid longitude coordinates as 0 to 360 + farrayPtrLonC(i1,i2) = REAL(i1-1)*360.0/REAL(GridLonSize) + + ! Set Grid latitude coordinates as -90 to 90 + farrayPtrLatC(i1,i2) = -90. + REAL(i2-1)*180.0/REAL(GridLatSize) + & + 0.5*180.0/REAL(GridLatSize) + enddo + enddo + + + !------------------------------------------------------------------- + ! Create newLocstream on the background Grid using the + ! "Lon" and "Lat" keys as the coordinates for the entries in + ! locstream. The entries in newLocstream with coordinates (lon,lat) + ! are on the same PET as the piece of grid which contains (lon,lat). + !------------------------------------------------------------------- + newLocstream=ESMF_LocStreamCreate(locstream, & + background=grid, rc=rc) + + + !------------------------------------------------------------------- + ! A Field can now be created on newLocstream and + ! ESMF_FieldRedist() can be used to move data between Fields built + ! on locstream and Fields built on newLocstream. + !------------------------------------------------------------------- ++ +
+ +
+The following is an example of how a LocStream object can be used in regridding. + +
+
+ !------------------------------------------------------------------- + ! Create a global Grid to use as the regridding source. The Grid is + ! GridLonSize by GridLatSize with the default distribution + ! (The first dimension split across the PETs). The coordinate range + ! is 0 to 360 in longitude and -90 to 90 in latitude. Note that we + ! use indexflag=ESMF_INDEX_GLOBAL for the Grid creation to calculate + ! coordinates across PETs. + !------------------------------------------------------------------- + grid=ESMF_GridCreate1PeriDim(maxIndex=(/GridLonSize,GridLatSize/), & + coordSys=ESMF_COORDSYS_SPH_DEG, & + indexflag=ESMF_INDEX_GLOBAL, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Allocate the center stagger location in which to put the coordinates. + !------------------------------------------------------------------- + call ESMF_GridAddCoord(grid, staggerloc=ESMF_STAGGERLOC_CENTER, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Get access to the Fortran array pointers that hold the Grid + ! coordinate information. + !------------------------------------------------------------------- + ! Longitudes + call ESMF_GridGetCoord(grid, & + staggerLoc=ESMF_STAGGERLOC_CENTER, & + coordDim=1, computationalLBound=clbnd, & + computationalUBound=cubnd, & + farrayPtr=farrayPtrLonC, rc=rc) ++ +
+
+ ! Latitudes + call ESMF_GridGetCoord(grid, & + staggerLoc=ESMF_STAGGERLOC_CENTER, & + coordDim=2, computationalLBound=clbnd, & + computationalUBound=cubnd, & + farrayPtr=farrayPtrLatC, rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Create a source Field to hold the data to be regridded to the + ! destination + !------------------------------------------------------------------- + srcField = ESMF_FieldCreate(grid, typekind=ESMF_TYPEKIND_R8, & + staggerloc=ESMF_STAGGERLOC_CENTER, & + name="source", rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Set the Grid coordinates to be uniformly distributed around the globe. + !------------------------------------------------------------------- + do i1=clbnd(1),cubnd(1) + do i2=clbnd(2),cubnd(2) + ! Set Grid longitude coordinates as 0 to 360 + farrayPtrLonC(i1,i2) = REAL(i1-1)*360.0/REAL(GridLonSize) + + ! Set Grid latitude coordinates as -90 to 90 + farrayPtrLatC(i1,i2) = -90. + REAL(i2-1)*180.0/REAL(GridLatSize) + & + 0.5*180.0/REAL(GridLatSize) ++ +
+
+ enddo + enddo + + !------------------------------------------------------------------- + ! Set the number of points the destination LocStream will have + ! depending on the PET. + !------------------------------------------------------------------- + if (petCount .eq. 1) then + numLocationsOnThisPet=7 + else + if (localpet .eq. 0) then + numLocationsOnThisPet=2 + else if (localpet .eq. 1) then + numLocationsOnThisPet=2 + else if (localpet .eq. 2) then + numLocationsOnThisPet=2 + else if (localpet .eq. 3) then + numLocationsOnThisPet=1 + endif + endif + + !------------------------------------------------------------------- + ! Create the LocStream: Allocate space for the LocStream object, + ! define the number of locations on this PET. + !------------------------------------------------------------------- + locstream=ESMF_LocStreamCreate(name="Test Data", & + localCount=numLocationsOnThisPet, & + coordSys=ESMF_COORDSYS_SPH_DEG, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Add key data to LocStream(internally allocating memory). + !------------------------------------------------------------------- + call ESMF_LocStreamAddKey(locstream, & + keyName="ESMF:Lat", & + KeyTypeKind=ESMF_TYPEKIND_R8, & + keyUnits="degrees", & + keyLongName="Latitude", rc=rc) ++ +
+
+ call ESMF_LocStreamAddKey(locstream, & + keyName="ESMF:Lon", & + KeyTypeKind=ESMF_TYPEKIND_R8, & + keyUnits="degrees", & + keyLongName="Longitude", rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Get access to the Fortran array pointers that hold the key data. + !------------------------------------------------------------------- + ! Longitudes + call ESMF_LocStreamGetKey(locstream, & + keyName="ESMF:Lon", & + farray=lonArray, & + rc=rc) ++ +
+
+ ! Latitudes + call ESMF_LocStreamGetKey(locstream, & + keyName="ESMF:Lat", & + farray=latArray, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Set coordinates in key arrays depending on the PET. + ! For this example use an arbitrary set of points around globe. + !------------------------------------------------------------------- + if (petCount .eq. 1) then + latArray = (/-87.75, -56.25, -26.5, 0.0, 26.5, 56.25, 87.75 /) + lonArray = (/51.4, 102.8, 154.2, 205.6, 257.0, 308.4, 359.8 /) + else + if (localpet .eq. 0) then + latArray = (/ -87.75, -56.25 /) + lonArray = (/ 51.4, 102.8 /) + else if (localpet .eq.1) then + latArray = (/ -26.5, 0.0 /) + lonArray = (/ 154.2, 205.6 /) + else if (localpet .eq.2) then + latArray = (/ 26.5, 56.25 /) + lonArray = (/ 257.0, 308.4 /) + else if (localpet .eq.3) then + latArray = (/ 87.75 /) + lonArray = (/ 359.8 /) + endif + endif + + !------------------------------------------------------------------- + ! Create the destination Field on the LocStream to hold the + ! result of the regridding. + !------------------------------------------------------------------- + dstField = ESMF_FieldCreate(locstream, typekind=ESMF_TYPEKIND_R8, & + name="dest", rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Calculate the RouteHandle that represents the regridding from + ! the source to destination Field using the Bilinear regridding method. + !------------------------------------------------------------------- + call ESMF_FieldRegridStore( srcField=srcField, & + dstField=dstField, & + routeHandle=routeHandle, & + regridmethod=ESMF_REGRIDMETHOD_BILINEAR, & + rc=rc) ++ +
+
+ !------------------------------------------------------------------- + ! Regrid from srcField to dstField + !------------------------------------------------------------------- + ! Can loop here regridding from srcField to dstField as src data changes + ! do i=1,... + + ! (Put data into srcField) + + !------------------------------------------------------------------- + ! Use the RouteHandle to regrid data from srcField to dstField. + !------------------------------------------------------------------- + call ESMF_FieldRegrid(srcField, dstField, routeHandle, rc=rc) + + ! (Can now use the data in dstField) + + ! enddo ++ +
+
+ !------------------------------------------------------------------- + ! Now that we are done, release the RouteHandle freeing its memory. + !------------------------------------------------------------------- + call ESMF_FieldRegridRelease(routeHandle, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + locstream1 = locstream2 +ARGUMENTS: +
type(ESMF_LocStream) :: locstream1 + type(ESMF_LocStream) :: locstream2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign locstream1 as an alias to the same ESMF LocStream object in memory + as locstream2. If locstream2 is invalid, then locstream1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (locstream1 == locstream2) then ... endif + OR + result = (locstream1 == locstream2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream1 + type(ESMF_LocStream), intent(in) :: locstream2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether locstream1 and locstream2 are valid aliases to the same ESMF + LocStream object in memory. For a more general comparison of two ESMF LocStreams, + going beyond the simple alias test, the ESMF_LocStreamMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (locstream1 /= locstream2) then ... endif + OR + result = (locstream1 /= locstream2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream1 + type(ESMF_LocStream), intent(in) :: locstream2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether locstream1 and locstream2 are not valid aliases to the + same ESMF LocStream object in memory. For a more general comparison of two ESMF + LocStreams, going beyond the simple alias test, the ESMF_LocStreamMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocStreamAddKey() + subroutine ESMF_LocStreamAddKeyAlloc(locstream, keyName, & + keyTypeKind, keyUnits, keyLongName, rc) +ARGUMENTS: +
type(ESMF_Locstream), intent(in) :: locstream + character (len=*), intent(in) :: keyName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_TypeKind_Flag), intent(in), optional :: keyTypeKind + character (len=*), intent(in), optional :: keyUnits + character (len=*), intent(in), optional :: keyLongName + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add a key to a locstream with a required keyName. Once a key has + been added, a pointer to its internally allocated memory can be + retrieved and used to set key values. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocStreamAddKey() + subroutine ESMF_LocStreamAddKeyArray(locstream, keyName, keyArray, & + destroyKey, keyUnits, keyLongName, rc) +ARGUMENTS: +
type(ESMF_Locstream), intent(in) :: locstream + character (len=*), intent(in) :: keyName + type(ESMF_Array), intent(in) :: keyArray + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: destroyKey + character (len=*), intent(in), optional :: keyUnits + character (len=*), intent(in), optional :: keyLongName + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add a key to a locstream with a required keyName and a required + ESMF_Array. The user is responsible for the creation of the + ESMF_Array that will hold the key values. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocStreamAddKey() + subroutine ESMF_LocStreamAddKeyI4(locstream, keyName, farray, & + datacopyflag, keyUnits, keyLongName, rc) +ARGUMENTS: +
type(ESMF_Locstream), intent(in) :: locstream + character (len=*), intent(in) :: keyName + <farray> + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DataCopy_Flag), intent(in), optional :: datacopyflag + character (len=*), intent(in), optional :: keyUnits + character (len=*), intent(in), optional :: keyLongName + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add a key to a locstream with a required keyName and a required + Fortran array. The user is responsible for the creation of the + Fortran array that will hold the key values, including + the maintenance of any allocated memory. + +
+Supported values for <farray> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocStreamCreate() + function ESMF_LocStreamCreateByBkgGrid(locstream, & + background, maskValues, & + unmappedaction, name, rc) +RETURN VALUE: +
type(ESMF_LocStream) :: ESMF_LocStreamCreateByBkgGrid +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + type(ESMF_Grid), intent(in) :: background + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(in), optional :: maskValues(:) + type(ESMF_UnmappedAction_Flag), intent(in), optional :: unmappedaction + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an location stream from an existing one in accordance with + the distribution of the background Grid. The entries + in the new location stream are redistributed, so that they lie on the same PET + as the piece of Grid which contains the coordinates of the entries. The coordinates + of the entries are the data in the keys named ESMF:Lon, ESMF:Lat, ESMF:Radius in the + case of a spherical system and ESMF:X, ESMF:Y, ESMF:Z for cartesian. To copy data in + Fields or FieldBundles built on locstream to the new one simply use ESMF_FieldRedist() + or ESMF_FieldBundleRedist(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocStreamCreate() + function ESMF_LocStreamCreateByBkgMesh(locstream, & + background, unmappedaction, name, rc) +RETURN VALUE: +
type(ESMF_LocStream) :: ESMF_LocStreamCreateByBkgMesh +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + type(ESMF_Mesh), intent(in) :: background + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_UnmappedAction_Flag), intent(in), optional :: unmappedaction + character (len=*), intent(in), optional :: name + integer, intent(out),optional :: rc ++DESCRIPTION: +
+Create an location stream from an existing one in accordance with + the distribution of the background Mesh. The entries + in the new location stream are redistributed, so that they lie on the same PET + as the piece of Mesh which contains the coordinates of the entries. The coordinates + of the entries are the data in the keys named ESMF:Lon, ESMF:Lat, ESMF:Radius in the + case of a spherical system and ESMF:X, ESMF:Y, ESMF:Z for cartesian. To copy data in + Fields or FieldBundles built on locstream to the new one simply use ESMF_FieldRedist() + or ESMF_FieldBundleRedist(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name: call using ESMF_LocStreamCreate() + function ESMF_LocStreamCreateFromDG(distgrid, & + indexflag, coordSys, name, vm, rc ) +RETURN VALUE: +
type(ESMF_LocStream) :: ESMF_LocStreamCreateFromDG +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + character (len=*), intent(in), optional :: name + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Allocates memory for a new ESMF_LocStream object, constructs its + internal derived types. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name: call using ESMF_LocStreamCreate() + function ESMF_LocStreamCreateIrreg(minIndex, countsPerDE, & + indexflag, coordSys, name, rc) +RETURN VALUE: +
type(ESMF_LocStream) :: ESMF_LocStreamCreateIrreg +ARGUMENTS: +
integer, intent(in), optional :: minIndex + integer, intent(in) :: countsPerDE(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Allocates memory for a new ESMF_LocStream object, constructs its + internal derived types. The ESMF_DistGrid is set up, indicating + how the LocStream is distributed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name: call using ESMF_LocStreamCreate() + function ESMF_LocStreamCreateFromLocal(localCount, & + indexflag, coordSys, name, rc) +RETURN VALUE: +
type(ESMF_LocStream) :: ESMF_LocStreamCreateFromLocal +ARGUMENTS: +
integer, intent(in) :: localCount + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Allocates memory for a new ESMF_LocStream object, constructs its + internal derived types. The ESMF_DistGrid is set up, indicating + how the LocStream is distributed. The assumed layout is one DE per PET. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name: call using ESMF_LocStreamCreate() + function ESMF_LocStreamCreateFromNewDG(locstream, distgrid, & + name, rc) +RETURN VALUE: +
type(ESMF_LocStream) :: ESMF_LocStreamCreateFromNewDG +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + type(ESMF_DistGrid), intent(in) :: distgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a new location stream that is a copy of an old one, but with a new + distribution. The new distribution is given by a distgrid passed into the call. + Key and other class information is copied from the old locstream to the new one. + Information contained in Fields build on the location streams can be copied over + by using the Field redistribution calls (e.g. ESMF_FieldRedistStore() + and ESMF_FieldRedist()). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name: call using ESMF_LocStreamCreate() + function ESMF_LocStreamCreateReg(regDecomp, decompFlag, & + minIndex, maxIndex, & + coordSys, indexflag, name, rc) +RETURN VALUE: +
type(ESMF_LocStream) :: ESMF_LocStreamCreateReg +ARGUMENTS: +
integer, intent(in), optional :: regDecomp + type(ESMF_Decomp_Flag), intent(in), optional :: decompflag + integer, intent(in), optional :: minIndex + integer, intent(in) :: maxIndex + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + type(ESMF_Index_Flag), intent(in), optional :: indexflag + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Allocates memory for a new ESMF_LocStream object, constructs its + internal derived types. The ESMF_DistGrid is set up, indicating + how the LocStream is distributed. + +
+The arguments are: +
+ +
+ +
+
+INTERFACE:
+
! Private name: call using ESMF_LocStreamCreate() + function ESMF_LocStreamCreateFromFile(filename, & + fileformat, varname, indexflag, centerflag, name, rc) +RETURN VALUE: +
type(ESMF_LocStream) :: ESMF_LocStreamCreateFromFile +ARGUMENTS: +
character (len=*), intent(in) :: filename + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_FileFormat_Flag), intent(in), optional :: fileformat + character(len=*), intent(in), optional :: varname + type(ESMF_Index_Flag), intent(in), optional :: indexflag + logical, intent(in), optional :: centerflag + character (len=*), intent(in), optional :: name + integer, intent(out),optional :: rc ++DESCRIPTION: +
+Create a new ESMF_LocStream object and add the coordinate keys and mask key + to the LocStream using the coordinates defined in a grid file. Currently, it + supports the SCRIP format, the ESMF unstructured grid format and the UGRID format. + For a 2D or 3D grid in ESMF or UGRID format, it can construct the LocStream using either + the center coordinates or the corner coordinates. For a SCRIP format grid file, the + LocStream can only be constructed using the center coordinates. In + addition, it supports 1D network topology in UGRID format. When + construction a LocStream using a 1D UGRID, it always uses node + coordinates (i.e., corner coordinates). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LocStreamDestroy(locstream, noGarbage, rc) +ARGUMENTS: +
type(ESMF_LocStream), intent(inout) :: locstream + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Deallocate an ESMF_LocStream object and appropriate + internal structures. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LocStreamGet(locstream, & + distgrid, keyCount, keyNames, localDECount, indexflag, & + coordSys, name, rc) +ARGUMENTS: +
type(ESMF_Locstream), intent(in) :: locstream + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DistGrid), intent(out), optional :: distgrid + integer, intent(out), optional :: keyCount + character(len=ESMF_MAXSTR), optional :: keyNames(:) + integer, intent(out), optional :: localDECount + type(ESMF_Index_Flag), intent(out), optional :: indexflag + type(ESMF_CoordSys_Flag), intent(out), optional :: coordSys + character(len=*), intent(out), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Query an ESMF_LocStream for various information. All arguments after + the locstream are optional. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LocStreamGetBounds(locstream, & + localDE, exclusiveLBound, exclusiveUBound, exclusiveCount, & + computationalLBound, computationalUBound, computationalCount,& + rc) +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: localDE + 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 :: rc ++DESCRIPTION: +
+This method gets the bounds of a localDE for a locstream. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocStreamGetKey() + subroutine ESMF_LocStreamGetKeyArray(locstream, keyName, keyArray, & + rc) +ARGUMENTS: +
type(ESMF_Locstream), intent(in) :: locstream + character (len=*), intent(in) :: keyName + type(ESMF_Array), intent(out) :: keyArray + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get ESMF Array associated with key. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocStreamGetKey() + subroutine ESMF_LocStreamGetKeyInfo(locstream, keyName, & + keyUnits, keyLongName, typekind, isPresent, rc) +ARGUMENTS: +
type(ESMF_Locstream), intent(in) :: locstream + character (len=*), intent(in) :: keyName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len=*), intent(out), optional :: keyUnits + character (len=*), intent(out), optional :: keyLongName + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + logical, intent(out), optional :: isPresent + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get ESMF Array associated with key. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LocStreamGetKey() + subroutine ESMF_LocStreamGetKey(locstream, keyName, & + localDE, exclusiveLBound, exclusiveUBound, exclusiveCount, & + computationalLBound, computationalUBound, computationalCount, & + totalLBound, totalUBound, totalCount, & + farray, datacopyflag, rc) +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + character (len=*), intent(in) :: keyName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: localDE + 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 + <farray> + 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 + key data for a particular key on the given local DE. + This is useful, for example, for setting the key values in a LocStream, or + for reading the values. + +
+Supported values for <farray> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_LocStreamIsCreated(locstream, rc) +RETURN VALUE: +
logical :: ESMF_LocStreamIsCreated +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the locstream has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LocStreamPrint(locstream, options, rc) +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len = *), intent(in), optional :: options + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Prints information about the locstream to stdout. + This subroutine goes through the internal data members of a locstream + ! data type and prints information of each data member. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LocStreamValidate(locstream, rc) +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Validates that the locstream is internally consistent. + Currently this method determines if the locstream is uninitialized + or already destroyed. + +
+The method returns an error code if problems are found. + +
+The arguments are: +
+ + +
+Unstructured grids are commonly used in the computational solution of partial differential +equations. These are especially useful for problems that involve complex geometry, where +using the less flexible structured grids can result in grid representation of regions +where no computation is needed. Finite element and finite volume methods map naturally +to unstructured grids and are used commonly in hydrology, ocean modeling, and many other +applications. + +
+In order to provide support for application codes using unstructured grids, the ESMF library +provides a class for representing unstructured grids called the Mesh. Fields can be +created on a Mesh to hold data. Fields created on a Mesh can also be used as either the +source or destination or both of an interpolation (i.e. an ESMF_FieldRegridStore() call) +which allows data to be moved between unstructured grids. This section describes the Mesh +and how to create and use them in ESMF. + +
+ +
+A Mesh in ESMF is constructed of nodes and elements. + +
+A node, also known as a vertex or corner, is a part of a Mesh which represents a single point. Coordinate information is +set in a node. + +
+An element, also known as a cell, is a part of a mesh which represents a small +region of space. Elements are described in terms of a connected set of nodes which represent locations along their boundaries. + +
+Field data may be located on either the nodes or elements of a Mesh. + +
+ +
+
+
+
+The dimension of a Mesh in ESMF is specified with two parameters: the parametric dimension and the spatial dimension. + +
+The parametric dimension of a Mesh is the dimension of the topology of the Mesh. This can be thought of as the dimension of +the elements which make up the Mesh. For example, a Mesh composed of triangles would have a parametric dimension of 2, whereas +a Mesh composed of tetrahedra would have a parametric dimension of 3. + +
+The spatial dimension of a Mesh is the dimension of the space the Mesh is embedded in. In other words, it is the number of coordinate dimensions needed to describe the location of the nodes making up the Mesh. + +
+For example, a Mesh constructed of squares on a plane would have a parametric dimension of 2 and a spatial dimension of 2. +If that same Mesh were used to represent the 2D surface of a sphere, then the Mesh would still have a parametric dimension +of 2, but now its spatial dimension would be 3. + +
+ +
+The range of Meshes supported by ESMF are defined by several factors: dimension, element +types, and distribution. + +
+ESMF currently only supports Meshes whose number of coordinate dimensions (spatial dimension) +is 2 or 3. The dimension of the elements in a Mesh (parametric dimension) must be less than +or equal to the spatial dimension, but also must be either 2 or 3. This means that a Mesh may +be either 2D elements in 2D space, 3D elements in 3D space, or a manifold constructed of 2D +elements embedded in 3D space. + +
+ESMF supports a range of elements for each Mesh parametric dimension. For a +parametric dimension of 2, the native supported element types are triangles and quadrilaterals. +In addition to these, ESMF supports 2D polygons with any number of sides. Internally these +are represented as sets of triangles, but to the user should behave like any other element. +For a parametric dimension of 3, the supported element types are tetrahedrons +and hexahedrons. See Section 33.2.1 for diagrams of these. The Mesh +supports any combination of element types within a particular dimension, but types from +different dimensions may not be mixed. For example, a Mesh cannot be constructed of both +quadrilaterals and tetrahedra. + +
+ESMF currently only supports distributions where every node on a PET must be a part of an +element on that PET. In other words, there must not be nodes without a corresponding element +on any PET. + +
+ +
+DESCRIPTION:
+
+ An ESMF Mesh can be constructed from a combination of different elements. The type of elements that can
+be used in a Mesh depends on the Mesh's parameteric dimension, which is set during Mesh creation. The
+following are the valid Mesh element types for each valid Mesh parametric dimension (2D or 3D) .
+
+
+ +
+
+
+
+
+ 3 4 ---------- 3 + / \ | | + / \ | | + / \ | | + / \ | | + / \ | | + 1 --------- 2 1 ---------- 2 + + ESMF_MESHELEMTYPE_TRI ESMF_MESHELEMTYPE_QUAD + + 2D element types (numbers are the order for elementConn during Mesh create) ++ +
+For a Mesh with parametric dimension of 2 ESMF supports two native element types (illustrated above), +but also supports polygons with more sides. Internally these polygons are represented as a set of +triangles, but to the user should behave like other elements. +To specify the non-native polygons in the elementType argument use the number of corners +of the polygon (e.g. for a pentagon use 5). The connectivity for a polygon should be specified in counterclockwise order. +The following table summarizes this information: + +
+ +
+ ++
Element Type | +Number of Nodes | +Description | +
ESMF_MESHELEMTYPE_TRI | +3 | +A triangle | +
ESMF_MESHELEMTYPE_QUAD | +4 | +A quadrilateral (e.g. a rectangle) | +
N | +N | +An N-gon (e.g. if N=5 a pentagon) | +
+ +
+
+
+
+
+
+
+
+ + 3 8---------------7 + /|\ /| /| + / | \ / | / | + / | \ / | / | + / | \ / | / | + / | \ 5---------------6 | + 4-----|-----2 | | | | + \ | / | 4----------|----3 + \ | / | / | / + \ | / | / | / + \ | / | / | / + \|/ |/ |/ + 1 1---------------2 + + ESMF_MESHELEMTYPE_TETRA ESMF_MESHELEMTYPE_HEX + + 3D element types (numbers are the order for elementConn during Mesh create) ++ +
+For a Mesh with parametric dimension of 3 the valid element types (illustrated above) are: + +
+ +
+ ++
Element Type | +Number of Nodes | +Description | +
ESMF_MESHELEMTYPE_TETRA | +4 | +A tetrahedron (NOT VALID IN BILINEAR OR PATCH REGRID) | +
ESMF_MESHELEMTYPE_HEX | +8 | +A hexahedron (e.g. a cube) | +
+ +
+ +
+This section describes the use of the ESMF Mesh class. It starts with an explanation and examples of + creating a Mesh and then goes through other Mesh methods. This set of sections covers the use of the + Mesh class interfaces. For further detail which applies to creating a Field on a Mesh, please see + Section 26.3.19. + +
+ +
+To create a Mesh we need to set some properties of the Mesh as a whole, some properties of each node in the mesh and + then some properties of each element which connects the nodes (for a definition of node and element please see + Section 33.1.1). + +
+For the Mesh as a whole we set its parametric dimension (parametricDim) and spatial dimension (spatialDim). + A Mesh's parametric dimension can be thought of as the dimension of the elements which make up the Mesh. + A Mesh's spatial dimension, on the other hand, is the is the number of coordinate dimensions needed to describe the location of + the nodes making up the Mesh. (For a fuller definition of these terms please see Section 33.1.1.) + +
+The structure of the per node and element information used to create a Mesh is influenced by the Mesh distribution strategy. + The Mesh class is distributed by elements. This means that a node must be present on any PET that contains an element + associated with that node, but not on any other PET (a node can't be on a PET without an element "home"). Since a node may be used + by two or more elements located on different PETs, a node may be duplicated on multiple PETs. When a node is duplicated in this manner, + one and only one of the PETs that contain the node must "own" the node. The user sets this ownership when they define the nodes during Mesh creation. + When a Field is created on a Mesh (i.e. on the Mesh nodes), on each PET the Field is only created on the nodes which are owned by that PET. + This means that the size of the Field memory on the PET can be smaller than the number of nodes used to create the Mesh on + that PET. Please see Section 26.3.19 in Field for further explanation and examples of this + issue and others in working with Fields on Meshes. + +
+For each node in the Mesh we set three properties: the global id of the node (nodeIds), node coordinates + (nodeCoords), and which PET owns the node (nodeOwners). The node id is a unique (across all PETs) integer + attached to the particular node. It is used to indicate which nodes are the same when connecting together pieces of the + Mesh on different processors. The node coordinates indicate the location of a node in space and are used in the + ESMF_FieldRegrid() functionality when interpolating. The node owner indicates which PET is in charge of the node. This + is used when creating a Field on the Mesh to indicate which PET should contain a Field location for the data. + +
+For each element in the Mesh we set three properties: the global id of the element (elementIds), the topology type of + the element (elementTypes), and which nodes are connected together to form the element (elementConn). The element id is + a unique (across all PETs) integer attached to the particular element. The element type describes the topology of the element + (e.g. a triangle vs. a quadrilateral). The range of choices for the topology of the elements in a Mesh are restricted by the + Mesh's parametric dimension (e.g. a Mesh can't contain a 2D element like a triangle, when its parametric dimension is 3D), but it can contain + any combination of elements appropriate to its dimension. In particular, in 2D ESMF supports two native element types triangle and quadrilateral, but + also provides support for polygons with any number of sides. These polygons are represented internally as sets of triangles, but to the user + should behave like other elements. To specify a polygon with more than four sides, the element type should be set to the number of corners of + the polygon (e.g. element type=6 for a hexagon). + The element connectivity indicates which nodes are to be connected together to + form the element. The number of nodes connected together for each element is implied by the elements topology type (elementTypes). + It is IMPORTANT to note, that the entries in this list are NOT the global ids of the nodes, but are indices into the PET local lists of + node info used in the Mesh Create. In other words, the element connectivity isn't specified in terms of the global list of nodes, but instead + is specified in terms of the locally described node info. One other important point about connectivities is that the order of the nodes in the + connectivity list of an element is important. Please see Section 33.2.1 for diagrams illustrating the correct order of + nodes in an element. In general, when specifying an element with parametric dimension 2, the nodes should be given in counterclockwise order + around the element. + +
+Mesh creation may either be performed as a one step process using the full ESMF_MeshCreate() call, or may be done in three steps. The + three step process starts with a more minimal ESMF_MeshCreate() call. It is then followed by the ESMF_MeshAddNodes() to + specify nodes, and then the ESMF_MeshAddElements() call to specify elements. This three step sequence is useful to conserve memory + because the node arrays being used for the ESMF_MeshAddNodes() call can be deallocated before creating the arrays to be used in the ESMF_MeshAddElements() call. + +
+ +
+ + + + 2.0 7 ------- 8 ------- 9 + | | | + | 4 | 5 | + | | | + 1.0 4 ------- 5 ------- 6 + | | \ 3 | + | 1 | \ | + | | 2 \ | + 0.0 1 ------- 2 ------- 3 + + 0.0 1.0 2.0 + + Node Id labels at corners + Element Id labels in centers + (Everything owned by PET 0) + |
+This example is intended to illustrate the creation of a small Mesh on one PET. The reason for starting with a single PET + case is so that the user can start to familiarize themselves with the concepts of Mesh creation without the added complication of + multiple processors. Later examples illustrate the multiple processor case. This example creates the small 2D Mesh which can be + seen in the figure above. Note that this Mesh consists of 9 nodes and 5 elements, where the elements are a mixture of + quadrilaterals and triangles. The coordinates of the nodes in the Mesh range from 0.0 to 2.0 in both dimensions. The node ids are + in the corners of the elements whereas the element ids are in the centers. The following section of code illustrates the creation of + this Mesh. + +
+
+ ! Set number of nodes + numNodes=9 + + ! Allocate and fill the node id array. + allocate(nodeIds(numNodes)) + nodeIds=(/1,2,3,4,5,6,7,8,9/) + + ! Allocate and fill node coordinate array. + ! Since this is a 2D Mesh the size is 2x the + ! number of nodes. + allocate(nodeCoords(2*numNodes)) + nodeCoords=(/0.0,0.0, & ! node id 1 + 1.0,0.0, & ! node id 2 + 2.0,0.0, & ! node id 3 + 0.0,1.0, & ! node id 4 + 1.0,1.0, & ! node id 5 + 2.0,1.0, & ! node id 6 + 0.0,2.0, & ! node id 7 + 1.0,2.0, & ! node id 8 + 2.0,2.0 /) ! node id 9 + + ! Allocate and fill the node owner array. + ! Since this Mesh is all on PET 0, it's just set to all 0. + allocate(nodeOwners(numNodes)) + nodeOwners=0 ! everything on PET 0 + + + ! Set the number of each type of element, plus the total number. + numQuadElems=3 + numTriElems=2 + numTotElems=numQuadElems+numTriElems + + + ! Allocate and fill the element id array. + allocate(elemIds(numTotElems)) + elemIds=(/1,2,3,4,5/) + + + ! Allocate and fill the element topology type array. + allocate(elemTypes(numTotElems)) + elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! elem id 1 + ESMF_MESHELEMTYPE_TRI, & ! elem id 2 + ESMF_MESHELEMTYPE_TRI, & ! elem id 3 + ESMF_MESHELEMTYPE_QUAD, & ! elem id 4 + ESMF_MESHELEMTYPE_QUAD/) ! elem id 5 + + + ! Allocate and fill the element connection type array. + ! Note that entries in this array refer to the + ! positions in the nodeIds, etc. arrays and that + ! the order and number of entries for each element + ! reflects that given in the Mesh options + ! section for the corresponding entry + ! in the elemTypes array. The number of + ! entries in this elemConn array is the + ! number of nodes in a quad. (4) times the + ! number of quad. elements plus the number + ! of nodes in a triangle (3) times the number + ! of triangle elements. + allocate(elemConn(4*numQuadElems+3*numTriElems)) + elemConn=(/1,2,5,4, & ! elem id 1 + 2,3,5, & ! elem id 2 + 3,6,5, & ! elem id 3 + 4,5,8,7, & ! elem id 4 + 5,6,9,8/) ! elem id 5 + + + ! Create Mesh structure in 1 step + mesh=ESMF_MeshCreate(parametricDim=2,spatialDim=2, & + coordSys=ESMF_COORDSYS_CART, & + nodeIds=nodeIds, nodeCoords=nodeCoords, & + nodeOwners=nodeOwners, elementIds=elemIds,& + elementTypes=elemTypes, elementConn=elemConn, & + rc=localrc) + + + ! After the creation we are through with the arrays, so they may be + ! deallocated. + deallocate(nodeIds) + deallocate(nodeCoords) + deallocate(nodeOwners) + deallocate(elemIds) + deallocate(elemTypes) + deallocate(elemConn) + + + ! At this point the mesh is ready to use. For example, as is + ! illustrated here, to have a field created on it. Note that + ! the Field only contains data for nodes owned by the current PET. + ! Please see Section "Create a Field from a Mesh" under Field + ! for more information on creating a Field on a Mesh. + field = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, rc=localrc) ++ +
+ +
+This example is intended to illustrate the creation of a small Mesh in three steps on one PET. The Mesh being created is exactly + the same one as in the last example (Section 33.3.2), but the three step process allows the creation to occur in + a more memory efficient manner. + +
+
+ ! Create the mesh structure setting the dimensions + ! and coordinate system + mesh = ESMF_MeshCreate(parametricDim=2,spatialDim=2, & + coordSys=ESMF_COORDSYS_CART, & + rc=localrc) + + ! Set number of nodes + numNodes=9 + + ! Allocate and fill the node id array. + allocate(nodeIds(numNodes)) + nodeIds=(/1,2,3,4,5,6,7,8,9/) + + ! Allocate and fill node coordinate array. + ! Since this is a 2D Mesh the size is 2x the + ! number of nodes. + allocate(nodeCoords(2*numNodes)) + nodeCoords=(/0.0,0.0, & ! node id 1 + 1.0,0.0, & ! node id 2 + 2.0,0.0, & ! node id 3 + 0.0,1.0, & ! node id 4 + 1.0,1.0, & ! node id 5 + 2.0,1.0, & ! node id 6 + 0.0,2.0, & ! node id 7 + 1.0,2.0, & ! node id 8 + 2.0,2.0 /) ! node id 9 + + ! Allocate and fill the node owner array. + ! Since this Mesh is all on PET 0, it's just set to all 0. + allocate(nodeOwners(numNodes)) + nodeOwners=0 ! everything on PET 0 + + ! Add the nodes to the Mesh + call ESMF_MeshAddNodes(mesh, nodeIds=nodeIds, & + nodeCoords=nodeCoords, nodeOwners=nodeOwners, rc=localrc) + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ! HERE IS THE POINT OF THE THREE STEP METHOD + ! WE CAN DELETE THESE NODE ARRAYS BEFORE + ! ALLOCATING THE ELEMENT ARRAYS, THEREBY + ! REDUCING THE AMOUNT OF MEMORY NEEDED + ! AT ONE TIME. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + deallocate(nodeIds) + deallocate(nodeCoords) + deallocate(nodeOwners) + + + ! Set the number of each type of element, plus the total number. + numQuadElems=3 + numTriElems=2 + numTotElems=numQuadElems+numTriElems + + ! Allocate and fill the element id array. + allocate(elemIds(numTotElems)) + elemIds=(/1,2,3,4,5/) + + ! Allocate and fill the element topology type array. + allocate(elemTypes(numTotElems)) + elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! elem id 1 + ESMF_MESHELEMTYPE_TRI, & ! elem id 2 + ESMF_MESHELEMTYPE_TRI, & ! elem id 3 + ESMF_MESHELEMTYPE_QUAD, & ! elem id 4 + ESMF_MESHELEMTYPE_QUAD/) ! elem id 5 + + + ! Allocate and fill the element connection type array. + ! Note that entries in this array refer to the + ! positions in the nodeIds, etc. arrays and that + ! the order and number of entries for each element + ! reflects that given in the Mesh options + ! section for the corresponding entry + ! in the elemTypes array. The number of + ! entries in this elemConn array is the + ! number of nodes in a quad. (4) times the + ! number of quad. elements plus the number + ! of nodes in a triangle (3) times the number + ! of triangle elements. + allocate(elemConn(4*numQuadElems+3*numTriElems)) + elemConn=(/1,2,5,4, & ! elem id 1 + 2,3,5, & ! elem id 2 + 3,6,5, & ! elem id 3 + 4,5,8,7, & ! elem id 4 + 5,6,9,8/) ! elem id 5 + + + ! Finish the creation of the Mesh by adding the elements + call ESMF_MeshAddElements(mesh, elementIds=elemIds,& + elementTypes=elemTypes, elementConn=elemConn, & + rc=localrc) + + ! After the creation we are through with the arrays, so they may be + ! deallocated. + deallocate(elemIds) + deallocate(elemTypes) + deallocate(elemConn) + + + ! At this point the mesh is ready to use. For example, as is + ! illustrated here, to have a field created on it. Note that + ! the Field only contains data for nodes owned by the current PET. + ! Please see Section "Create a Field from a Mesh" under Field + ! for more information on creating a Field on a Mesh. + field = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, rc=localrc) ++ +
+ +
+ + + 2.0 7 ------- 8 [8] ------ 9 + | | | | + | 4 | | 5 | + | | | | + 1.0 [4] ----- [5] [5] ----- [6] + + 0.0 1.0 1.0 2.0 + + PET 2 PET 3 + + + 1.0 4 ------- 5 [5] ------ 6 + | | | \ 3 | + | 1 | | \ | + | | | 2 \ | + 0.0 1 ------- 2 [2] ------ 3 + + 0.0 1.0 1.0 2.0 + + PET 0 PET 1 + + Node Id labels at corners + Element Id labels in centers + |
+This example is intended to illustrate the creation of a small Mesh on multiple PETs. This example creates the same small 2D Mesh as the + previous two examples (See Section 33.3.2 for a diagram), however, in this case the Mesh is broken up across 4 PETs. + The figure above illustrates the distribution of the Mesh across the PETs. As in the previous diagram, the node ids are in + the corners of the elements and the element ids are in the centers. In this figure '[' and ']' around a character indicate a node which + is owned by another PET. The nodeOwner parameter indicates which PET owns the node. Note that the three step creation + illustrated in Section 33.3.3 could also be used in a parallel Mesh creation such as this by simply interleaving + the three calls in the appropriate places between the node and element array definitions. + +
+
+ ! Break up what's being set by PET + if (localPET .eq. 0) then !!! This part only for PET 0 + ! Set number of nodes + numNodes=4 + + ! Allocate and fill the node id array. + allocate(nodeIds(numNodes)) + nodeIds=(/1,2,4,5/) + + ! Allocate and fill node coordinate array. + ! Since this is a 2D Mesh the size is 2x the + ! number of nodes. + allocate(nodeCoords(2*numNodes)) + nodeCoords=(/0.0,0.0, & ! node id 1 + 1.0,0.0, & ! node id 2 + 0.0,1.0, & ! node id 4 + 1.0,1.0 /) ! node id 5 + + ! Allocate and fill the node owner array. + allocate(nodeOwners(numNodes)) + nodeOwners=(/0, & ! node id 1 + 0, & ! node id 2 + 0, & ! node id 4 + 0/) ! node id 5 + + ! Set the number of each type of element, plus the total number. + numQuadElems=1 + numTriElems=0 + numTotElems=numQuadElems+numTriElems + + ! Allocate and fill the element id array. + allocate(elemIds(numTotElems)) + elemIds=(/1/) + + ! Allocate and fill the element topology type array. + allocate(elemTypes(numTotElems)) + elemTypes=(/ESMF_MESHELEMTYPE_QUAD/) ! elem id 1 + + ! Allocate and fill the element connection type array. + ! Note that entry are local indices + allocate(elemConn(4*numQuadElems+3*numTriElems)) + elemConn=(/1,2,4,3/) ! elem id 1 + + else if (localPET .eq. 1) then !!! This part only for PET 1 + ! Set number of nodes + numNodes=4 + + ! Allocate and fill the node id array. + allocate(nodeIds(numNodes)) + nodeIds=(/2,3,5,6/) + + ! Allocate and fill node coordinate array. + ! Since this is a 2D Mesh the size is 2x the + ! number of nodes. + allocate(nodeCoords(2*numNodes)) + nodeCoords=(/1.0,0.0, & ! node id 2 + 2.0,0.0, & ! node id 3 + 1.0,1.0, & ! node id 5 + 2.0,1.0 /) ! node id 6 + + ! Allocate and fill the node owner array. + allocate(nodeOwners(numNodes)) + nodeOwners=(/0, & ! node id 2 + 1, & ! node id 3 + 0, & ! node id 5 + 1/) ! node id 6 + + ! Set the number of each type of element, plus the total number. + numQuadElems=0 + numTriElems=2 + numTotElems=numQuadElems+numTriElems + + ! Allocate and fill the element id array. + allocate(elemIds(numTotElems)) + elemIds=(/2,3/) + + ! Allocate and fill the element topology type array. + allocate(elemTypes(numTotElems)) + elemTypes=(/ESMF_MESHELEMTYPE_TRI, & ! elem id 2 + ESMF_MESHELEMTYPE_TRI/) ! elem id 3 + + ! Allocate and fill the element connection type array. + allocate(elemConn(4*numQuadElems+3*numTriElems)) + elemConn=(/1,2,3, & ! elem id 2 + 2,4,3/) ! elem id 3 + + else if (localPET .eq. 2) then !!! This part only for PET 2 + ! Set number of nodes + numNodes=4 + + ! Allocate and fill the node id array. + allocate(nodeIds(numNodes)) + nodeIds=(/4,5,7,8/) + + ! Allocate and fill node coordinate array. + ! Since this is a 2D Mesh the size is 2x the + ! number of nodes. + allocate(nodeCoords(2*numNodes)) + nodeCoords=(/0.0,1.0, & ! node id 4 + 1.0,1.0, & ! node id 5 + 0.0,2.0, & ! node id 7 + 1.0,2.0 /) ! node id 8 + + ! Allocate and fill the node owner array. + ! Since this Mesh is all on PET 0, it's just set to all 0. + allocate(nodeOwners(numNodes)) + nodeOwners=(/0, & ! node id 4 + 0, & ! node id 5 + 2, & ! node id 7 + 2/) ! node id 8 + + ! Set the number of each type of element, plus the total number. + numQuadElems=1 + numTriElems=0 + numTotElems=numQuadElems+numTriElems + + ! Allocate and fill the element id array. + allocate(elemIds(numTotElems)) + elemIds=(/4/) + + ! Allocate and fill the element topology type array. + allocate(elemTypes(numTotElems)) + elemTypes=(/ESMF_MESHELEMTYPE_QUAD/) ! elem id 4 + + ! Allocate and fill the element connection type array. + allocate(elemConn(4*numQuadElems+3*numTriElems)) + elemConn=(/1,2,4,3/) ! elem id 4 + + else if (localPET .eq. 3) then !!! This part only for PET 3 + ! Set number of nodes + numNodes=4 + + ! Allocate and fill the node id array. + allocate(nodeIds(numNodes)) + nodeIds=(/5,6,8,9/) + + ! Allocate and fill node coordinate array. + ! Since this is a 2D Mesh the size is 2x the + ! number of nodes. + allocate(nodeCoords(2*numNodes)) + nodeCoords=(/1.0,1.0, & ! node id 5 + 2.0,1.0, & ! node id 6 + 1.0,2.0, & ! node id 8 + 2.0,2.0 /) ! node id 9 + + ! Allocate and fill the node owner array. + allocate(nodeOwners(numNodes)) + nodeOwners=(/0, & ! node id 5 + 1, & ! node id 6 + 2, & ! node id 8 + 3/) ! node id 9 + + ! Set the number of each type of element, plus the total number. + numQuadElems=1 + numTriElems=0 + numTotElems=numQuadElems+numTriElems + + ! Allocate and fill the element id array. + allocate(elemIds(numTotElems)) + elemIds=(/5/) + + ! Allocate and fill the element topology type array. + allocate(elemTypes(numTotElems)) + elemTypes=(/ESMF_MESHELEMTYPE_QUAD/) ! elem id 5 + + ! Allocate and fill the element connection type array. + allocate(elemConn(4*numQuadElems+3*numTriElems)) + elemConn=(/1,2,4,3/) ! elem id 5 + endif + + + ! Create Mesh structure in 1 step + mesh=ESMF_MeshCreate(parametricDim=2, spatialDim=2, & + coordSys=ESMF_COORDSYS_CART, & + nodeIds=nodeIds, nodeCoords=nodeCoords, & + nodeOwners=nodeOwners, elementIds=elemIds,& + elementTypes=elemTypes, elementConn=elemConn, & + rc=localrc) + + + ! After the creation we are through with the arrays, so they may be + ! deallocated. + deallocate(nodeIds) + deallocate(nodeCoords) + deallocate(nodeOwners) + deallocate(elemIds) + deallocate(elemTypes) + deallocate(elemConn) + + + ! At this point the mesh is ready to use. For example, as is + ! illustrated here, to have a field created on it. Note that + ! the Field only contains data for nodes owned by the current PET. + ! Please see Section "Create a Field from a Mesh" under Field + ! for more information on creating a Field on a Mesh. + field = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, rc=localrc) ++ +
+ +
+ + + 2.0 7 -------[8] 8 ------- 9 + | | | | + | 4 | | 5 | + | | | | + 1.0 4 ------ [5] 5 ------- 6 + + 0.0 1.0 1.0 2.0 + + PET 1 PET 0 + + + 1.0 [4] ----- [5] [5] ----- [6] + | | \ \ | + | 1 | 2 \ \ 3 | + | | \ \ | + 0.0 1 ------- 2 -----[3] 3 + + 0.0 1.0 1.0 2.0 + + PET 2 PET 3 + + Node Id labels at corners + Element Id labels in centers + |
+This example demonstrates the creation of a new Mesh which is a copy of an existing Mesh + with a new distribution of the original Mesh's nodes and elements. To create the new Mesh + in this manner the user needs two DistGrids. One to describe the new distribution of the nodes. + The other to describe the new distribution of the elements. In this example we create new + DistGrids from a list of indices. The DistGrids are then used in the redistribution + Mesh create interface which is overloaded to ESMF_MeshCreate(). In this example + we redistribute the Mesh created in the previous example (Section 33.3.4) + to the distribution pictured above. Note that for simplicity's sake, the position of the + Mesh in the diagram is basically the same, but the PET positions and node owners + have been changed. + +
+
+ ! Setup the new location of nodes and elements depending on the processor + if (localPet .eq. 0) then !!! This part only for PET 0 + allocate(elemIds(1)) + elemIds=(/5/) + + allocate(nodeIds(4)) + nodeIds=(/5,6,8,9/) + + else if (localPet .eq. 1) then !!! This part only for PET 1 + allocate(elemIds(1)) + elemIds=(/4/) + + allocate(nodeIds(2)) + nodeIds=(/7,4/) + + else if (localPet .eq. 2) then !!! This part only for PET 2 + allocate(elemIds(2)) + elemIds=(/1,2/) + + allocate(nodeIds(2)) + nodeIds=(/1,2/) + + else if (localPet .eq. 3) then !!! This part only for PET 3 + allocate(elemIds(1)) + elemIds=(/3/) + + allocate(nodeIds(1)) + nodeIds=(/3/) + + endif + + + ! Create new node DistGrid + nodedistgrid=ESMF_DistGridCreate(nodeIds, rc=localrc) + if (localrc .ne. ESMF_SUCCESS) rc=ESMF_FAILURE + + + ! Create new element DistGrid + elemdistgrid=ESMF_DistGridCreate(elemIds, rc=localrc) + if (localrc .ne. ESMF_SUCCESS) rc=ESMF_FAILURE + + + ! Can now deallocate distribution lists + deallocate(elemIds) + deallocate(nodeIds) + + + ! Create new redisted Mesh based on DistGrids + mesh2=ESMF_MeshCreate(mesh, & + nodalDistgrid=nodedistgrid, & + elementDistgrid=elemdistgrid, & + rc=localrc) + if (localrc .ne. ESMF_SUCCESS) rc=ESMF_FAILURE + + + ! At this point the mesh is ready to use. For example, as is + ! illustrated here, to have a field created on it. Note that + ! the Field only contains data for nodes owned by the current PET. + ! Please see Section "Create a Field from a Mesh" under Field + ! for more information on creating a Field on a Mesh. + field = ESMF_FieldCreate(mesh2, ESMF_TYPEKIND_R8, rc=localrc) ++ +
+ +
+ + + 2.0 * ------- * * ------- * + | | | | + | 3 | | 4 | + | | | | + 1.0 * ------- * * ------- * + + 0.0 1.0 1.0 2.0 + + PET 2 PET 3 + + + 1.0 * ------- * * ------- * + | | | | + | 1 | | 2 | + | | | | + 0.0 * ------- * * ------- * + + 0.0 1.0 1.0 2.0 + + PET 0 PET 1 + + Element Id labels in centers + |
+This example is intended to illustrate the creation of a small Mesh on multiple PETs using the easy element creation interface. + Here the Mesh consists of only one type of element, so we can use a slightly more convenient interface. In this interface the user + only needs to specify the element type once and the elementCornerCoords argument has three dimensions. This means that the corners for all + elements are not collapsed into a 1D list as happens with the next example. + +
+The figure above shows the Mesh to be created and it's distribution across the PETs. As in the previous diagrams, the element ids are in the centers. + Note that in the example code below the user doesn't specify the element ids. In this case, they are assigned sequentially + through the local elements on each PET starting with 1 for the first element on PET 0. (It isn't shown in the example below, but there is + an optional argument that enables the user to set the element ids if they wish.) + Unlike some of the previous examples of Mesh creation, here the user doesn't specify node ids or ownership, so that information is shown by a "*" in + the diagram. + +
+
+ ! Break up what's being set by PET + if (localPET .eq. 0) then !!! This part only for PET 0 + + ! Set the number of elements on this PET + numTotElems=1 + + ! Allocate and fill element corner coordinate array. + allocate(elemCornerCoords3(2,4,numTotElems)) + elemCornerCoords3(:,1,1)=(/0.0,0.0/) ! elem id 1 corner 1 + elemCornerCoords3(:,2,1)=(/1.0,0.0/) ! elem id 1 corner 2 + elemCornerCoords3(:,3,1)=(/1.0,1.0/) ! elem id 1 corner 3 + elemCornerCoords3(:,4,1)=(/0.0,1.0/) ! elem id 1 corner 4 + + else if (localPET .eq. 1) then !!! This part only for PET 1 + + ! Set the number of elements on this PET + numTotElems=1 + + ! Allocate and fill element corner coordinate array. + allocate(elemCornerCoords3(2,4,numTotElems)) + elemCornerCoords3(:,1,1)=(/1.0,0.0/) ! elem id 2 corner 1 + elemCornerCoords3(:,2,1)=(/2.0,0.0/) ! elem id 2 corner 2 + elemCornerCoords3(:,3,1)=(/2.0,1.0/) ! elem id 2 corner 3 + elemCornerCoords3(:,4,1)=(/1.0,1.0/) ! elem id 2 corner 4 + + + else if (localPET .eq. 2) then !!! This part only for PET 2 + + ! Set the number of elements on this PET + numTotElems=1 + + ! Allocate and fill element corner coordinate array. + allocate(elemCornerCoords3(2,4,numTotElems)) + elemCornerCoords3(:,1,1)=(/0.0,1.0/) ! elem id 3 corner 1 + elemCornerCoords3(:,2,1)=(/1.0,1.0/) ! elem id 3 corner 2 + elemCornerCoords3(:,3,1)=(/1.0,2.0/) ! elem id 3 corner 3 + elemCornerCoords3(:,4,1)=(/0.0,2.0/) ! elem id 3 corner 4 + + + else if (localPET .eq. 3) then !!! This part only for PET 3 + + ! Set the number of elements on this PET + numTotElems=1 + + ! Allocate and fill element corner coordinate array. + allocate(elemCornerCoords3(2,4,numTotElems)) + elemCornerCoords3(:,1,1)=(/1.0,1.0/) ! elem id 4 corner 1 + elemCornerCoords3(:,2,1)=(/2.0,1.0/) ! elem id 4 corner 2 + elemCornerCoords3(:,3,1)=(/2.0,2.0/) ! elem id 4 corner 3 + elemCornerCoords3(:,4,1)=(/1.0,2.0/) ! elem id 4 corner 4 + + endif + + ! Create Mesh structure in 1 step + mesh=ESMF_MeshCreate(parametricDim=2, & + coordSys=ESMF_COORDSYS_CART, & + elementType=ESMF_MESHELEMTYPE_QUAD, & + elementCornerCoords=elemCornerCoords3, & + rc=localrc) + + + ! After the creation we are through with the arrays, so they may be + ! deallocated. + deallocate(elemCornerCoords3) + + ! At this point the mesh is ready to use. For example, as is + ! illustrated here, to have a field created on it. Note that + ! the Field only contains data for elements owned by the current PET. + ! Please see Section "Create a Field from a Mesh" under Field + ! for more information on creating a Field on a Mesh. + field = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, & + meshloc=ESMF_MESHLOC_ELEMENT, rc=localrc) ++ +
+ +
+ + + 2.0 * ------- * * ------- * + | | | | + | 4 | | 5 | + | | | | + 1.0 * ------- * * ------- * + + 0.0 1.0 1.0 2.0 + + PET 2 PET 3 + + + 1.0 * ------- * * ------- * + | | | \ 3 | + | 1 | | \ | + | | | 2 \ | + 0.0 * ------- * * ------- * + + 0.0 1.0 1.0 2.0 + + PET 0 PET 1 + + Element Id labels in centers + |
+This example is intended to illustrate the creation of a small Mesh on multiple PETs using the easy element creation interface. + In this example, the Mesh being created contains elements of multiple types. + To support the specification of a set of elements containing different types and thus different + numbers of corners, the elementCornerCoords argument has the + corner and element dimensions collapsed together into one dimension. + +
+The figure above shows the Mesh to be created and it's distribution across the PETs. As in the previous diagrams, the element ids are in the centers. + Note that in the example code below the user doesn't specify the element ids. In this case, they are assigned sequentially + through the local elements on each PET starting with 1 for the first element on PET 0. (It isn't shown in the example below, but there is + an optional argument that enables the user to set the element ids if they wish.) + Unlike some of the previous examples of Mesh creation, here the user doesn't specify node ids or ownership, so that information is shown by a "*" in + the diagram. + +
+
+ ! Break up what's being set by PET + if (localPET .eq. 0) then !!! This part only for PET 0 + + ! Set the number of each type of element, plus the total number. + numQuadElems=1 + numTriElems=0 + numTotElems=numQuadElems+numTriElems + numElemCorners=4*numQuadElems+3*numTriElems + + ! Allocate and fill the element type array. + allocate(elemTypes(numTotElems)) + elemTypes=(/ESMF_MESHELEMTYPE_QUAD/) ! elem id 1 + + ! Allocate and fill element corner coordinate array. + allocate(elemCornerCoords2(2,numElemCorners)) + elemCornerCoords2(:,1)=(/0.0,0.0/) ! elem id 1 corner 1 + elemCornerCoords2(:,2)=(/1.0,0.0/) ! elem id 1 corner 2 + elemCornerCoords2(:,3)=(/1.0,1.0/) ! elem id 1 corner 3 + elemCornerCoords2(:,4)=(/0.0,1.0/) ! elem id 1 corner 4 + + else if (localPET .eq. 1) then !!! This part only for PET 1 + + ! Set the number of each type of element, plus the total number. + numQuadElems=0 + numTriElems=2 + numTotElems=numQuadElems+numTriElems + numElemCorners=4*numQuadElems+3*numTriElems + + ! Allocate and fill the element type array. + allocate(elemTypes(numTotElems)) + elemTypes=(/ESMF_MESHELEMTYPE_TRI, & ! elem id 2 + ESMF_MESHELEMTYPE_TRI/) ! elem id 3 + + ! Allocate and fill element corner coordinate array. + allocate(elemCornerCoords2(2,numElemCorners)) + elemCornerCoords2(:,1)=(/1.0,0.0/) ! elem id 2 corner 1 + elemCornerCoords2(:,2)=(/2.0,0.0/) ! elem id 2 corner 2 + elemCornerCoords2(:,3)=(/1.0,1.0/) ! elem id 2 corner 3 + elemCornerCoords2(:,4)=(/2.0,0.0/) ! elem id 3 corner 1 + elemCornerCoords2(:,5)=(/2.0,1.0/) ! elem id 3 corner 2 + elemCornerCoords2(:,6)=(/1.0,1.0/) ! elem id 3 corner 3 + + else if (localPET .eq. 2) then !!! This part only for PET 2 + + ! Set the number of each type of element, plus the total number. + numQuadElems=1 + numTriElems=0 + numTotElems=numQuadElems+numTriElems + numElemCorners=4*numQuadElems+3*numTriElems + + + ! Allocate and fill the element type array. + allocate(elemTypes(numTotElems)) + elemTypes=(/ESMF_MESHELEMTYPE_QUAD/) ! elem id 4 + + ! Allocate and fill element corner coordinate array. + allocate(elemCornerCoords2(2,numElemCorners)) + elemCornerCoords2(:,1)=(/0.0,1.0/) ! elem id 4 corner 1 + elemCornerCoords2(:,2)=(/1.0,1.0/) ! elem id 4 corner 2 + elemCornerCoords2(:,3)=(/1.0,2.0/) ! elem id 4 corner 3 + elemCornerCoords2(:,4)=(/0.0,2.0/) ! elem id 4 corner 4 + + + else if (localPET .eq. 3) then !!! This part only for PET 3 + + ! Set the number of each type of element, plus the total number. + numQuadElems=1 + numTriElems=0 + numTotElems=numQuadElems+numTriElems + numElemCorners=4*numQuadElems+3*numTriElems + + ! Allocate and fill the element type array. + allocate(elemTypes(numTotElems)) + elemTypes=(/ESMF_MESHELEMTYPE_QUAD/) ! elem id 5 + + ! Allocate and fill element corner coordinate array. + allocate(elemCornerCoords2(2,numElemCorners)) + elemCornerCoords2(:,1)=(/1.0,1.0/) ! elem id 5 corner 1 + elemCornerCoords2(:,2)=(/2.0,1.0/) ! elem id 5 corner 2 + elemCornerCoords2(:,3)=(/2.0,2.0/) ! elem id 5 corner 3 + elemCornerCoords2(:,4)=(/1.0,2.0/) ! elem id 5 corner 4 + + endif + + ! Create Mesh structure in 1 step + mesh=ESMF_MeshCreate(parametricDim=2, & + coordSys=ESMF_COORDSYS_CART, & + elementTypes=elemTypes, & + elementCornerCoords=elemCornerCoords2, & + rc=localrc) + + + ! After the creation we are through with the arrays, so they may be + ! deallocated. + deallocate(elemTypes) + deallocate(elemCornerCoords2) + + ! At this point the mesh is ready to use. For example, as is + ! illustrated here, to have a field created on it. Note that + ! the Field only contains data for elements owned by the current PET. + ! Please see Section "Create a Field from a Mesh" under Field + ! for more information on creating a Field on a Mesh. + field = ESMF_FieldCreate(mesh, ESMF_TYPEKIND_R8, & + meshloc=ESMF_MESHLOC_ELEMENT, rc=localrc) ++ +
+ +
+ESMF supports the creation of a Mesh from three grid file formats: the SCRIP format 12.8.1, the + ESMF format 12.8.2 or the + proposed CF unstructured grid UGRID format 12.8.4. All three of these grid file formats + are NetCDF files. + +
+When creating a Mesh from a SCRIP format file, there are a number of options to control the output Mesh. + The data is located at the center of the grid cell in a SCRIP grid; whereas + the data is located at the corner of a cell in an ESMF Mesh object. Therefore, + we create a Mesh object by default by constructing a "dual" mesh using the coordinates in the file. + If the user wishes to not construct the dual mesh, the optional argument convertToDual may be + used to control this behavior. When comvertToDual is + set to .false. the Mesh constructed from the file will not be the dual. This is necessary when using the + Mesh as part of a conservative regridding operation in the ESMF_FieldRegridStore() call, so the + weights are properly generated for the cell centers in the file. + +
+The following example code depicts how to create a Mesh using a SCRIP file. Note that + you have to set the fileformat to ESMF_FILEFORMAT_SCRIP. +
+
+ mesh = ESMF_MeshCreate(filename="data/ne4np4-pentagons.nc", & + fileformat=ESMF_FILEFORMAT_SCRIP, rc=localrc) ++ +
+As mentioned above ESMF also supports creating Meshes from the ESMF format. + The ESMF format works better with the methods used to create an ESMF Mesh object, so less conversion needs + to be done to create a Mesh, and thus this format is more efficient than SCRIP to use within ESMF. + The ESMF format is also more general than the SCRIP format because it supports higher dimension coordinates and more general + topologies. Currently, ESMF_MeshCreate() does not support conversion to a dual mesh for this format. All regrid methods + are supported on Meshes in this format. + +
+Here is an example of creating a Mesh from an ESMF unstructured grid file. Note that you have to set the fileformat to + ESMF_FILEFORMAT_ESMFMESH. +
+
+ mesh = ESMF_MeshCreate(filename="data/ne4np4-esmf.nc", & + fileformat=ESMF_FILEFORMAT_ESMFMESH, & + rc=localrc) ++ +
+ +
+This example demostrates how to create a ESMF_Mesh object representing a cubed sphere grid with + identical regular decomposition for every tile. + In this example, the tile resolution is 45, so there will be a total 45x45x6=12150 elements in the mesh. + nx and ny are the regular decomposition of each tile. + The total number of DEs is nx x ny x 6. If the number of PETs are less than the total + number of DEs, the DEs will be distributed to the PETs using the default cyclic distribution. +
+
+ ! Decompose each tile into 2 x 1 blocks + nx=2 + ny=1 + + ! Create Mesh + mesh = ESMF_MeshCreateCubedSphere(tileSize=45, nx=nx,ny=ny, rc=localrc) ++ +
+ +
+There are two different levels that the memory in a Mesh can be removed. The first of these is the standard destroy call, + ESMF_MeshDestroy(). As with other classes, this call removes all memory associated with the object, and afterwards + the object can not be used further (i.e. should not be used in any methods). The second, which is unique to Mesh, is the + ESMF_MeshFreeMemory() call. This call removes the connection and coordinate information associated with the Mesh, but + leaves the distgrid information. The coordinate and connection information held in the Mesh can consume a large amount of memory + for a big Mesh, so using this call can very significantly reduce the amount of memory used. However, once this method + has been used on a Mesh there are some restriction on what may be done with it. Once a Mesh has had its memory freed using this method, + any Field built on the Mesh can no longer be used as part of an ESMF_FieldRegridStore() call. However, because the distgrid + information is still part of the Mesh, Fields built on such a Mesh can still be part of an ESMF_FieldRegrid() + call (where the routehandle was generated previous to the ESMF_MeshFreeMemory() operation). Fields may also + still be created on these Meshes. The following short piece of code illustrates the use of this call. + +
+
+ ! Here a Field built on a mesh may be used + ! as part of a ESMF_FieldRegridStore() call + + ! This call removes connection and coordinate + ! information, significantly reducing the memory used by + ! mesh, but limiting what can be done with it. + call ESMF_MeshFreeMemory(mesh, rc=localrc) + + ! Here a new Field may be built on mesh, or + ! a field built on a mesh may be used as part + ! of an ESMF_FieldRegrid() call + + ! Destroy the mesh + call ESMF_MeshDestroy(mesh, rc=localrc) + + ! Here mesh can't be used for anything ++ +
+ +
+There are two types of masking available in Mesh: node masking and element masking. These both work + in a similar manner, but vary slightly in the details of setting the mask information during mesh creation. + +
+For node masking, the mask information is set using the nodeMask argument to either ESMF_MeshCreate() or + ESMF_MeshAddNodes(). When a regrid store method is called (e.g. ESMF_FieldRegridStore()) the mask values arguments + (srcMaskValues and dstMaskValues) can + then be used to indicate which particular values set in the nodeMask array indicate that the node should be masked. For example, when + calling ESMF_FieldRegridStore() if dstMaskValues has been set to 1, then any node in the destination Mesh whose + corresponding nodeMask value is 1 will be masked out (a node with any other value than 1 will not be masked). + +
+For element masking, the mask information is set using the elementMask argument to either ESMF_MeshCreate() or + ESMF_MeshAddElements(). In a similar manner to node masking, when a regrid store method is called (e.g. ESMF_FieldRegridStore()) + the mask values arguments + (srcMaskValues and dstMaskValues) can + then be used to indicate which particular values set in the elementMask array indicate that the element should be masked. For example, when + calling ESMF_FieldRegridStore() if dstMaskValues has been set to 1, then any element in the destination Mesh whose + corresponding elementMask value is 1 will be masked out (an element with any other value than 1 will not be masked). + +
+ +
+ + + 2.0 7 ------- 8 [8] ------ 9 + | | | | + | 4 | | 5 | + | | | | + 1.0 [4] ----- [5] [5] ----- [6] + + 0.0 1.0 1.0 2.0 + + PET 2 PET 3 + + + 1.0 4 ------- 5 [5] ------ 6 + | | | \ 3 | + | 1 | | \ | + | | | 2 \ | + 0.0 1 ------- 2 [2] ------ 3 + + 0.0 1.0 1.0 2.0 + + PET 0 PET 1 + + Node Id labels at corners + Element Id labels in centers + |
+This section illustrates the process of setting up halo communication for a Field built on the nodes of a Mesh. + The Mesh used in this example is the one that was created in section 33.3.4. The diagram for + that Mesh is repeated above for convenience's sake. The halo method used here is the one described in + section 28.2.16, but made more specific to the case of a Mesh. + This example shows how to set up haloing for nodes which are owned by another processor (e.g. the node with id + 5 on PET 1 above). However, it could be expanded to halo other nodes simply by including them in the + halo arrays below on the PET where their values are needed. + +
+The first step in setting up the halo communication is to create arrays containing + the ids of the haloed nodes on the PETs where they + are needed. + +
+The following illustrates that for the Mesh diagramed above. + +
+
+ ! Create halo lists based on PET id. + if (localPET .eq. 0) then !!! This part only for PET 0 + + ! Allocate and fill the halo list. + allocate(haloSeqIndexList(0)) ! There are no haloed points on PET 0 + + else if (localPET .eq. 1) then !!! This part only for PET 1 + + ! Allocate and fill the halo list. + allocate(haloSeqIndexList(2)) + haloSeqIndexList=(/2,5/) + + else if (localPET .eq. 2) then !!! This part only for PET 2 + + ! Allocate and fill the halo list. + allocate(haloSeqIndexList(2)) + haloSeqIndexList=(/4,5/) + + else if (localPET .eq. 3) then !!! This part only for PET 3 + + ! Allocate and fill the halo list. + allocate(haloSeqIndexList(3)) + haloSeqIndexList=(/5,6,8/) + + endif ++ +
+The next step is to create an ESMF Array with a halo region to hold the data being haloed. + +
+
+ ! Get node DistGrid from the Mesh. + call ESMF_MeshGet(mesh, nodalDistgrid=nodeDistgrid, rc=localrc) + + ! Create an ESMF Array with a halo region from a node DistGrid. + array=ESMF_ArrayCreate(nodeDistgrid, typekind=ESMF_TYPEKIND_R8, & + haloSeqIndexList=haloSeqIndexList, rc=localrc) ++ +
+Note that currently the halo data is stored at the end of the Array data on each PET in the order specified + by the haloSeqIndexList argument (e.g. for PET 3 the halo information will be in the order 5,6,8 + at the end of the piece of array on PET 3). This means that if the halo information needs to be in the order of + nodes specified when you create the Mesh, then the nodes owned by another processor need to + be at the end of the node information when the Mesh is created (e.g. when creating + the piece of the Mesh on PET 3, then nodes 5,6,8 would need to be at the end of the node information lists). + +
+At this point haloing could be done on the ESMF Array by using the ESMF_ArrayHaloStore() call + followed by ESMF_ArrayHalo(). However, in this example we wrap the Array in an ESMF Field. + This allows it to be used in Field specific calls (e.g. ESMF_FieldRegridStore()) as well + as for haloing. + +
+
+ ! Wrap the ESMF Array in a Field created on the nodes of the Mesh. + field=ESMF_FieldCreate(mesh, array=array, & + meshLoc=ESMF_MESHLOC_NODE, rc=localrc) ++ +
+We can now proceed with haloing the Field by using the ESMF_FieldHaloStore() call to + create a RouteHandle, and then the ESMF_FieldHalo() call to apply the RouteHandle. Note + that once the RouteHandle has been created it can be applied repeatedly to redo the halo + communication as data changes in the Field. + +
+
+ ! Create the RouteHandle for the halo communication. + call ESMF_FieldHaloStore(field, routehandle=haloHandle, rc=localrc) + + ! Can repeatedly do halo as data in field changes. + ! do t=... + + ! Data set in non-halo field locations. + + ! Do the halo communication. + call ESMF_FieldHalo(field, routehandle=haloHandle, rc=localrc) + + ! Halo locations now filled in field. + + ! enddo + + ! After its last use the RouteHandle can be released. + call ESMF_FieldHaloRelease(haloHandle, rc=localrc) ++ +
+
+ ! The Field can now be destroyed. + call ESMF_FieldDestroy(field, rc=localrc) + + ! The Array can now be destroyed. + call ESMF_ArrayDestroy(array, rc=localrc) ++ +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + mesh1 = mesh2 +ARGUMENTS: +
type(ESMF_Mesh) :: mesh1 + type(ESMF_Mesh) :: mesh2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign mesh1 as an alias to the same ESMF Mesh object in memory + as mesh2. If mesh2 is invalid, then mesh1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (mesh1 == mesh2) then ... endif + OR + result = (mesh1 == mesh2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh1 + type(ESMF_Mesh), intent(in) :: mesh2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether mesh1 and mesh2 are valid aliases to the same ESMF + Mesh object in memory. For a more general comparison of two ESMF Meshes, + going beyond the simple alias test, the ESMF_MeshMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (mesh1 /= mesh2) then ... endif + OR + result = (mesh1 /= mesh2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh1 + type(ESMF_Mesh), intent(in) :: mesh2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether mesh1 and mesh2 are not valid aliases to the + same ESMF Mesh object in memory. For a more general comparison of two ESMF + Meshes, going beyond the simple alias test, the ESMF_MeshMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_MeshAddElements(mesh, elementIds, elementTypes, & + elementConn, elementMask, elementArea, elementCoords, & + elementDistgrid, rc) +ARGUMENTS: +
type(ESMF_Mesh), intent(inout) :: mesh + integer, intent(in) :: elementIds(:) + integer, intent(in) :: elementTypes(:) + integer, intent(in) :: elementConn(:) + integer, intent(in), optional :: elementMask(:) + real(ESMF_KIND_R8), intent(in), optional :: elementArea(:) + real(ESMF_KIND_R8), intent(in), optional :: elementCoords(:) + type(ESMF_DistGrid), intent(in), optional :: elementDistgrid + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call is the third and last part of the three part mesh create + sequence and should be called after the mesh is created with ESMF_MeshCreate() + (33.4.6) + and after the nodes are added with ESMF_MeshAddNodes() (33.4.5). + This call adds the elements to the + mesh and finalizes the create. After this call the Mesh is usable, for + example a Field may be built on the created Mesh object and + this Field may be used in a ESMF_FieldRegridStore() call. + +
+The parameters to this call elementIds, elementTypes, and + elementConn describe the elements to be created. The description + for a particular element lies at the same index location in elementIds + and elementTypes. Each entry in elementConn consists of the list of + nodes used to create that element, so the connections for element in the + elementIds array will start at + in elementConn. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_MeshAddNodes(mesh, nodeIds, nodeCoords, nodeOwners, & + nodeMask, nodalDistgrid, rc) +ARGUMENTS: +
type(ESMF_Mesh), intent(inout) :: mesh + integer, intent(in) :: nodeIds(:) + real(ESMF_KIND_R8), intent(in) :: nodeCoords(:) + integer, intent(in), optional :: nodeOwners(:) + integer, intent(in), optional :: nodeMask(:) + type(ESMF_DistGrid), intent(in), optional :: nodalDistgrid + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call is the second part of the three part mesh create + sequence and should be called after the mesh's dimensions are set + using ESMF_MeshCreate() (33.4.6). + This call adds the nodes to the + mesh. The next step is to call ESMF_MeshAddElements() (33.4.4). + +
+The parameters to this call nodeIds, nodeCoords, and + nodeOwners describe the nodes to be created on this PET. + The description for a particular node lies at the same index location in + nodeIds and nodeOwners. Each entry + in nodeCoords consists of spatial dimension coordinates, so the coordinates + for node in the nodeIds array will start at +. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MeshCreate() + function ESMF_MeshCreate3Part(parametricDim, spatialDim, coordSys, name, rc) +RETURN VALUE: +
type(ESMF_Mesh) :: ESMF_MeshCreate3Part +ARGUMENTS: +
integer, intent(in) :: parametricDim + integer, intent(in) :: spatialDim + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call is the first part of the three part mesh create + sequence. This call sets the dimension of the elements in the mesh + (parametricDim) and the number of coordinate dimensions in the mesh + (spatialDim). The next step is to call ESMF_MeshAddNodes() (33.4.5) + to add the nodes and then ESMF_MeshAddElements() (33.4.4) to add + the elements and finalize the mesh. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MeshCreate() + function ESMF_MeshCreate1Part(parametricDim, spatialDim, & + nodeIds, nodeCoords, nodeOwners, nodeMask, nodalDistgrid, & + elementIds, elementTypes, elementConn, & + elementMask, elementArea, elementCoords, & + elementDistgrid, coordSys, name, rc) +RETURN VALUE: +
type(ESMF_Mesh) :: ESMF_MeshCreate1Part +ARGUMENTS: +
integer, intent(in) :: parametricDim + integer, intent(in) :: spatialDim + integer, intent(in) :: nodeIds(:) + real(ESMF_KIND_R8), intent(in) :: nodeCoords(:) + integer, intent(in), optional :: nodeOwners(:) + integer, intent(in), optional :: nodeMask(:) + type(ESMF_DistGrid), intent(in), optional :: nodalDistgrid + integer, intent(in) :: elementIds(:) + integer, intent(in) :: elementTypes(:) + integer, intent(in) :: elementConn(:) + integer, intent(in), optional :: elementMask(:) + real(ESMF_KIND_R8), intent(in), optional :: elementArea(:) + real(ESMF_KIND_R8), intent(in), optional :: elementCoords(:) + type(ESMF_DistGrid), intent(in), optional :: elementDistgrid + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a Mesh object in one step. After this call the Mesh is usable, for + example, a Field may be built on the created Mesh object and + this Field may be used in a ESMF_FieldRegridStore() call. + +
+This call sets the dimension of the elements in the mesh + (parametricDim) and the number of coordinate dimensions in the mesh + (spatialDim). It then creates the nodes, and + then creates the elements by connecting together the nodes. + +
+The parameters to this call nodeIds, nodeCoords, and + nodeOwners describe the nodes to be created on this PET. + The description for a particular node lies at the same index location in + nodeIds and nodeOwners. Each entry + in nodeCoords consists of spatial dimension coordinates, so the coordinates + for node in the nodeIds array will start at +. + +
+The parameters to this call elementIds, elementTypes, and + elementConn describe the elements to be created. The description + for a particular element lies at the same index location in elementIds + and elementTypes. Each entry in elementConn consists of the list of + nodes used to create that element, so the connections for element in the + elementIds array will start at + in elementConn. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MeshCreate() + function ESMF_MeshCreateFromGrid(grid, name, rc) +RETURN VALUE: +
type(ESMF_Mesh) :: ESMF_MeshCreateFromGrid +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF Mesh from an ESMF Grid. This method creates the elements of + the Mesh from the cells of the Grid, and the nodes of the Mesh from the corners of + the Grid. Corresponding locations in the Grid and new Mesh will have the same + coordinates, sequence indices, masking, and area information. + +
+This method currently only works for 2D Grids. In addition, this method requires + the input Grid to have coordinates in the corner stagger location. + +
+
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MeshCreate() + function ESMF_MeshCreateFromFile(filename, fileformat, & + convertToDual, addUserArea, maskFlag, varname, & + nodalDistgrid, elementDistgrid, & + coordSys, name, rc) +RETURN VALUE: +
type(ESMF_Mesh) :: ESMF_MeshCreateFromFile +ARGUMENTS: +
character(len=*), intent(in) :: filename + type(ESMF_FileFormat_Flag), intent(in) :: fileformat + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: convertToDual + logical, intent(in), optional :: addUserArea + type(ESMF_MeshLoc), intent(in), optional :: maskFlag + character(len=*), intent(in), optional :: varname + type(ESMF_DistGrid), intent(in), optional :: nodalDistgrid + type(ESMF_DistGrid), intent(in), optional :: elementDistgrid + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a Mesh from a file. Provides options to convert to 3D and in the case of SCRIP + format files, allows the dual of the mesh to be created. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MeshCreate() + function ESMF_MeshCreateRedist(mesh, nodalDistgrid, & + elementDistgrid, vm, name, rc) +RETURN VALUE: +
type(ESMF_Mesh) :: ESMF_MeshCreateRedist +ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DistGrid), intent(in), optional :: nodalDistgrid + type(ESMF_DistGrid), intent(in), optional :: elementDistgrid + type(ESMF_VM), intent(in), optional :: vm + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a copy of an existing Mesh with a new distribution. Information + in the Mesh such as connections, coordinates, areas, masks, etc. are + automatically redistributed to the new Mesh. To redistribute + data in Fields built on the original Mesh create a Field on the new Mesh + and then use the Field redistribution functionality + (ESMF_FieldRedistStore(), etc.). The equivalent methods + can also be used for data in FieldBundles. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MeshCreate() + function ESMF_MeshCreateEasyElems1Type(parametricDim, coordSys, & + elementIds, elementType, elementCornerCoords, & + elementMask, elementArea, elementCoords, & + elementDistgrid, rc) +RETURN VALUE: +
type(ESMF_Mesh) :: ESMF_MeshCreateEasyElems1Type +ARGUMENTS: +
integer, intent(in) :: parametricDim + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + integer, intent(in), optional :: elementIds(:) + integer, intent(in) :: elementType + real(ESMF_KIND_R8), intent(in) :: elementCornerCoords(:,:,:) + integer, intent(in), optional :: elementMask(:) + real(ESMF_KIND_R8), intent(in), optional :: elementArea(:) + real(ESMF_KIND_R8), intent(in), optional :: elementCoords(:,:) + type(ESMF_DistGrid), intent(in), optional :: elementDistgrid + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a Mesh object in one step by just specifying the corner coordinates of each element. + Internally these corners are turned into nodes forming the outside edges of the elements. + This call assumes that each element is the same type to make the specification of the elements + a bit easier. + After this call the Mesh is usable, for + example, a Field may be built on the created Mesh object and + this Field may be used in ESMF_FieldRegridStore(). However, the Mesh created by this + call consists of a set of disconnected elements, and so shouldn't be used in a situation where + connections between elements are necessary (e.g. bilinear regridding on element centers, patch regridding, + or second-order conservative regridding). + +
+This call sets the dimension of the elements in the Mesh + via parametricDim and the number of coordinate dimensions in the mesh + is determined from the first dimension of elementCornerCoords. + +
+The parameters to this call elementIds, elementTypes, and + elementCornerCoords describe the elements to be created. The description + for a particular element lies at the same index location in elementIds + and elementTypes. The argument elementCornerCoords contains the coordinates of the + corners used to create each element. The first dimension of this argument are across the coordinate dimensions. + The second dimension of this argument is across the corners of a + particular element. The last dimension of this argument is across the list + of elements on this PET, so the coordinates of corner c in element e on this PET + would be in elementCornerCoords(:,c,e). + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_MeshCreate() + function ESMF_MeshCreateEasyElemsGen(parametricDim, coordSys, & + elementIds, elementTypes, elementCornerCoords, & + elementMask, elementArea, elementCoords, & + elementDistgrid, rc) +RETURN VALUE: +
type(ESMF_Mesh) :: ESMF_MeshCreateEasyElemsGen +ARGUMENTS: +
integer, intent(in) :: parametricDim + type(ESMF_CoordSys_Flag), intent(in), optional :: coordSys + integer, intent(in), optional :: elementIds(:) + integer, intent(in) :: elementTypes(:) + real(ESMF_KIND_R8), intent(in) :: elementCornerCoords(:,:) + integer, intent(in), optional :: elementMask(:) + real(ESMF_KIND_R8), intent(in), optional :: elementArea(:) + real(ESMF_KIND_R8), intent(in), optional :: elementCoords(:,:) + type(ESMF_DistGrid), intent(in), optional :: elementDistgrid + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a Mesh object in one step by just specifying the corner coordinates of each element. + Internally these corners are turned into nodes forming the outside edges of the elements. + After this call the Mesh is usable, for + example, a Field may be built on the created Mesh object and + this Field may be used in ESMF_FieldRegridStore(). However, the Mesh created by this + call consists of a set of disconnected elements, and so shouldn't be used in a situation where + connections between elements are necessary (e.g. bilinear regridding on element centers, patch regridding, + or second-order conservative regridding). + +
+This call sets the dimension of the elements in the Mesh + via parametricDim and the number of coordinate dimensions in the mesh + is determined from the first dimension of elementCornerCoords. + +
+The parameters to this call elementIds, elementTypes, and + elementCornerCoords describe the elements to be created. The description + for a particular element lies at the same index location in elementIds + and elementTypes. The argument elementCornerCoords consists of a list of + all the corners used to create all the elements, so the corners for element in the + elementTypes array will start at + in elementCornerCoords. + +
+This call is collective across the current VM. + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_MeshCreateCubedSphere(tileSize, nx, ny, name, rc) +RETURN VALUE: +
type(ESMF_Mesh) :: ESMF_MeshCreateCubedSphere +ARGUMENTS: +
integer, intent(in) :: tileSize + integer, intent(in) :: nx + integer, intent(in) :: ny + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a ESMF_Mesh object for a cubed sphere grid using identical regular decomposition for every tile. + The grid coordinates are generated based on the algorithm used by GEOS-5, The tile resolution is defined by + tileSize. Each tile is decomposed into nx x ny blocks and the total number of DEs used + is nx x ny x 6. If the total PET is not equal to the number of DEs, the DEs are distributed + into PETs in the default cyclic distribution. Internally, the nodes and the elements from multiple DEs are + collapsed into a 1D array. Therefore, the nodal distgrid or the element distgrid attached to the Mesh object + is always a one DE arbitrarily distributed distgrid. The sequential indices of the nodes and the elements + are derived based on the location of the point in the Cubed Sphere grid. If an element is located at (x, y) of + tile n. Its sequential index would be (n-1)*tileSize*tileSize+(y-1)*tileSize+x. If it is a node, its + sequential index would be (n-1)*(tileSize+1)*(tileSize+1)+(y-1)*(tileSize+1)+x. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_MeshDestroy(mesh, noGarbage, rc) +RETURN VALUE: +
+ARGUMENTS: +
type(ESMF_Mesh), intent(inout) :: mesh + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This call removes internal memory associated with mesh. + After this call mesh will no longer be usable. + ! + ! The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_MeshEmptyCreate(nodalDistgrid, elementDistgrid, name, rc) +RETURN VALUE: +
type(ESMF_Mesh) :: ESMF_MeshEmptyCreate +ARGUMENTS: +
type(ESMF_DistGrid), intent(in), optional :: elementdistgrid + type(ESMF_DistGrid), intent(in), optional :: nodalDistgrid + character(len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a Mesh to hold distribution information (i.e. Distgrids). + Such a mesh will have no coordinate or connectivity information stored. + Aside from holding distgrids the Mesh created by this call can't be used in other + ESMF functionality (e.g. it can't be used to create a Field or in regridding). + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_MeshFreeMemory(mesh, rc) +RETURN VALUE: +
+ARGUMENTS: +
type(ESMF_Mesh), intent(inout) :: mesh + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call removes the portions of mesh which contain connection and coordinate + information. After this call, Fields build on mesh will no longer be usable + as part of an ESMF_FieldRegridStore() operation. However, after this call + Fields built on mesh can still be used in an ESMF_FieldRegrid() + operation if the routehandle was generated beforehand. New Fields may also + be built on mesh after this call. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_MeshGet(mesh, parametricDim, spatialDim, & + nodeCount, nodeIds, nodeCoords, nodeOwners, & + nodeMaskIsPresent, nodeMask,& + elementCount, elementIds, elementTypes, & + elementConnCount, elementConn, & + elementMaskIsPresent,elementMask, & + elementAreaIsPresent, elementArea, & + elementCoordsIsPresent, elementCoords, & + nodalDistgridIsPresent, nodalDistgrid, & + elementDistgridIsPresent, elementDistgrid, & + numOwnedNodes, ownedNodeCoords, & + numOwnedElements, ownedElemCoords, & + elemMaskArray, elemAreaArray, & + isMemFreed, coordSys, status, name, rc) +RETURN VALUE: +
+ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh + integer, intent(out), optional :: parametricDim + integer, intent(out), optional :: spatialDim + integer, intent(out), optional :: nodeCount + integer, intent(out), optional :: nodeIds(:) + real(ESMF_KIND_R8), intent(out), optional :: nodeCoords(:) + integer, intent(out), optional :: nodeOwners(:) + logical, intent(out), optional :: nodeMaskIsPresent + integer, intent(out), optional :: nodeMask(:) + integer, intent(out), optional :: elementCount + integer, intent(out), optional :: elementIds(:) + integer, intent(out), optional :: elementTypes(:) + integer, intent(out), optional :: elementConnCount + integer, intent(out), optional :: elementConn(:) + logical, intent(out), optional :: elementMaskIsPresent + integer, intent(out), optional :: elementMask(:) + logical, intent(out), optional :: elementAreaIsPresent + real(ESMF_KIND_R8), intent(out), optional :: elementArea(:) + logical, intent(out), optional :: elementCoordsIsPresent + real(ESMF_KIND_R8), intent(out), optional :: elementCoords(:) + logical, intent(out), optional :: nodalDistgridIsPresent + type(ESMF_DistGrid), intent(out), optional :: nodalDistgrid + logical, intent(out), optional :: elementDistgridIsPresent + type(ESMF_DistGrid), intent(out), optional :: elementDistgrid + integer, intent(out), optional :: numOwnedNodes + real(ESMF_KIND_R8), intent(out), optional :: ownedNodeCoords(:) + integer, intent(out), optional :: numOwnedElements + real(ESMF_KIND_R8), intent(out), optional :: ownedElemCoords(:) + logical, intent(out), optional :: isMemFreed + type(ESMF_Array), intent(inout), optional :: elemMaskArray + type(ESMF_Array), intent(inout), optional :: elemAreaArray + type(ESMF_CoordSys_Flag), intent(out), optional :: coordSys + type(ESMF_MeshStatus_Flag),intent(out), optional :: status + character(len=*), intent(out), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get various information from a mesh. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_MeshGetMOAB(moabOn, rc) +ARGUMENTS: +
logical, intent(out) :: moabOn + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This method is only temporary. It was created to enable testing during the stage in ESMF development while + we have two internal mesh implementations. At some point it will be removed. + +
+This method can be used to check whether the MOAB library is being used + to hold the internal structure of the Mesh. When set to .true. the following + Mesh create calls create a Mesh using MOAB internally. When set to .false. the following + Mesh create calls use the ESMF native internal mesh respresentation. Note that ESMF Meshes + created on MOAB are only supported in a limited set of operations and should be used + with caution as they haven't yet been tested as thoroughly as the native version. + Also, operations that use a pair of Meshes (e.g. regrid weight generation) are only supported between + meshes of the same type (e.g. you can regrid between two MOAB meshes, but not between a MOAB and + a native mesh). + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_MeshIsCreated(mesh, rc) +RETURN VALUE: +
logical :: ESMF_MeshIsCreated +ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the mesh has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_MeshSet(mesh, & + elementMask, elementArea, rc) +RETURN VALUE: +
+ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh + integer, intent(in), optional :: elementMask(:) + real(ESMF_KIND_R8), intent(in), optional :: elementArea(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This call allows the user to change the set of information that it's legal to alter after + a mesh has been created. Currently, this call requires that the information has already + been added to the mesh during creation. For example, you can only change the element mask + information, if the mesh was initially created with element masking. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_MeshSetMOAB(moabOn, rc) +ARGUMENTS: +
logical, intent(in) :: moabOn + integer, intent(out) , optional :: rc ++DESCRIPTION: +
+This method is only temporary. It was created to enable testing during the stage in ESMF development while + we have two internal mesh implementations. At some point it will be removed. + +
+This method can be employed to turn on or off using the MOAB library + to hold the internal structure of the Mesh. When set to .true. the following + Mesh create calls create a Mesh using MOAB internally. When set to .false. the following + Mesh create calls use the ESMF native internal mesh respresentation. Note that ESMF Meshes + created on MOAB are only supported in a limited set of operations and should be used + with caution as they haven't yet been tested as thoroughly as the native version. + Also, operations that use a pair of Meshes (e.g. regrid weight generation) are only supported between + meshes of the same type (e.g. you can regrid between two MOAB meshes, but not between a MOAB and + a native mesh). + +
+
+ + +
+An exchange grid represents the 2D boundary layer usually between the +atmosphere on one side and ocean and land on the other in an Earth +system model. There are dynamical and thermodynamical processes on +either side of the boundary layer and on the boundary layer itself. +The boundary layer exchanges fluxes from either side and adjusts +boundary conditions for the model components involved. For climate modeling, +it is critical that the fluxes transferred by the boundary layer are +conservative. + +
+The ESMF exchange grid is implemented as the ESMF_XGrid class. +Internally it's represented by a collection of the intersected cells +between atmosphere and ocean/land[17] grids. +These polygonal cells can have irregular shapes +and can be broken down into triangles facilitating a finite element +approach. + +
+There are two ways to create an ESMF_XGrid object from +user supplied information. The first way to create an ESMF_XGrid takes +two lists of ESMF_Grid or ESMF_Mesh that represent the model component grids on +either side of the exchange grid. From the two lists of ESMF_Grid or ESMF_Mesh, +information required for flux exchange calculation between any pair of the +model components from either side of the exchange grid is computed. In addition, the +internal representation of the ESMF_XGrid is computed and can be optionally stored +as an ESMF_Mesh. This internal representation is the collection of the intersected +polygonal cells as a result of merged ESMF_Meshes from both sides of the exchange grid. +ESMF_Field can be created on the ESMF_XGrid and used for weight generation +and regridding as the internal representation in the ESMF_XGrid has +a complete geometrical description of the exchange grid. + +
+The second way +to create an ESMF_XGrid requires users to supply all necessary information +to compute communication routehandle. A later +call to ESMF_FieldRegridStore() with the xgrid and source and destination +ESMF_Fields computes the ESMF_Routehandle object for matrix +multiply operation used in model remapping. + +
+ESMF_XGrid deals with 2 distinctive kinds of fraction for each Grid or Mesh cell +involved in its creation. The following description applies to both ESMF_Grid +and ESMF_Mesh involved in the ESMF_XGrid creation process. +The first fraction quantity is the same as defined in direct +Field regrid between a source and destination ESMF_Field pair, namely the fraction +of a total Grid cell area that is used in weight generation. The second fraction quantity +is a result of the Grid merging process when multiple ESMF_Grids or model components +exist on one side of the exchange grid. To compute XGrid, the multiple ESMF_Grids +are first merged together to form a super mesh. During the merging process, Grids that are +of a higher priority clips into lower priority Grids, creating fractional cells in the lower +priority Grids. Priority is a mechanism to resolve the claim of a surface region by multiple +Grids. To conserve flux, any surface area can only be claimed by a unique Grid. This is +a typical practice in earth system modelling, e.g. to handle land and ocean boundary. + +
+In addition to the matrix multiply communication routehandle, +ESMF_XGrid exports both and to the user through the ESMF_FieldRegridStore() method +because each remapping pair has different and associated with it. from source Grid is +folded directly in the calculated weight matrices since its used to calculate destination point flux +density . The global source flux is defined as +. +The global destination flux is defined as: + +, is the + modified weight intersecting s-th source Grid cell with d-th destination Grid cell. +It can be proved that this formulation of the fractions and +weight calculation ensures first order global conservation of +flux transferred from source grids to exchange grid, and from exchange grid to destination grids. + +
+ +
+DESCRIPTION:
+
+Specify which side of the ESMF_XGrid the current operation is taking place.
+
+
+The type of this flag is: + +
+type(ESMF_XGridSide_Flag) + +
+The valid values are: +
+ +
+ +
+ +
+An ESMF_XGrid object can be created from Grids on either side + of the exchange grid. Internally the + weight matrices and index mapping are computed and stored in the XGrid, along + with other necessary information for flux exchange calculation between + any pair of model components used for the XGrid creation. + +
+In this example, we create an XGrid from overlapping Grids on + either side of the XGrid. Then we perform a flux exchange from one side + to the other side of the XGrid. + +
+We start by creating the Grids on both sides and associate coordinates with + the Grids on the corner stagger. The Grids use global indexing and padding + for coordinates on the corner stagger. + +
+For details of Grid creation and coordinate use, + please refer to Grid class documentation: 31.3.2. +
+
+ ! First Grid on side A + sideA(1) = ESMF_GridCreateNoPeriDim(maxIndex=(/20, 20/), & + indexflag=ESMF_INDEX_GLOBAL, & + gridEdgeLWidth=(/0,0/), gridEdgeUWidth=(/1,1/), & + name='source Grid 1 on side A', rc=localrc) ++ +
+
+ ! Second Grid on side A + sideA(2) = ESMF_GridCreateNoPeriDim(maxIndex=(/20, 10/), & + indexflag=ESMF_INDEX_GLOBAL, & + gridEdgeLWidth=(/0,0/), gridEdgeUWidth=(/1,1/), & + name='source Grid 2 on side A', rc=localrc) ++ +
+
+ ! Allocate coordinates for Grid corner stagger + do i = 1, 2 + call ESMF_GridAddCoord(sideA(i), staggerloc=ESMF_STAGGERLOC_CORNER, & + rc=localrc) ++ +
+
+ enddo ++ +
+Assign coordinate for the Grids on sideA at corner stagger. +
+
+ ! SideA first grid spans (0-20, 0-20) with 1.0x1.0 degree resolution + ! X corner + call ESMF_GridGetCoord(sideA(1), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CORNER, coordDim=1, & + farrayPtr=coordX, rc=localrc) ++ +
+
+ ! Y corner + call ESMF_GridGetCoord(sideA(1), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CORNER, coordDim=2, & + farrayPtr=coordY, rc=localrc) ++ +
+
+ do i = lbound(coordX,1), ubound(coordX,1) + do j = lbound(coordX, 2), ubound(coordX, 2) + coordX(i,j) = (i-1)*1.0 + coordY(i,j) = (j-1)*1.0 + enddo + enddo ++ +
+
+ ! SideA second grid spans (14.3-24.3, 14.2-24.2) with 0.5x1.0 degree + ! resolution X corner + call ESMF_GridGetCoord(sideA(2), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CORNER, coordDim=1, & + farrayPtr=coordX, rc=localrc) ++ +
+
+ ! Y corner + call ESMF_GridGetCoord(sideA(2), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CORNER, coordDim=2, & + farrayPtr=coordY, rc=localrc) ++ +
+
+ do i = lbound(coordX,1), ubound(coordX,1) + do j = lbound(coordX, 2), ubound(coordX, 2) + coordX(i,j) = 14.3+(i-1)*0.5 + coordY(i,j) = 14.2+(j-1)*1.0 + enddo + enddo ++ +
+Create the destination grid on side B, only one Grid exists on side B. Also associate + coordinate with the Grid: +
+
+ sideB(1) = ESMF_GridCreateNoPeriDim(maxIndex=(/30, 30/), & + indexflag=ESMF_INDEX_GLOBAL, & + gridEdgeLWidth=(/0,0/), gridEdgeUWidth=(/1,1/), & + name='source Grid 1 on side B', rc=localrc) ++ +
+
+ do i = 1, 1 + call ESMF_GridAddCoord(sideB(i), staggerloc=ESMF_STAGGERLOC_CORNER, & + rc=localrc) ++ +
+
+ enddo ++ +
+
+ ! SideB grid spans (0-30, 0-30) with 1.0x1.0 degree resolution + ! X corner + call ESMF_GridGetCoord(sideB(1), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CORNER, coordDim=1, & + farrayPtr=coordX, rc=localrc) ++ +
+
+ ! Y corner + call ESMF_GridGetCoord(sideB(1), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CORNER, coordDim=2, & + farrayPtr=coordY, rc=localrc) ++ +
+
+ do i = lbound(coordX,1), ubound(coordX,1) + do j = lbound(coordX, 2), ubound(coordX, 2) + coordX(i,j) = (i-1)*1.0 + coordY(i,j) = (j-1)*1.0 + enddo + enddo ++ +
+Create an ESMF_XGrid object from the two lists of Grids on side A and B. + In this example both Grids on side A overlaps with the Grid on side B. It's an error to have a Grid + on either side that is spatially disjoint with the XGrid. Neither of the Grid on side A is + identical to the Grid on side B. Calling the ESMF_XGridCreate() method is straightforward: +
+
+ xgrid = ESMF_XGridCreate(sideAGrid=sideA, sideBGrid=sideB, rc=localrc) ++ +
+Create an ESMF_Field on the XGrid: +
+
+ field = ESMF_FieldCreate(xgrid, typekind=ESMF_TYPEKIND_R8, & + rc=localrc) ++ +
+Query the Field for its Fortran data pointer and its exclusive bounds: +
+
+ call ESMF_FieldGet(field, farrayPtr=xfarrayPtr, & + exclusiveLBound=xlb, exclusiveUBound=xub, rc=localrc) ++ +
+Create src and dst Fields on side A and side B Grids. +
+
+ do i = 1, 2 + srcField(i) = ESMF_FieldCreate(sideA(i), & + typekind=ESMF_TYPEKIND_R8, rc=localrc) ++ +
+
+ enddo + do i = 1, 1 + dstField(i) = ESMF_FieldCreate(sideB(i), & + typekind=ESMF_TYPEKIND_R8, rc=localrc) ++ +
+
+ enddo ++ +
+The current implementation requires that Grids used to generate the XGrid + must not match, i.e. they are different either topologically or geometrically or both. + In this example, the first source Grid is topologically identical to the destination + Grid but their geometric coordinates are different. + +
+First we compute the regrid routehandles, these routehandles can be used repeatedly + afterwards. Then we initialize the values in the Fields. Finally we execute the Regrid. + +
+
+ ! Compute regrid routehandles. The routehandles can be used + ! repeatedly afterwards. + ! From A -> X + do i = 1, 2 + call ESMF_FieldRegridStore(xgrid, srcField(i), field, & + routehandle=rh_src2xgrid(i), rc = localrc) ++ +
+
+ enddo + ! from X -> B, retrieve the destination fraction Fields. + do i = 1, 1 + call ESMF_FieldRegridStore(xgrid, field, dstField(i), & + dstFracField=dstFrac, dstMergeFracField=dstFrac2, & + routehandle=rh_xgrid2dst(i), rc = localrc) ++ +
+
+ enddo + + ! Initialize values in the source Fields on side A + do i = 1, 2 + call ESMF_FieldGet(srcField(i), farrayPtr=farrayPtr, rc=localrc) ++ +
+
+ farrayPtr = i + enddo + ! Initialize values in the destination Field on XGrid + xfarrayPtr = 0.0 + ! Initialize values in the destination Field on Side B + do i = 1, 1 + call ESMF_FieldGet(dstField(i), farrayPtr=farrayPtr, rc=localrc) ++ +
+
+ farrayPtr = 0.0 + enddo ++ +
+First we regrid from the Fields on side A to the Field on the XGrid: +
+
+ ! Execute regrid from A -> X + do i = 1, 2 + call ESMF_FieldRegrid(srcField(i), field, & + routehandle=rh_src2xgrid(i), & + zeroregion=ESMF_REGION_SELECT, rc = localrc) ++ +
+
+ enddo ++ +
+Next we regrid from the Field on XGrid to the destination Field on side B: +
+
+ ! Execute the regrid store + do i = 1, 1 + call ESMF_FieldRegrid(field, dstField(i), & + routehandle=rh_xgrid2dst(i), & + rc = localrc) ++ +
+
+ enddo ++ +
+After the regridding calls, the routehandle can be released by calling the + ESMF_FieldRegridRelease() method. +
+
+ do i = 1, 2 + call ESMF_FieldRegridRelease(routehandle=rh_src2xgrid(i), rc=localrc) ++ +
+
+ enddo + call ESMF_FieldRegridRelease(routehandle=rh_xgrid2dst(1), rc=localrc) ++ +
+In the above example, we first set up all the required parameters to create an XGrid from user + supplied input. Then we create Fields on the XGrid and the Grids on either side. Finally + we use the ESMF_FieldRegrid() interface to perform a flux exchange from the source side + to the destination side. + +
+ +
+A typical application in Earth System Modeling is to calculate flux exchange + through the planetary boundary layer that can be represented by ESMF_XGrid. + Atmosphere is above the planetary boundary layer while land and ocean are below the boundary layer. + To create an XGrid, the land and ocean Grids that are usually different in resolution + need to be merged first to create a super Mesh. This merging process is enabled through the support + of masking. + +
+The global land and ocean Grids need to be created with masking enabled. + In practice, each Grid cell has an integer masking value attached to it. For examples using masking in + ESMF_Grid please refer to section 31.3.17. + +
+When calling the ESMF_XGridCreate() method, user can supply the optional arguments + sideAMaskValues and sideBMaskValues. + These arguments are one dimensional Fortran integer arrays. If any of the sideAMaskValues entry + matches the masking value used in sideA Grid, the sideA Grid cell is masked out, vice versa for sideB. + Thus by specifying different regions of a land and ocean Grids to be masked out, the two global Grids + can be merged into a new global Mesh covering the entire Earth. + +
+The following call shows how to use the ESMF_XGridCreate() method with the optional + arguments sideAMaskValues and sideBMaskValues. + +
+
+ xgrid = ESMF_XGridCreate(sideAGrid=sideA, sideBGrid=sideB, & + sideAMaskValues=(/2/), sideBMaskValues=(/3,4/), rc=localrc) ++ +
+ + +
+ +
+ +
+ +
+Alternatively, XGrid can be created from Grids on either side, + area and centroid information of XGrid cells, sparse matrix matmul information. + The functionalities provided by the + XGrid object is constrained by the user supplied input during its creation time. + +
+In this example, we will set up a simple XGrid from overlapping Grids on + either side of the XGrid. Then we perform a flux exchange from one side + to the other side of the XGrid. The Grids are laid out in the following figure: +
+ |
+We start by creating the Grids on both sides and associate coordinates with + the Grids. For details of Grid creation and coordinate use, please refer to + Grid class documentation. +
+
+ sideA(1) = ESMF_GridCreateNoPeriDim(minIndex=(/1,1/), maxIndex=(/2,2/), & + coordDep1=(/1/), & + coordDep2=(/2/), & + name='source Grid 1 on side A', rc=localrc) ++ +
+
+ sideA(2) = ESMF_GridCreateNoPeriDim(minIndex=(/1,1/), maxIndex=(/2,1/), & + coordDep1=(/1/), & + coordDep2=(/2/), & + name='source Grid 2 on side A', rc=localrc) ++ +
+
+ do i = 1, 2 + call ESMF_GridAddCoord(sideA(i), staggerloc=ESMF_STAGGERLOC_CENTER, & + rc=localrc) ++ +
+
+ enddo ++ +
+Coordinate for the Grids on sideA, refer to the Grid layout diagram for the + interpretation of the coordinate values: +
+
+ ! SideA first grid + centroidA1X=(/0.5, 1.5/) + centroidA1Y=(/0.5, 1.5/) + call ESMF_GridGetCoord(sideA(1), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CENTER, coordDim=1, & + farrayPtr=coordX, rc=localrc) ++ +
+
+ coordX = centroidA1X + call ESMF_GridGetCoord(sideA(1), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CENTER, coordDim=2, & + farrayPtr=coordY, rc=localrc) ++ +
+
+ coordY = centroidA1Y + + ! SideA second grid + centroidA2X=(/0.5, 1.5/) + centroidA2Y=(/2.5/) + call ESMF_GridGetCoord(sideA(2), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CENTER, coordDim=1, & + farrayPtr=coordX, rc=localrc) ++ +
+
+ coordX = centroidA2X + call ESMF_GridGetCoord(sideA(2), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CENTER, coordDim=2, & + farrayPtr=coordY, rc=localrc) ++ +
+
+ coordY = centroidA2Y ++ +
+Create the destination grid on side B, only one Grid exists on side B. Also associate + coordinate with the Grid: +
+
+ sideB(1) = ESMF_GridCreateNoPeriDim(minIndex=(/1,1/), maxIndex=(/2,2/), & + coordDep1=(/1/), coordDep2=(/2/), & + name='destination Grid on side B', rc=localrc) ++ +
+
+ do i = 1, 1 + call ESMF_GridAddCoord(sideB(i), staggerloc=ESMF_STAGGERLOC_CENTER, & + rc=localrc) ++ +
+
+ enddo + + ! SideB grid + centroidBX=(/0.75, 1.75/) + centroidBY=(/0.75, 2.25/) + call ESMF_GridGetCoord(sideB(1), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CENTER, coordDim=1, farrayPtr=coordX, & + rc=localrc) ++ +
+
+ coordX = centroidBX + call ESMF_GridGetCoord(sideB(1), localDE=0, & + staggerLoc=ESMF_STAGGERLOC_CENTER, coordDim=2, farrayPtr=coordY, & + rc=localrc) ++ +
+
+ coordY = centroidBY ++ +
+Set up the mapping indices and weights from A side to the XGrid. For details of + sequence indices, factorIndexList, and factorList, please see section + 28.2.18 in the reference manual. Please refer to the figure above + for interpretation of the sequence indices used here. + +
+In order to compute the destination flux on sideB through the XGrid as an mediator, + we need to set up the factorList (weights) and factorIndexList (indices) + for sparse matrix multiplication in this formulation: + dst_flux = W'*W*src_flux, where W' is the weight matrix from the XGrid to + destination; and W is the weight matrix from source to the XGrid. The weight matrix + is generated using destination area weighted algorithm. Please refer to figure + 20 for details. + +
+
+ ! Set up mapping from A1 -> X + sparseMatA2X(1)%factorIndexList(1,1)=1 ! src seq index (green) + sparseMatA2X(1)%factorIndexList(1,2)=2 ! src seq index (green) + sparseMatA2X(1)%factorIndexList(1,3)=2 ! src seq index (green) + sparseMatA2X(1)%factorIndexList(1,4)=3 ! src seq index (green) + sparseMatA2X(1)%factorIndexList(1,5)=4 ! src seq index (green) + sparseMatA2X(1)%factorIndexList(1,6)=4 ! src seq index (green) + sparseMatA2X(1)%factorIndexList(1,7)=3 ! src seq index (green) + sparseMatA2X(1)%factorIndexList(1,8)=4 ! src seq index (green) + sparseMatA2X(1)%factorIndexList(1,9)=4 ! src seq index (green) + + sparseMatA2X(1)%factorIndexList(2,1)=1 ! dst seq index (black) + sparseMatA2X(1)%factorIndexList(2,2)=2 ! dst seq index (black) + sparseMatA2X(1)%factorIndexList(2,3)=3 ! dst seq index (black) + sparseMatA2X(1)%factorIndexList(2,4)=4 ! dst seq index (black) + sparseMatA2X(1)%factorIndexList(2,5)=5 ! dst seq index (black) + sparseMatA2X(1)%factorIndexList(2,6)=6 ! dst seq index (black) + sparseMatA2X(1)%factorIndexList(2,7)=7 ! dst seq index (black) + sparseMatA2X(1)%factorIndexList(2,8)=8 ! dst seq index (black) + sparseMatA2X(1)%factorIndexList(2,9)=9 ! dst seq index (black) + + ! Set up mapping from A2 -> X + sparseMatA2X(2)%factorIndexList(1,1)=1 ! src seq index (red) + sparseMatA2X(2)%factorIndexList(1,2)=2 ! src seq index (red) + sparseMatA2X(2)%factorIndexList(1,3)=2 ! src seq index (red) + + sparseMatA2X(2)%factorIndexList(2,1)=10 ! dst seq index (black) + sparseMatA2X(2)%factorIndexList(2,2)=11 ! dst seq index (black) + sparseMatA2X(2)%factorIndexList(2,3)=12 ! dst seq index (black) ++ +
+Set up the mapping weights from side A to the XGrid: +
+
+ ! Note that the weights are dest area weighted, they are ratio + ! of areas with destination area as the denominator. + ! Set up mapping weights from A1 -> X + sparseMatA2X(1)%factorList(:)=1. + + ! Set up mapping weights from A2 -> X + sparseMatA2X(2)%factorList(:)=1. ++ +
+Set up the mapping indices and weights from the XGrid to B side: +
+
+ ! Set up mapping from X -> B + sparseMatX2B(1)%factorIndexList(1,1)=1 ! src seq index (black) + sparseMatX2B(1)%factorIndexList(1,2)=2 ! src seq index (black) + sparseMatX2B(1)%factorIndexList(1,3)=3 ! src seq index (black) + sparseMatX2B(1)%factorIndexList(1,4)=4 ! src seq index (black) + sparseMatX2B(1)%factorIndexList(1,5)=5 ! src seq index (black) + sparseMatX2B(1)%factorIndexList(1,6)=6 ! src seq index (black) + sparseMatX2B(1)%factorIndexList(1,7)=7 ! src seq index (black) + sparseMatX2B(1)%factorIndexList(1,8)=8 ! src seq index (black) + sparseMatX2B(1)%factorIndexList(1,9)=9 ! src seq index (black) + sparseMatX2B(1)%factorIndexList(1,10)=10 ! src seq index (black) + sparseMatX2B(1)%factorIndexList(1,11)=11 ! src seq index (black) + sparseMatX2B(1)%factorIndexList(1,12)=12 ! src seq index (black) + + sparseMatX2B(1)%factorIndexList(2,1)=1 ! dst seq index (blue) + sparseMatX2B(1)%factorIndexList(2,2)=1 ! dst seq index (blue) + sparseMatX2B(1)%factorIndexList(2,3)=2 ! dst seq index (blue) + sparseMatX2B(1)%factorIndexList(2,4)=1 ! dst seq index (blue) + sparseMatX2B(1)%factorIndexList(2,5)=1 ! dst seq index (blue) + sparseMatX2B(1)%factorIndexList(2,6)=2 ! dst seq index (blue) + sparseMatX2B(1)%factorIndexList(2,7)=3 ! dst seq index (blue) + sparseMatX2B(1)%factorIndexList(2,8)=3 ! dst seq index (blue) + sparseMatX2B(1)%factorIndexList(2,9)=4 ! dst seq index (blue) + sparseMatX2B(1)%factorIndexList(2,10)=3 ! dst seq index (blue) + sparseMatX2B(1)%factorIndexList(2,11)=3 ! dst seq index (blue) + sparseMatX2B(1)%factorIndexList(2,12)=4 ! dst seq index (blue) + + ! Set up mapping weights from X -> B + sparseMatX2B(1)%factorList(1)=4./9. + sparseMatX2B(1)%factorList(2)=2./9. + sparseMatX2B(1)%factorList(3)=2./3. + sparseMatX2B(1)%factorList(4)=2./9. + sparseMatX2B(1)%factorList(5)=1./9. + sparseMatX2B(1)%factorList(6)=1./3. + sparseMatX2B(1)%factorList(7)=2./9. + sparseMatX2B(1)%factorList(8)=1./9. + sparseMatX2B(1)%factorList(9)=1./3. + sparseMatX2B(1)%factorList(10)=4./9. + sparseMatX2B(1)%factorList(11)=2./9. + sparseMatX2B(1)%factorList(12)=2./3. ++ +
+Optionally the area can be setup to compute surface area weighted flux integrals: +
+
+ ! Set up destination areas to adjust weighted flux + xgrid_area(1) = 1. + xgrid_area(2) = 0.5 + xgrid_area(3) = 0.5 + xgrid_area(4) = 0.5 + xgrid_area(5) = 0.25 + xgrid_area(6) = 0.25 + xgrid_area(7) = 0.5 + xgrid_area(8) = 0.25 + xgrid_area(9) = 0.25 + xgrid_area(10) = 1. + xgrid_area(11) = 0.5 + xgrid_area(12) = 0.5 ++ +
+Create an XGrid based on the user supplied regridding parameters: +
+
+ xgrid = ESMF_XGridCreateFromSparseMat(sideAGrid=sideA, & + sideBGrid=sideB, area=xgrid_area, & + centroid=centroid, sparseMatA2X=sparseMatA2X, & + sparseMatX2B=sparseMatX2B, rc=localrc) ++ +
+Create an ESMF_Field on the XGrid: +
+
+ field = ESMF_FieldCreate(xgrid, typekind=ESMF_TYPEKIND_R8, & + rc=localrc) ++ +
+Query the Field for its Fortran data pointer and its exclusive bounds: +
+
+ call ESMF_FieldGet(field, farrayPtr=xfarrayPtr, & + exclusiveLBound=xlb, exclusiveUBound=xub, rc=localrc) ++ +
+Setup and initialize src and dst Fields on side A and side B Grids, + source Fields have different source flux: +
+
+ do i = 1, 2 + srcField(i) = ESMF_FieldCreate(sideA(i), & + typekind=ESMF_TYPEKIND_R8, rc=localrc) ++ +
+
+ call ESMF_FieldGet(srcField(i), farrayPtr=farrayPtr, rc=localrc) ++ +
+
+ farrayPtr = i + enddo + do i = 1, 1 + dstField(i) = ESMF_FieldCreate(sideB(i), & + typekind=ESMF_TYPEKIND_R8, rc=localrc) ++ +
+
+ call ESMF_FieldGet(dstField(i), farrayPtr=farrayPtr, rc=localrc) ++ +
+
+ farrayPtr = 0.0 + enddo ++ +
+The current implementation requires that Grids used to generate the XGrid + must not match, i.e. they are different either topologically or geometrically or both. + In this example, the first source Grid is topologically identical to the destination + Grid but their geometric coordinates are different. This requirement will be relaxed + in a future release. + +
+First we compute the regrid routehandles, these routehandles can be used repeatedly + afterwards. Then we initialize the values in the Fields. Finally we execute the Regrid. + +
+
+ ! Compute regrid routehandles. The routehandles can be used + ! repeatedly afterwards. + ! From A -> X + do i = 1, 2 + call ESMF_FieldRegridStore(xgrid, srcField(i), field, & + routehandle=rh_src2xgrid(i), rc = localrc) ++ +
+
+ enddo + ! from X -> B + do i = 1, 1 + call ESMF_FieldRegridStore(xgrid, field, dstField(i), & + routehandle=rh_xgrid2dst(i), rc = localrc) ++ +
+
+ enddo + + ! Initialize values in the source Fields on side A + do i = 1, 2 + call ESMF_FieldGet(srcField(i), farrayPtr=farrayPtr, rc=localrc) ++ +
+
+ farrayPtr = i + enddo + ! Initialize values in the destination Field on XGrid + xfarrayPtr = 0.0 + ! Initialize values in the destination Field on Side B + do i = 1, 1 + call ESMF_FieldGet(dstField(i), farrayPtr=farrayPtr, rc=localrc) ++ +
+
+ farrayPtr = 0.0 + enddo ++ +
+First we regrid from the Fields on side A to the Field on the XGrid: +
+
+ ! Execute regrid from A -> X + do i = 1, 2 + call ESMF_FieldRegrid(srcField(i), field, & + routehandle=rh_src2xgrid(i), & + zeroregion=ESMF_REGION_SELECT, rc = localrc) ++ +
+
+ enddo ++ +
+Next we regrid from the Field on XGrid to the destination Field on side B: +
+
+ ! Execute the regrid store + do i = 1, 1 + call ESMF_FieldRegrid(field, dstField(i), & + routehandle=rh_xgrid2dst(i), rc = localrc) ++ +
+
+ enddo ++ +
+In the above example, we first set up all the required parameters to create an XGrid from user + supplied input. Then we create Fields on the XGrid and the Grids on either side. Finally + we use the ESMF_FieldRegrid() interface to perform a flux exchange from the source side + to the destination side. + +
+ +
+
+ call ESMF_XGridGet(xgrid, & + sideAGridCount=ngridA, & ! number of Grids on side A + sideBGridCount=ngridB, & ! number of Grids on side B + sideAGrid=l_sideA, & ! list of Grids on side A + sideBGrid=l_sideB, & ! list of Grids on side B + area=l_area, & ! list of area of XGrid + centroid=l_centroid, & ! list of centroid of XGrid + distgridA=l_sideAdg, & ! list of Distgrids on side A + distgridM = distgrid, & ! balanced distgrid + sparseMatA2X=l_sparseMatA2X, & !sparse matrix matmul parameters A to X + sparseMatX2B=l_sparseMatX2B, & !sparse matrix matmul parameters X to B + rc=localrc) ++ +
+
+ call ESMF_XGridGet(xgrid, localDe=0, & + elementCount=eleCount, & ! elementCount on the localDE + exclusiveCount=ec, & ! exclusive count + exclusiveLBound=elb, & ! exclusive lower bound + exclusiveUBound=eub, & ! exclusive upper bound + rc=localrc) ++ +
+
+ call ESMF_XGridGet(xgrid, & + xgridSide=ESMF_XGRIDSIDE_A, & ! side of the XGrid to query + gridIndex=1, & ! index of the distgrid + distgrid=distgrid, & ! the distgrid returned + rc=localrc) ++ +
+ +
+
+ ! After the regridding is successful. + ! Clean up all the allocated resources: + call ESMF_FieldDestroy(field, rc=localrc) ++ +
+
+ call ESMF_XGridDestroy(xgrid, rc=localrc) ++ +
+
+ do i = 1, 2 + call ESMF_FieldDestroy(srcField(i), rc = localrc) ++ +
+
+ call ESMF_GridDestroy(sideA(i), rc = localrc) ++ +
+
+ enddo + + do i = 1, 1 + call ESMF_FieldDestroy(dstField(i), rc = localrc) ++ +
+
+ call ESMF_GridDestroy(sideB(i), rc = localrc) ++ +
+
+ enddo + + deallocate(sparseMatA2X(1)%factorIndexList, sparseMatA2X(1)%factorList) + deallocate(sparseMatA2X(2)%factorIndexList, sparseMatA2X(2)%factorList) + deallocate(sparseMatX2B(1)%factorIndexList, sparseMatX2B(1)%factorList) ++ +
+ + +
+ +
+
+ +
+ +
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + xgrid1 = xgrid2 +ARGUMENTS: +
type(ESMF_XGrid) :: xgrid1 + type(ESMF_XGrid) :: xgrid2 ++DESCRIPTION: +
+Assign xgrid1 as an alias to the same ESMF XGrid object in memory + as xgrid2. If xgrid2 is invalid, then xgrid1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (xgrid1 == xgrid2) then ... endif + OR + result = (xgrid1 == xgrid2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid1 + type(ESMF_XGrid), intent(in) :: xgrid2 ++DESCRIPTION: +
+Test whether xgrid1 and xgrid2 are valid aliases to the same ESMF + XGrid object in memory. For a more general comparison of two ESMF XGrids, + going beyond the simple alias test, the ESMF_XGridMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (xgrid1 /= xgrid2) then ... endif + OR + result = (xgrid1 /= xgrid2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid1 + type(ESMF_XGrid), intent(in) :: xgrid2 ++DESCRIPTION: +
+Test whether xgrid1 and xgrid2 are not valid aliases to the + same ESMF XGrid object in memory. For a more general comparison of two ESMF + XGrids, going beyond the simple alias test, the ESMF_XGridMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
+ function ESMF_XGridCreate(& + sideAGrid, sideAMesh, & + sideBGrid, sideBMesh, & + sideAGridPriority, sideAMeshPriority, & + sideBGridPriority, sideBMeshPriority, & + sideAMaskValues, sideBMaskValues, & + storeOverlay, & + name, rc) +RETURN VALUE: +
type(ESMF_XGrid) :: ESMF_XGridCreate +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Grid), intent(in), optional :: sideAGrid(:) + type(ESMF_Mesh), intent(in), optional :: sideAMesh(:) + type(ESMF_Grid), intent(in), optional :: sideBGrid(:) + type(ESMF_Mesh), intent(in), optional :: sideBMesh(:) + integer, intent(in), optional :: sideAGridPriority(:) + integer, intent(in), optional :: sideAMeshPriority(:) + integer, intent(in), optional :: sideBGridPriority(:) + integer, intent(in), optional :: sideBMeshPriority(:) + integer(ESMF_KIND_I4),intent(in), optional :: sideAMaskValues(:) + integer(ESMF_KIND_I4),intent(in), optional :: sideBMaskValues(:) + logical, intent(in), optional :: storeOverlay + character(len=*), intent(in), optional :: name + integer, intent(out),optional :: rc ++DESCRIPTION: +
+Create an XGrid from user supplied input: the list of Grids or Meshes on side A and side B, + and other optional arguments. A user can supply both Grids and Meshes on one side to create + the XGrid. By default, the Grids have a higher priority over Meshes but the order of priority + can be adjusted by the optional GridPriority and MeshPriority arguments. The priority order + of Grids and Meshes can also be interleaved by rearranging the optional + GridPriority and MeshPriority arguments accordingly. + +
+Sparse matrix multiplication coefficients are internally computed and + uniquely determined by the Grids or Meshes provided in sideA and sideB. User can supply + a single ESMF_Grid or an array of ESMF_Grid on either side of the + ESMF_XGrid. For an array of ESMF_Grid or ESMF_Mesh in sideA or sideB, + a merging process concatenates all the ESMF_Grids and ESMF_Meshes + into a super mesh represented + by ESMF_Mesh. The super mesh is then used to compute the XGrid. + Grid or Mesh objects in sideA and sideB arguments must have coordinates defined for + the corners of a Grid or Mesh cell. XGrid creation can be potentially memory expensive given the + size of the input Grid and Mesh objects. By default, the super mesh is not stored + to reduce memory usage. + Once communication routehandles are computed using ESMF_FieldRegridStore() method through + XGrid, all memory can be released by destroying the XGrid. + +
+If sideA and sideB have a single + Grid or Mesh object, it's erroneous + if the two Grids or Meshes are spatially disjoint. + It is also erroneous to specify a Grid or Mesh object in sideA or sideB + that is spatially disjoint from the ESMF_XGrid. + +
+This call is collective across the current VM. For more details please refer to the description + 34.1 of the XGrid class. For an example and associated documentation using this method see section + 34.3.1 + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
+ function ESMF_XGridCreateFromSparseMat(& + sideAGrid, sideAMesh, & + sideBGrid, sideBMesh, & + sideAGridPriority, sideAMeshPriority, & + sideBGridPriority, sideBMeshPriority, & + sparseMatA2X, sparseMatX2A, sparseMatB2X, sparseMatX2B, & + area, centroid, & + name, & + rc) +RETURN VALUE: +
type(ESMF_XGrid) :: ESMF_XGridCreateFromSparseMat +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Grid), intent(in), optional :: sideAGrid(:) + type(ESMF_Mesh), intent(in), optional :: sideAMesh(:) + type(ESMF_Grid), intent(in), optional :: sideBGrid(:) + type(ESMF_Mesh), intent(in), optional :: sideBMesh(:) + integer, intent(in), optional :: sideAGridPriority(:) + integer, intent(in), optional :: sideAMeshPriority(:) + integer, intent(in), optional :: sideBGridPriority(:) + integer, intent(in), optional :: sideBMeshPriority(:) + type(ESMF_XGridSpec), intent(in), optional :: sparseMatA2X(:) + type(ESMF_XGridSpec), intent(in), optional :: sparseMatX2A(:) + type(ESMF_XGridSpec), intent(in), optional :: sparseMatB2X(:) + type(ESMF_XGridSpec), intent(in), optional :: sparseMatX2B(:) + real(ESMF_KIND_R8), intent(in), optional :: area(:) + real(ESMF_KIND_R8), intent(in), optional :: centroid(:,:) + character (len=*), intent(in), optional :: name + integer, intent(out),optional :: rc ++DESCRIPTION: +
+Create an XGrid directly from user supplied sparse matrix parameters. User + is responsible to supply all information necessary for communication calculation. + For an example and associated documentation using this method see section + 34.3.3 + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_XGridIsCreated(xgrid, rc) +RETURN VALUE: +
logical :: ESMF_XGridIsCreated +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the xgrid has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
+ subroutine ESMF_XGridDestroy(xgrid, noGarbage, rc) +ARGUMENTS: +
type(ESMF_XGrid), intent(inout) :: xgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroys an ESMF_XGrid, releasing the resources associated + with the object. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_XGridGet() + + subroutine ESMF_XGridGetDefault(xgrid, & + sideAGridCount, sideBGridCount, sideAMeshCount, sideBMeshCount, & + coordSys, & + dimCount, elementCount, & + sideAGrid, sideBGrid, sideAMesh, sideBMesh, & + mesh, & + area, centroid, & + distgridA, distgridB, distgridM, & + sparseMatA2X, sparseMatX2A, sparseMatB2X, sparseMatX2B, & + name, & + rc) +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: sideAGridCount, sideBGridCount + integer, intent(out), optional :: sideAMeshCount, sideBMeshCount + type(ESMF_CoordSys_Flag), intent(out), optional :: coordSys + integer, intent(out), optional :: dimCount + integer, intent(out), optional :: elementCount + type(ESMF_Grid), intent(out), optional :: sideAGrid(:), sideBGrid(:) + type(ESMF_Mesh), intent(out), optional :: sideAMesh(:), sideBMesh(:) + type(ESMF_Mesh), intent(out), optional :: mesh + real(ESMF_KIND_R8), intent(out), optional :: area(:) + real(ESMF_KIND_R8), intent(out), optional :: centroid(:,:) + type(ESMF_DistGrid), intent(out), optional :: distgridA(:) + type(ESMF_DistGrid), intent(out), optional :: distgridB(:) + type(ESMF_DistGrid), intent(out), optional :: distgridM + type(ESMF_XGridSpec), intent(out), optional :: sparseMatA2X(:) + type(ESMF_XGridSpec), intent(out), optional :: sparseMatX2A(:) + type(ESMF_XGridSpec), intent(out), optional :: sparseMatB2X(:) + type(ESMF_XGridSpec), intent(out), optional :: sparseMatX2B(:) + character (len=*), intent(out), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get information about XGrid + +
+The arguments are: +
+ + +
+ +
+ +
+ + +
+The ESMF Geom class is used as a container for other ESMF geometry objects (e.g. an ESMF Grid). This allows a generic +representation of a geometry to be passed around (e.g. through a coupled system) without it's specific type being known. +Some operations are supported on a Geom object and more will be added over time as needed. However, if +an unsupported operation is needed, then the specific geometry object can always be pulled out and operated on that way. + +
+In addition to the geometry object, a Geom can also contain information describing a location on a geometry. For example, in the case of +a Grid, a geometry object will also contain a stagger location. Having this location information allows the creation of Fields and +other capabilities to be performed in the most generic way on a Geom object. For geometries where it is appropriate, the user can +optionally specify this location information during the creation of a Geom object. However, if no location is specified, then default values for +this information are provided which match those which would be used when creating a Field with the specific geometry +(e.g. stagger location ESMF_STAGGERLOC_CENTER for a Grid). + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + geom1 = geom2 +ARGUMENTS: +
type(ESMF_Geom) :: geom1 + type(ESMF_Geom) :: geom2 ++DESCRIPTION: +
+Assign geom1 as an alias to the same ESMF Geom object in memory + as geom2. If geom2 is invalid, then geom1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (geom1 == geom2) then ... endif + OR + result = (geom1 == geom2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Geom), intent(in) :: geom1 + type(ESMF_Geom), intent(in) :: geom2 + ! ++DESCRIPTION: +
+Test whether geom1 and geom2 are valid aliases to the same ESMF + Geom object in memory. For a more general comparison of two ESMF Geoms, + going beyond the simple alias test, the ESMF_GeomMatch() function + must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (geom1 /= geom2) then ... endif + OR + result = (geom1 /= geom2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Geom), intent(in) :: geom1 + type(ESMF_Geom), intent(in) :: geom2 ++DESCRIPTION: +
+Test whether geom1 and geom2 are not valid aliases to the + same ESMF Geom object in memory. For a more general comparison of two ESMF + Geoms, going beyond the simple alias test, the ESMF_GeomMatch() function + (not yet fully implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GeomCreate() + function ESMF_GeomCreateGrid(grid,staggerloc, rc) +RETURN VALUE: +
type(ESMF_Geom) :: ESMF_GeomCreateGrid +ARGUMENTS: +
type(ESMF_Grid), intent(in) :: grid + type(ESMF_StaggerLoc), intent(in), optional :: staggerloc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Geom object from an ESMF_Grid object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GeomCreate() + function ESMF_GeomCreateMesh(mesh, meshLoc, rc) +RETURN VALUE: +
type(ESMF_Geom) :: ESMF_GeomCreateMesh +ARGUMENTS: +
type(ESMF_Mesh), intent(in) :: mesh + type(ESMF_MeshLoc), intent(in), optional :: meshLoc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Geom object from an ESMF_Mesh object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GeomCreate() + function ESMF_GeomCreateLocStream(locstream, rc) +RETURN VALUE: +
type(ESMF_Geom) :: ESMF_GeomCreateLocStream +ARGUMENTS: +
type(ESMF_LocStream), intent(in) :: locstream + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_Geom object from an ESMF_LocStream object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_GeomCreate() + function ESMF_GeomCreateXGrid(xgrid, xgridside, gridIndex, rc) +RETURN VALUE: +
type(ESMF_Geom) :: ESMF_GeomCreateXGrid +ARGUMENTS: +
type(ESMF_XGrid), intent(in) :: xgrid + type(ESMF_XGridSide_Flag), intent(in), optional :: xgridSide + integer, intent(in), optional :: gridIndex + integer, intent(out),optional :: rc ++DESCRIPTION: +
+Create an ESMF_Geom object from an ESMF_XGrid object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GeomDestroy(geom, rc) +ARGUMENTS: +
type(ESMF_Geom) :: geom + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Destroys an ESMF_Geom object. This call does not destroy wrapped + Grid, LocStream, or other objects. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_GeomGet(geom, & + dimCount, rank, localDECount, distgrid, & + distgridToGridMap, indexFlag, geomtype, & + grid, staggerloc, mesh, meshloc, locstream, & + xgrid, xgridside, gridIndex,rc) +ARGUMENTS: +
type(ESMF_Geom), intent(in) :: geom + integer, intent(out), optional :: dimCount + integer, intent(out), optional :: rank + integer, intent(out), optional :: localDECount + type(ESMF_DistGrid), intent(out), optional :: distgrid + integer, intent(out), optional :: distgridToGridMap(:) + type(ESMF_Index_Flag), intent(out), optional :: indexflag + type(ESMF_GeomType_Flag), intent(out), optional :: geomtype + type(ESMF_Grid), intent(out), optional :: grid + type(ESMF_StaggerLoc), intent(out), optional :: staggerloc + type(ESMF_Mesh), intent(out), optional :: mesh + type(ESMF_MeshLoc), intent(out), optional :: meshloc + type(ESMF_LocStream), intent(out), optional :: locstream + type(ESMF_XGrid), intent(out), optional :: xgrid + type(ESMF_XGridSide_Flag), intent(out), optional :: xgridside + integer, intent(out), optional :: gridIndex + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get various types of information about a Geom. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_GeomMatch(geom1, geom2, rc) +RETURN VALUE: +
type(ESMF_GeomMatch_Flag) :: ESMF_GeomMatch +ARGUMENTS: +
type(ESMF_Geom), intent(in) :: geom1 + type(ESMF_Geom), intent(in) :: geom2 + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Check if geom1 and geom2 match. Returns a range of values of type + ESMF_GeomMatch indicating how closely the Geoms match. For a description of + the possible return values, please see . + Please also note that by default this call is not collective and only + returns the match for the piece of the Geoms on the local PET. In this case, + it is possible for this call to return a different match on different PETs + for the same Geoms. + +
+The arguments are: +
+ + +
+The ESMF DistGrid class sits on top of the DELayout class and holds domain +information in index space. A DistGrid object captures the index space topology +and describes its decomposition in terms of DEs. Combined with DELayout and VM +the DistGrid defines the data distribution of a domain decomposition across the +computational resources of an ESMF Component. + +
+The global domain is defined as the union of logically +rectangular (LR) sub-domains or tiles. The DistGrid create methods allow +the specification of such a multi-tile global domain and its decomposition into +exclusive, DE-local LR regions according to various degrees of user specified +constraints. Complex index space topologies can be constructed by specifying +connection relationships between tiles during creation. + +
+The DistGrid class holds domain information for all DEs. Each DE is associated +with a local LR region. No overlap of the regions is allowed. The DistGrid +offers query methods that allow DE-local topology information to be extracted, +e.g. for the construction of halos by higher classes. + +
+A DistGrid object only contains decomposable dimensions. The minimum rank for a +DistGrid object is 1. A maximum rank does not exist for DistGrid objects, +however, ranks greater than 7 may lead to difficulties with respect to the +Fortran API of higher classes based on DistGrid. The rank of a DELayout object +contained within a DistGrid object must be equal to the DistGrid rank. Higher +class objects that use the DistGrid, such as an Array object, may be of +different rank than the associated DistGrid object. The higher class object +will hold the mapping information between its dimensions and the DistGrid +dimensions. + +
+ +
+DESCRIPTION:
+
+Indicates the level to which two DistGrid variables match.
+
+
+The type of this flag is: + +
+type(ESMF_DistGridMatch_Flag) + +
+The valid values are: +
+The following examples demonstrate how to create, use and destroy DistGrid objects. In order to produce complete and valid DistGrid objects all of the ESMF_DistGridCreate() calls require to be called in unison i.e. on all PETs of a component with a complete set of valid arguments. + +
+ +
+ +
+ +
+The minimum information required to create an ESMF_DistGrid object + for a single tile with default decomposition are the min and max of the tile + in index space. The following call creates a DistGrid for a + 1D index space tile with elements from 1 through 1000. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1/), maxIndex=(/1000/), rc=rc) ++ +
+A default DELayout with 1 DE per PET will be created during the + ESMF_DistGridCreate() call. The 1000 elements of the specified 1D tile + are then block decomposed into the available DEs, and distributed across the + PETs (same number as DEs by default). + Assuming execution on 4 PETs, the (min) (max) indices of the DE-local + blocks will be: +
+ DE 0 - (1) ~ (250) + DE 1 - (251) ~ (500) + DE 2 - (501) ~ (750) + DE 3 - (751) ~ (1000) ++ +
+DistGrids with rank > 1 can also be created with default decompositions, + specifying only the min and max indices of the tile. The following creates a + 2D DistGrid for a 5x5 tile with default decomposition. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), rc=rc) ++ +
+The default decomposition for a DistGrid of rank will be +, where is the number of DEs in the DELayout + and there are factors of . For the 2D example above this means + a regular decomposition if executed on 4 PETs and will result + in the following DE-local LR regions: +
+ DE 0 - (1,1) ~ (2,5) + DE 1 - (3,1) ~ (3,5) + DE 2 - (4,1) ~ (4,5) + DE 3 - (5,1) ~ (5,5) ++ +
+In many cases the default decomposition will not suffice for higher rank + DistGrids (rank > 1). For this reason a decomposition descriptor + regDecomp argument is available during ESMF_DistGridCreate(). The + following call creates a DistGrid on the same 2D tile as before, but now with + a user specified regular decomposition of + DEs. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + regDecomp=(/2,3/), rc=rc) ++ +
+The default DE labeling sequence follows column major order for the + regDecomp argument: +
+ -----------> 2nd dimension + | 0 2 4 + | 1 3 5 + v + 1st dimension ++ +
+By default grid points along all dimensions are homogeneously divided between + the DEs. The maximum element count difference between DEs along any dimension + is 1. The (min) (max) indices of the DE-local blocks of the above + example are as follows: +
+ DE 0 - (1,1) ~ (3,2) + DE 1 - (4,1) ~ (5,2) + DE 2 - (1,3) ~ (3,4) + DE 3 - (4,3) ~ (5,4) + DE 4 - (1,5) ~ (3,5) + DE 5 - (4,5) ~ (5,5) ++ +
+The specifics of the tile decomposition into DE-local LR domains can be + modified by the optional decompflag argument. The following line shows + how this argument is used to keep ESMF's default decomposition in the first + dimension but move extra grid points of the second dimension to the last DEs + in that direction. Extra elements occur if the number of DEs for a certain + dimension does not evenly divide its extent. In this example there are + 2 extra grid points for the second dimension because its extent is 5 but there + are 3 DEs along this index space axis. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + regDecomp=(/2,3/), decompflag=(/ESMF_DECOMP_BALANCED, & + ESMF_DECOMP_RESTLAST/), rc=rc) ++ +
+Now DE 4 and DE 5 will hold the extra elements along the 2nd dimension. +
+ DE 0 - (1,1) ~ (3,1) + DE 1 - (4,1) ~ (5,1) + DE 2 - (1,2) ~ (3,2) + DE 3 - (4,2) ~ (5,2) + DE 4 - (1,3) ~ (3,5) + DE 5 - (4,3) ~ (5,5) ++ +
+An alternative way of indicating the DE-local LR regions is to list the + index space coordinate as given by the associated DistGrid tile for each + dimension. For this 2D example there are two lists (dim 1) / (dim 2) for each + DE: +
+ DE 0 - (1,2,3) / (1) + DE 1 - (4,5) / (1) + DE 2 - (1,2,3) / (2) + DE 3 - (4,5) / (2) + DE 4 - (1,2,3) / (3,4,5) + DE 5 - (4,5) / (3,4,5) ++ +
+Information about DE-local LR regions in the latter format can be obtained + from the DistGrid object by use of ESMF_DistGridGet() methods: + +
+
+ allocate(dimExtent(2, 0:5)) ! (dimCount, deCount) + call ESMF_DistGridGet(distgrid, delayout=delayout, & + indexCountPDe=dimExtent, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + call ESMF_DELayoutGet(delayout, localDeCount=localDeCount, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + allocate(localDeToDeMap(0:localDeCount-1)) + call ESMF_DELayoutGet(delayout, localDeToDeMap=localDeToDeMap, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + do localDe=0, localDeCount-1 + de = localDeToDeMap(localDe) + do dim=1, 2 + allocate(localIndexList(dimExtent(dim, de))) ! allocate list + ! to hold indices + call ESMF_DistGridGet(distgrid, localDe=localDe, dim=dim, & + indexList=localIndexList, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + print *, "local DE ", localDe," - DE ",de, & + " localIndexList along dim=", dim," :: ", localIndexList + deallocate(localIndexList) + enddo + enddo + deallocate(localDeToDeMap) + deallocate(dimExtent) ++ +
+The advantage of the localIndexList format over the minIndex/maxIndex + format is that it can be used directly for DE-local to tile index + dereferencing. Furthermore the localIndexList allows to express very + general decompositions such as the cyclic decompositions in the first + dimension generated by the following call: +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + regDecomp=(/2,3/), & + decompflag=(/ESMF_DECOMP_CYCLIC,ESMF_DECOMP_RESTLAST/), rc=rc) ++ +
+with decomposition: +
+ DE 0 - (1,3,5) / (1) + DE 1 - (2,4) / (1) + DE 2 - (1,3,5) / (2) + DE 3 - (2,4) / (2) + DE 4 - (1,3,5) / (3,4,5) + DE 5 - (2,4) / (3,4,5) ++ +
+Finally, a DistGrid object is destroyed by calling +
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+ +
+The examples of this section use the 2D DistGrid of the previous section + to show the interplay between DistGrid and DELayout. By default, i.e. + without specifying the delayout argument, a DELayout will be created + during DistGrid creation that provides as many DEs as the DistGrid + object requires. The implicit call to ESMF_DELayoutCreate() is issued + with a fixed number of DEs and default settings in all other aspects. The + resulting DE to PET mapping depends on the number of PETs of the current VM + context. Assuming 6 PETs in the VM +
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + regDecomp=(/2,3/), rc=rc) ++ +
+will result in the following domain decomposition in terms of DEs +
+ 0 2 4 + 1 3 5 ++ and their layout or distribution over the available PETs: +
+ DE 0 -> PET 0 + DE 1 -> PET 1 + DE 2 -> PET 2 + DE 3 -> PET 3 + DE 4 -> PET 4 + DE 5 -> PET 5 ++ +
+Running the same example on a 4 PET VM will not change the domain + decomposition into 6 DEs as specified by +
+ 0 2 4 + 1 3 5 ++ but the layout across PETs will now contain multiple DE-to-PET mapping with + default cyclic distribution: +
+ DE 0 -> PET 0 + DE 1 -> PET 1 + DE 2 -> PET 2 + DE 3 -> PET 3 + DE 4 -> PET 0 + DE 5 -> PET 1 ++ +
+Sometimes it may be desirable for performance tuning to construct a DELayout + with specific characteristics. For instance, if the 6 PETs of the above + example are running on 3 nodes of a dual-SMP node cluster and there is a + higher communication load along the first dimension of the model than along + the second dimension it would be sensible to place DEs according to this + knowledge. + +
+The following example first creates a DELayout + with 6 DEs where groups of 2 DEs are to be in fast connection. This DELayout + is then used to create a DistGrid. +
+
+ delayout = ESMF_DELayoutCreate(deCount=6, deGrouping=(/(i/2,i=0,5)/), rc=rc) ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + regDecomp=(/2,3/), delayout=delayout, rc=rc) ++ +
+This will ensure a distribution of DEs across the cluster resource + in the following way: +
+ 0 2 4 + 1 3 5 + SMP SMP SMP ++ +
+The interplay between DistGrid and DELayout may at first seem complicated. + The simple but important rule to understand is that DistGrid describes a + domain decomposition and each domain is labeled with a DE number. The DELayout + describes how these DEs are laid out over the compute resources of the VM, + i.e. PETs. The DEs are purely logical elements of decomposition and may be + relabeled to fit the algorithm or legacy code better. The following + example demonstrates this by describing the exact same distribution of the + domain data across the fictitious cluster of SMP-nodes with a different + choice of DE labeling: +
+
+ delayout = ESMF_DELayoutCreate(deCount=6, deGrouping=(/(mod(i,3),i=0,5)/), & + rc=rc) ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + regDecomp=(/2,3/), deLabelList=(/0,3,1,4,2,5/), delayout=delayout, rc=rc) ++ +
+Here the deLabelList argument changes the default DE label sequence from + column major to row major. The DELayout compensates for this change in DE + labeling by changing the deGrouping argument to map the first dimension + to SMP nodes as before. The decomposition and layout now looks as follows: +
+ 0 1 2 + 3 4 5 + SMP SMP SMP ++ +
+Finally, in order to achieve a completely user-defined distribution of the + domain data across the PETs of the VM a DELayout may be created from a + petMap before using it in the creation of a DistGrid. If for + instance the desired distribution of a 2 x 3 decomposition puts the DEs of + the first row onto 3 separate PETs (PET 0, 1, 2) and groups the DEs of + the second row onto PET 3 a petMap must first be setup that + takes the DE labeling of the DistGrid into account.The following lines of + code result in the desired distribution using column major DE labeling by + first create a DELayout and then using it in the DistGrid creation. +
+
+ delayout = ESMF_DELayoutCreate(petMap=(/0,3,1,3,2,3/), rc=rc) ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + regDecomp=(/2,3/), delayout=delayout, rc=rc) ++ +
+This decomposes the global domain into +
+ 0 2 4 + 1 3 5 ++ and associates the DEs to the following PETs: +
+ DE 0 -> PET 0 + DE 1 -> PET 3 + DE 2 -> PET 1 + DE 3 -> PET 3 + DE 4 -> PET 2 + DE 5 -> PET 3 ++ +
+ +
+In the previous examples the DistGrid objects were created with regular + decompositions. In some cases a regular decomposition may not be the most + natural choice to decompose and distribute the index space. The + DE block version of ESMF_DistGridCreate() offers more control + over the precise decomposition. The following example shows how the + deBlockList argument is used to determine exactly what index space + block ends up on each DE. + +
+A single 5x5 tile is decomposed into 6 DEs. To this end a list is + constructed that holds the min and max indices of all six DE + blocks. The DE blocks must be constructed to cover the index space without + overlapping each other. It is okay to leave holes in the index space, i.e. + the DE blocks do not completely cover the index space tile. +
+
+ allocate(deBlockList(2, 2, 6)) ! (dimCount, 2, deCount) + deBlockList(:,1,1) = (/1,1/) ! minIndex 1st deBlock + deBlockList(:,2,1) = (/3,2/) ! maxIndex 1st deBlock + deBlockList(:,1,2) = (/4,1/) ! minIndex 2nd deBlock + deBlockList(:,2,2) = (/5,2/) ! maxIndex 2nd deBlock + deBlockList(:,1,3) = (/1,3/) + deBlockList(:,2,3) = (/2,4/) + deBlockList(:,1,4) = (/3,3/) + deBlockList(:,2,4) = (/5,4/) + deBlockList(:,1,5) = (/1,5/) + deBlockList(:,2,5) = (/3,5/) + deBlockList(:,1,6) = (/4,5/) ! minIndex 6th deBlock + deBlockList(:,2,6) = (/5,5/) ! maxInbex 6th deBlock ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/5,5/), & + deBlockList=deBlockList, rc=rc) ++ +
+ +
+Creating a DistGrid from a list of LR tiles is a straightforward + extension of the single tile case. The first four + arguments of ESMF_DistGridCreate() are promoted to rank 2 where the + second dimension is the tile index. + +
+The following 2D multi-tile domain consisting of 3 LR tiles will + be used in the examples of this section: +
+ + ----------------------------------------> 2nd dim + | + | (1,11)-----(1,20) + | | | + | | | + | | | + | | | + | | | + | (10,11)---(10,20) + | (11,1)----(11,10)(11,11)---(11,20) + | | || | + | | || | + | | || | + | | || | + | | || | + | (20,1)----(20,10)(20,11)---(20,20) + | + | + v + 1st dim ++ +
+The first step in creating a multi-tile global domain is to construct the + minIndex and maxIndex arrays. +
+
+ allocate(minIndexPTile(2,3)) ! (dimCount, tileCount) + allocate(maxIndexPTile(2,3)) ! (dimCount, tileCount) + minIndexPTile(:,1) = (/11,1/) + maxIndexPTile(:,1) = (/20,10/) + minIndexPTile(:,2) = (/11,11/) + maxIndexPTile(:,2) = (/20,20/) + minIndexPTile(:,3) = (/1,11/) + maxIndexPTile(:,3) = (/10,20/) ++ +
+Next the regular decomposition for each tile is set up in the + regDecomp array. In this example each tile is associated with a + single DE. +
+
+ allocate(regDecompPTile(2,3)) ! (dimCount, tileCount) + regDecompPTile(:,1) = (/1,1/) ! one DE + regDecompPTile(:,2) = (/1,1/) ! one DE + regDecompPTile(:,3) = (/1,1/) ! one DE ++ +
+Finally the DistGrid can be created by calling +
+ distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, & + maxIndexPTile=maxIndexPTile, regDecompPTile=regDecompPTile, rc=rc) ++ +
+The default DE labeling sequence is identical to the tile labeling sequence + and follows the sequence in which the tiles are defined during the create + call. However, DE labels start at 0 whereas tile labels start at 1. In this + case the DE labels look as: +
+ 2 + 0 1 ++ +
+Each tile can be decomposed differently into DEs. The default DE labeling + follows the column major order for each tile. This is demonstrated in the + following case where the multi-tile global domain is decomposed into 9 DEs, +
+
+ regDecompPTile(:,1) = (/2,2/) ! 4 DEs + regDecompPTile(:,2) = (/1,3/) ! 3 DEs + regDecompPTile(:,3) = (/2,1/) ! 2 DEs + + distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, & + maxIndexPTile=maxIndexPTile, regDecompPTile=regDecompPTile, rc=rc) ++ +
+resulting in the following decomposition: +
+ +-------+ + | 7 | + | | + | 8 | + +-------+-------+ + | 0 2 | | + | | 4 5 6 | + | 1 3 | | + +-------+-------+ ++ +
+
+ DE 0 - (11,1) ~ (15,5) + DE 1 - (16,1) ~ (20,5) + DE 2 - (11,6) ~ (15,10) + DE 3 - (16,6) ~ (20,10) + DE 4 - (11,11) ~ (20,14) + DE 5 - (11,15) ~ (20,17) + DE 6 - (11,18) ~ (20,20) + DE 7 - (1,11) ~ (5,20) + DE 8 - (6,11) ~ (10,20) ++ +
+The decompflag and deLabelList arguments can be used much like + in the single LR domain case to overwrite the default grid decomposition + (per tile) and to change the overall DE labeling sequence, respectively. + +
+ +
+The third, and most flexible way of creating an ESMF DistGrid object is + by specifying the arbitrary sequence indices of all the index space elements + associated with a particular DE. The concept of sequence index + comes into the DistGrid class through the support it implements for the + communication methods of higher classes: Arrays and Fields. This support + is based by associating a unique sequence index with each + DistGrid index tuple. The sequence index can be used to address every Array + or Field element. By default, the DistGrid does not actually generate and + store the sequence index of each element. Instead a default sequence through + the elements is implemented in the DistGrid code. This default sequence + is used internally when needed. + +
+The DistGrid class provides two ESMF_DistGridCreate() calls that + allow the user to specify arbitrary sequence indices, overriding the use of + the default sequence index scheme. The user sequence indices are passed to + the DistGrid in form of 1d Fortran arrays, one array on each PET. The local + size of this array on each PET determines the number of DistGrid elements on + the PET. The supplied sequence indices must be unique across all PETs. + +
+
+ allocate(arbSeqIndexList(10)) ! each PET will have 10 elements + + do i=1, 10 + arbSeqIndexList(i) = (i-1)*petCount + localPet ! initialize unique + ! seq. indices + enddo ++ +
+A default DELayout will be created automatically during + ESMF_DistGridCreate(), associating 1 DE per PET. +
+
+ distgrid = ESMF_DistGridCreate(arbSeqIndexList=arbSeqIndexList, rc=rc) ++ +
+The user provided sequence index array can be deallocated once it has + been used. +
+
+ deallocate(arbSeqIndexList) ++ +
+The distgrid object can be used just like any other DistGrid object. + The "arbitrary" nature of distgrid will only become visible during + Array or Field communication methods, where source and destination objects + map elements according to the sequence indices provided by the associated + DistGrid objects. +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+The second ESMF_DistGridCreate() call, that accepts the + arbSeqIndexList argument, allows the user to specify additional, + regular DistGrid dimensions. These additional DistGrid dimensions are not + decomposed across DEs, but instead are simply "added" or "multiplied" to the + 1D arbitrary dimension. + +
+The same arbSeqIndexList array as before is used to define the + user supplied sequence indices. +
+
+ allocate(arbSeqIndexList(10)) ! each PET will have 10 elements + + do i=1, 10 + arbSeqIndexList(i) = (i-1)*petCount + localPet ! initialize unique + ! seq. indices + enddo ++ +
+The additional DistGrid dimensions are specified in the usual manner using + minIndex and maxIndex arguments. The dimCount of the + resulting DistGrid is the size of the minIndex and maxIndex + arguments plus 1 for the arbitrary dimension. The arbDim argument is + used to indicate which or the resulting DistGrid dimensions + is associated with the arbitrary sequence indices provided by the user. +
+
+ distgrid = ESMF_DistGridCreate(arbSeqIndexList=arbSeqIndexList, & + arbDim=1, minIndexPTile=(/1,1/), maxIndexPTile=(/5,7/), rc=rc) ++ +
+
+ deallocate(arbSeqIndexList) ++ +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+ +
+By default all of the edges of the index space tiles making up a DistGrid + are open. There is no sense of connectedness between the tiles. This situation + is shown for a simple 2 tile DistGrid. +
+
+ allocate(minIndexPTile(2,2)) ! (dimCount, tileCount) + allocate(maxIndexPTile(2,2)) ! (dimCount, tileCount) + minIndexPTile(:,1) = (/1,1/) + maxIndexPTile(:,1) = (/10,10/) + minIndexPTile(:,2) = (/11,1/) + maxIndexPTile(:,2) = (/20,10/) + + distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, & + maxIndexPTile=maxIndexPTile, rc=rc) ++ +
+ +
+
+
+ |
+Connections between index space tiles are specified during DistGrid + creation through the connectionList argument. This argument takes + a list of elements of type(ESMF_DistGridConnection). Each element + refers to one specific connection between any two tiles. + +
+Each connection is defined by 4 parameters: + +
+The underlying principle of the DistGrid connections is that all supported
+ connections can be written as a forward transformation of the form
+
+
+As an example consider the index space point marked by the black circle in + figure 21. In the reference frame of + tile 1 the point has an index tuple of (11,3). Because of the global index + space (ESMF_INDEX_GLOBAL), the point has the same index + tuple of (11,3) in the reference frame of tile 2. Therefore, the connection + that connects the right edge of tile 1 with the left edge of tile 2 has + + (default orientation) and +. Therefore + the connection can be set by the following code. The resulting situation is + shown in figure 22. +
+
+ allocate(connectionList(1)) + call ESMF_DistGridConnectionSet(connection=connectionList(1), & + tileIndexA=1, tileIndexB=2, positionVector=(/0,0/), rc=rc) ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, & + maxIndexPTile=maxIndexPTile, connectionList=connectionList, & + rc=rc) ! defaults to ESMF_INDEX_GLOBAL ++ +
+The same topology can be defined for ESMF_INDEX_DELOCAL indexing. + However, the positionVector must be adjusted for the fact that now + the same point in index space has different index tuples depending on what + tile's reference frame is used. + +
+With local indexing both tiles start at (1,1) and end at (10,10). +
+
+ allocate(minIndexPTile(2,2)) ! (dimCount, tileCount) + allocate(maxIndexPTile(2,2)) ! (dimCount, tileCount) + minIndexPTile(:,1) = (/1,1/) + maxIndexPTile(:,1) = (/10,10/) + minIndexPTile(:,2) = (/1,1/) + maxIndexPTile(:,2) = (/10,10/) ++ +
+To see the impact that the index scheme has on the positionVector, + again consider the same highlighted index space point. The index tuple + for this point is still (11,3) in the reference frame of tile 1 (tile "A" of + the connection). However, in the reference frame of of tile 2 + (tile "B" of the connection)) it has changed to (1,3) due to local indexing. + Therefore, using form (4), we find that the + position vector must be +. +
+
+ allocate(connectionList(1)) + call ESMF_DistGridConnectionSet(connection=connectionList(1), & + tileIndexA=1, tileIndexB=2, positionVector=(/-10,0/), rc=rc) ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, & + maxIndexPTile=maxIndexPTile, connectionList=connectionList, & + indexflag=ESMF_INDEX_DELOCAL, rc=rc) ++ +
+ +
+
+
+ |
+Further note that every forward transformation has an associated inverse, or
+ backward transformation from tile "B" into the reference frame of tile "A".
+ Inverting the forward transform yields the backward transform as
+
+
+ | +(5) |
+Before going into the details of how the orientationVector and + positionVector arguments correspond to and for more + complex cases, it is useful to explore what class of connections are covered + by the above introduced form (4) of + +. + +
+First consider the case where tile "A" is rotated by + relative to tile "B" around a general pivot point given in terms + of the index space of tile "A": + +
+
+
+With substitution
+
+
+ | +(7) |
+Next consider transform (6) followed by + a translation of tile "B" relative to tile "A": + +
+
+
+Again form (4) is recovered with the
+ appropriate subsitution:
+
+
+Equation (9) is the general + definition of the positionVector argument for DistGrid connections. + It allows two tiles to be connected according to the relationship expressed + by (8). Note that this formualation of + tile connections is more general than connecting an edge of a tile to the + edge of another tile. Instead a DistGrid connection is specified as a general + relationship between the two index spaces, accounting for possible rotation + and translation. This formuation supports situations where some elements of + the connected tiles overlap with each other in index space. The ESMF + DistGrid class leverages this feature when representing topologies that + lead to redundancies of elements. Examples for this are the bipolar cut line + in a tripole grid, or the edges of a cubed sphere. + +
+By definition, DistGrid connections associate an index tuple of one tile + with exactly one index tuple expressed in the reference frame of another tile. + This restricts the supported rotations to multiples of . + Also allowing invesion of index space dimensions leads to 8 unique + operations in two dimension shown in table 3. + +
+
+ | + | orientationVector | +||
+ | + | ++ | +||
+ | + | ++ | +||
+ | + | ++ | +||
+ | + | ++ | +||
+ inversion dim 1 | ++ | ++ | +||
+ inversion dim 2 | ++ | ++ | +||
+ inversion dim 1 | ++ | ++ | +||
+ inversion dim 2 | ++ | ++ | +
+The orientationVector is simply a more compact format holding the same + information provided by the 8 rotational matrices. The first (or top) element + of the orientation vector indicates which dimension of the tile "A" index + tuple is used for the first dimension of the tile "B" tuple. The second + (or bottom) element of the orientation vector indicates which dimension of the + tile "A" index tuple is used for the second dimenson of the tile "B" tuple. + If an orientation vector entry is negative, the sign of the associated + tuple element is inverted when going from tile "A" to tile "B" reference + frame. Table 3 provides the corresponding + orientationVector argument for each of the 8 2D rotational operations. + +
+ +
+The concept of DistGrid connections is not limited to cases with multiple + tiles. Even a single tile DistGrid can have connections. In this instance + tileA and tileB simply reference the same tile. A very common + case is that of a single tile with periodic boundary conditions. + +
+First consider a single tile DistGrid without connections. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/50,20/), rc=rc) ++ +
+In order to better visualize the topology, the first index space + dimension is associated with the longitude ( +), and + the second dimension with latitude ( +) of the unit + sphere (using an ESMF_Grid object) as shown in figure + 23. + +
+ +
+
+
+ |
+A single DistGrid connection is needed to connect the right edge of the + index space tile with its left edge. Connecting a tile with itself in such + manner leads to a periodic topology. + +
+First the connectionList needs to be allocated for a single connection. + Then the connection is defined with both tileIndexA and + tileIndexB set to 1, referring to the first, and only tile in this case. +
+
+ allocate(connectionList(1)) + call ESMF_DistGridConnectionSet(connection=connectionList(1), & + tileIndexA=1, tileIndexB=1, positionVector=(/-50,0/), rc=rc) ++ +
+The positionVector is determined by transformation + (4), the fact that there is no rotation + involved, and that stepping over the right edge needs to connect back to + the left edge. Therefore +. Here stands for an arbitrary value along the second index + space dimension. + +
+Creating a DistGrid on the same index space tile, but with this connection, + results in a periodic boundary condition along the first dimension. + This is shown in figure 24. + +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/50,20/), & + connectionList=connectionList, rc=rc) ++ +
+ +
+
+
+ |
+In general it is more useful to express the position vector of a connection + in terms of the tile minIndex and maxIndex components. For this we define the + same index space tile in a set of variables. +
+
+ allocate(minIndex(2)) ! (dimCount) + allocate(maxIndex(2)) ! (dimCount) + minIndex(:) = (/1,1/) + maxIndex(:) = (/50,20/) ++ +
+Now we can code any connection on this tile in terms of minIndex and + maxIndex. For purpose of demonstration we define periodic boundary + conditions along both index space dimensions. The resulting torus topology + is depicted in figure 25. +
+
+ allocate(connectionList(2)) + call ESMF_DistGridConnectionSet(connection=connectionList(1), & ! 1st connection + tileIndexA=1, tileIndexB=1, & ! periodic along i + positionVector=(/ -(maxIndex(1)-minIndex(1)+1) , 0/), & + rc=rc) ++ +
+
+ call ESMF_DistGridConnectionSet(connection=connectionList(2), & ! 2nd connection + tileIndexA=1, tileIndexB=1, & ! periodic along j + positionVector=(/ 0 , -(maxIndex(2)-minIndex(2)+1) /), & + rc=rc) ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndex=minIndex, maxIndex=maxIndex, & + connectionList=connectionList, rc=rc) ++ +
+ +
+
+
+ |
+While the topology shown in figure + 25 is that of a torus, the + coordinates chosen are actually those of a sphere. Next we replace + the periodic connection along (i.e. the second index space dimension) + with a more fitting pole connection at the top of the sphere + (i.e. at ). + +
+For the orientation vector associated with a regular pole connection at + we first look at how the two index space directions are affected. + Looking at a point with along the first dimension, and a second point + that is just to the right of the first point, we see that as the + pole is being crossed, the second point maps just right of the first point. + Therefore, the orientation of the first index space dimension is unaffected + by the pole connection. However, for the second dimension we find that + increasing on one side corresponds to a dereasing across the pole. + We thus have found the general fact that orientationVector=(1,-2) for + a pole connection across the direction. + +
+In order to find the position vector of the polar connection we consider + starting at a general point (,) at the top edge of the tile. + Crossing the pole this takes us to a point that is again right on the + top edge with , and is rotated along the first + dimension. This means +, with +. + In practice the modulo operation is automatically taken care of by the + periodic connection along . We can therefore write: + +
+
+
+ | +(10) |
+Using this observation, together with table 3 to + translate the polar orientationVector into a standard rotation + operation , we get the position vector from equation + (4): + +
+
+
+ | + | + | + |
+ | + | + | + |
+ | + | + | +(11) |
+
+ allocate(connectionList(2)) + call ESMF_DistGridConnectionSet(connection=connectionList(1), & ! 1st connection + tileIndexA=1, tileIndexB=1, & ! periodic along i + positionVector=(/-(maxIndex(1)-minIndex(1)+1),0/), & + rc=rc) ++ +
+
+ call ESMF_DistGridConnectionSet(connection=connectionList(2), & ! 2nd connection + tileIndexA=1, tileIndexB=1, & ! pole at j_max + orientationVector=(/1,-2/), & + positionVector=(/ (maxIndex(1)-minIndex(1)+1)/2 , 2*maxIndex(2)+1 /), & + rc=rc) ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndex=minIndex, maxIndex=maxIndex, & + connectionList=connectionList, rc=rc) ++ +
+The pole connection at can clearly be seen in figure + 26. Note that the chosen perspective + hides the fact that the lower edge of the index space tile remains open. + In other words there is still a hole at the bottom of the sphere that cannot + be seen. Only three of the four sides have been connected so far: + The first connection + connects the left and the right tile edges. The second connection connects + the top edge to itself to form the pole. A third connection would be needed, + e.g. to form a pole at the bottom edge much like the top edge. + This would then complete a perfectly spherical topology with a single tile. + +
+ +
+
+
+ |
+The final single tile topology discussed in this section is that of a tripole. + A tripolar sphere has the typical spherical periodic boundary condition + along one direction (e.g. connecting the left and the right tile edge), and a + regular monopole at one of the other edges of the tile. However, instead + of defining a second monopole at the opposite edge, a bipole connection + is chosen. + +
+Topologically a bipole connection can be thought of folding the respective + edge at the middle point back onto itself. Assuming the bipole at the top + edge, i.e. at , we get mappings across the bipole of + +, + +, and so forth. + This means that + compared to the regular pole connection, the bipolar orientation vector + reverses the direction in addition to the direction: + orientationVector=(-1,-2). + +
+Using the bipolar mapping just mentioned for a point at , together + with table 3 to translate the polar orientationVector + into a standard rotation operation , we can solve for the position + vector according to equation (4): + +
+
+
+ | + | + | + |
+ | + | + | + |
+ | + | + | +(12) |
+Figure 27 visualizes the + bipolar topology at the top edge of the tile. Note, however, that the + coordinates are perfectly spherical. Consequently there is no "drawing + shut" of the cut line as would be expected for a true bipolar geometry. + Still, the two poles are becoming visible at the two opposing + ends of the top circle, where the distance between the connection lines is + starting to go to zero. + +
+ +
+
+
+ |
+
+ allocate(connectionList(3)) + call ESMF_DistGridConnectionSet(connection=connectionList(1), & ! 1st connection + tileIndexA=1, tileIndexB=1, & ! periodic along i + positionVector=(/-(maxIndex(1)-minIndex(1)+1),0/), & + rc=rc) ++ +
+
+ call ESMF_DistGridConnectionSet(connection=connectionList(2), & ! 2nd connection + tileIndexA=1, tileIndexB=1, & ! pole at j_min + orientationVector=(/1,-2/), & + positionVector=(/ (maxIndex(1)-minIndex(1)+1)/2 , 2*minIndex(2)+1 /), & + rc=rc) ++ +
+
+ call ESMF_DistGridConnectionSet(connection=connectionList(3), & ! 3rd connection + tileIndexA=1, tileIndexB=1, & ! bi-pole at j_max + orientationVector=(/-1,-2/), & + positionVector=(/ maxIndex(1)+minIndex(1) , 2*maxIndex(2)+1 /), & + rc=rc) ++ +
+
+ distgrid = ESMF_DistGridCreate(minIndex=minIndex, maxIndex=maxIndex, & + connectionList=connectionList, rc=rc) ++ +
+ +
+Starting point of the multi-tile connection examples will be the + six tile case shown in figure 28. + All six tiles are identical squares of size 10x10. + +
+ +
+
+
+ |
+One geometrical interpretation of the six tiles shown is that of an unfolded + cube. In fact, the way that the tiles are arranged in the 2D plane does + suggest the cubic interpretation. In order to turn the six tiles into a + cubic topology, each tile must be connected to its neighbors on all four + sides. In total there will be 12 connections that need to be made. + +
+Choosing global indexing, the depicted six tile case can be created + in the following way: +
+
+ allocate(minIndexPTile(2,6)) ! (dimCount, tileCount) + allocate(maxIndexPTile(2,6)) ! (dimCount, tileCount) + size = 10 ! number of index space points along tile sides + !- tile 1 + tile=1 + minIndexPTile(1,tile)=1 + minIndexPTile(2,tile)=1 + maxIndexPTile(1,tile)=minIndexPTile(1,tile)+size-1 + maxIndexPTile(2,tile)=minIndexPTile(2,tile)+size-1 + !- tile 2 + tile=2 + minIndexPTile(1,tile)=maxIndexPTile(1,tile-1)+1 + minIndexPTile(2,tile)=minIndexPTile(2,tile-1) + maxIndexPTile(1,tile)=minIndexPTile(1,tile)+size-1 + maxIndexPTile(2,tile)=minIndexPTile(2,tile)+size-1 + !- tile 3 + tile=3 + minIndexPTile(1,tile)=minIndexPTile(1,tile-1) + minIndexPTile(2,tile)=maxIndexPTile(2,tile-1)+1 + maxIndexPTile(1,tile)=minIndexPTile(1,tile)+size-1 + maxIndexPTile(2,tile)=minIndexPTile(2,tile)+size-1 + !- tile 4 + tile=4 + minIndexPTile(1,tile)=maxIndexPTile(1,tile-1)+1 + minIndexPTile(2,tile)=minIndexPTile(2,tile-1) + maxIndexPTile(1,tile)=minIndexPTile(1,tile)+size-1 + maxIndexPTile(2,tile)=minIndexPTile(2,tile)+size-1 + !- tile 5 + tile=5 + minIndexPTile(1,tile)=minIndexPTile(1,tile-1) + minIndexPTile(2,tile)=maxIndexPTile(2,tile-1)+1 + maxIndexPTile(1,tile)=minIndexPTile(1,tile)+size-1 + maxIndexPTile(2,tile)=minIndexPTile(2,tile)+size-1 + !- tile 6 + tile=6 + minIndexPTile(1,tile)=maxIndexPTile(1,tile-1)+1 + minIndexPTile(2,tile)=minIndexPTile(2,tile-1) + maxIndexPTile(1,tile)=minIndexPTile(1,tile)+size-1 + maxIndexPTile(2,tile)=minIndexPTile(2,tile)+size-1 + + distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, & + maxIndexPTile=maxIndexPTile, rc=rc) ++ +
+The five connections between tiles 1&2, 2&3, 3&4, 4&5, 5&6 are trivial. + There are no rotations, which means that the orientationVector argument + can be ommitted in these connections. Further, because of the global index + space, there are no translations either, which means that + positionVector=(0,0) for these five connections. The resulting + topology is shown in figure 29. +
+
+ allocate(connectionList(5)) + !- connection 1 + conn=1 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=1, tileIndexB=2, positionVector=(/0, 0/), rc=rc) + !- connection 2 + conn=2 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=2, tileIndexB=3, positionVector=(/0, 0/), rc=rc) + !- connection 3 + conn=3 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=3, tileIndexB=4, positionVector=(/0, 0/), rc=rc) + !- connection 4 + conn=4 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=4, tileIndexB=5, positionVector=(/0, 0/), rc=rc) + !- connection 5 + conn=5 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=5, tileIndexB=6, positionVector=(/0, 0/), rc=rc) + + distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, & + maxIndexPTile=maxIndexPTile, connectionList=connectionList, rc=rc) ++ +
+ +
+ ++The sixth connection that does not involve a rotation is that between tile + 1&6. While there is no rotation involved, it does include a translation + because the bottom edge of tile 1 must reach all the way to the top edge + of tile 6. This involves a translation along both the and the + dimension. + +
+Using the same procedure introduced in the previous section, we chose an + arbitrary index space point close to the connection and write it in terms + of both tiles that we want to connect. E.g. the first point of the top + edge of tile 6 is + +
+( minIndexPTile(1,6) , maxIndexPTile(2,6) ) + +
+in terms of tile 6. However, + in terms of tile 1, going through the connection, it is + +
+( minIndexPTile(1,1) , minIndexPTile(2,1)-1 ). + +
+According to the general transformation relationship + (4) the position vector for the + forward transform tile 1 tile 6 is then given as the + difference between these two representations. Figure + 30 visualizes the situation. +
+
+ !- connection 6 + conn=6 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=1, tileIndexB=6, & + positionVector=(/minIndexPTile(1,6)-minIndexPTile(1,1), & + maxIndexPTile(2,6)-minIndexPTile(2,1)+1/), & + rc=rc) + + distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, & + maxIndexPTile=maxIndexPTile, connectionList=connectionList, rc=rc) ++ +
+ +
+
+
+ |
+The six remaining connections all involve rotations. The procedure for finding + the correct orientationVector and positionVector arguments + still remains the same: First determine the direction of the connection + to be formulated. This is important because for the forward connection the + rotation applies to tile "A". Once the correct rotation operation is + pinned down, an arbitrary point close to the connection is chosen. This point + can either be on tile "A" or "B". It is written then written in terms of tile + "A" index space , and in terms of tile "B" index space . + Obviously one of those formulations (either or ) will take + advantage of the connection, i.e. it will actually step outside the reference + tile in order to reach the chosen point. Finally the position vector + of the connection is determined by expression + (4) as the difference: + +
+
+
+Following the above outlined procedure for connection tile 1 + tile 3, we find first that tile 1 needs to be rotated clockwise by . + This rotation lines up the top edge of tile 1 with the left edge of + tile 3. A clockwise rotation of corresponds to a counterclockwise + rotation by given in table 3. We therefore know + that orientationVector=(2,-1) for this connection, and the associated + operation is +. + +
+Next we chose the first point on the top edge of tile 1 as a reference point. + In terms of tile 1 this point has coordinates + +
+ = ( minIndexPTile(1,1) , maxIndexPTile(2,1) ). + +
+The same point in terms of tile 3 (going through the connection) has + coordinates + +
+ = ( minIndexPTile(1,3)-1 , maxIndexPTile(2,3) ). + +
+Using equation (13) we find the position vector and + can write down the connection: +
+
+ allocate(connectionList(2)) + !- connection 1 + conn=1 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=1, tileIndexB=3, & + orientationVector=(/2,-1/), & ! 270 degree rotation of tile A + positionVector=(/minIndexPTile(1,3)-1-maxIndexPTile(2,1), & + maxIndexPTile(2,3)+minIndexPTile(1,1)/), & + rc=rc) ++ +
+For greater clarity figure 31 only + shows two connections. Besides the connection just defined between tile 1 + and 3, the other connection shown is between tile 4 and 6. Defining the + connection as forward going from tile 4 to tile 6 means that tile 4 needs + to be rotated in such a way that its right edge meets up with the bottom + edge of tile 6. This requires a counterclockwise rotation of tile 4 by + . From table 3 we then get + orientationVector=(-2,1), and +. + +
+Choosing the left most point on the bottom edge of tile 6 as the reference + point, we find the coordinates in terms of tile 4 (through the connection) + +
+ = ( maxIndexPTile(1,4)+1 , maxIndexPTile(2,4) ), + +
+and in terms of tile 6 + +
+ = ( minIndexPTile(1,6) , minIndexPTile(2,6) ). + +
+Again using equation (13) we find the position vector + and can implement the second connection: +
+
+ !- connection 2 + conn=2 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=4, tileIndexB=6, & + orientationVector=(/-2,1/), & ! 90 degree rotation of tile A + positionVector=(/minIndexPTile(1,6)+maxIndexPTile(2,4), & + minIndexPTile(2,6)-maxIndexPTile(1,4)-1/), & + rc=rc) + + distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, & + maxIndexPTile=maxIndexPTile, connectionList=connectionList, rc=rc) ++ +
+ +
+
+
+ |
+The remaining four connections with rotations can be determined following the + exact same recipe. The following code finally defines all 12 connections + needed to connect the six index space tiles into a cubic topology. +
+
+ allocate(connectionList(12)) + + !- connection 1: tile 1 -> tile 2 + conn=1 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=1, tileIndexB=2, positionVector=(/0, 0/), rc=rc) + + !- connection 2: tile 2 -> tile 3 + conn=2 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=2, tileIndexB=3, positionVector=(/0, 0/), rc=rc) + + !- connection 3: tile 3 -> tile 4 + conn=3 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=3, tileIndexB=4, positionVector=(/0, 0/), rc=rc) + + !- connection 4: tile 4 -> tile 5 + conn=4 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=4, tileIndexB=5, positionVector=(/0, 0/), rc=rc) + + !- connection 5: tile 5 -> tile 6 + conn=5 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=5, tileIndexB=6, positionVector=(/0, 0/), rc=rc) + + !- connection 6: tile 1 -> tile 6 + conn=6 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=1, tileIndexB=6, & + positionVector=(/minIndexPTile(1,6)-minIndexPTile(1,1), & + maxIndexPTile(2,6)-minIndexPTile(2,1)+1/), & + rc=rc) + + !- connection 7: tile 1 -> tile 3 + conn=7 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=1, tileIndexB=3, & + orientationVector=(/2,-1/), & ! 270 degree rotation of tile A + positionVector=(/minIndexPTile(1,3)-1-maxIndexPTile(2,1), & + maxIndexPTile(2,3)+minIndexPTile(1,1)/), & + rc=rc) + + !- connection 8: tile 3 -> tile 5 + conn=8 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=3, tileIndexB=5, & + orientationVector=(/2,-1/), & ! 270 degree rotation of tile A + positionVector=(/minIndexPTile(1,5)-1-maxIndexPTile(2,3), & + maxIndexPTile(2,5)+minIndexPTile(1,3)/), & + rc=rc) + + !- connection 9: tile 5 -> tile 1 + conn=9 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=5, tileIndexB=1, & + orientationVector=(/2,-1/), & ! 270 degree rotation of tile A + positionVector=(/minIndexPTile(1,1)-1-maxIndexPTile(2,5), & + maxIndexPTile(2,1)+minIndexPTile(1,5)/), & + rc=rc) + + !- connection 10: tile 2 -> tile 4 + conn=10 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=2, tileIndexB=4, & + orientationVector=(/-2,1/), & ! 90 degree rotation of tile A + positionVector=(/minIndexPTile(1,4)+maxIndexPTile(2,2), & + minIndexPTile(2,4)-maxIndexPTile(1,2)-1/), & + rc=rc) + + !- connection 11: tile 4 -> tile 6 + conn=11 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=4, tileIndexB=6, & + orientationVector=(/-2,1/), & ! 90 degree rotation of tile A + positionVector=(/minIndexPTile(1,6)+maxIndexPTile(2,4), & + minIndexPTile(2,6)-maxIndexPTile(1,4)-1/), & + rc=rc) + + !- connection 12: tile 6 -> tile 2 + conn=12 + call ESMF_DistGridConnectionSet(connection=connectionList(conn), & + tileIndexA=6, tileIndexB=2, & + orientationVector=(/-2,1/), & ! 90 degree rotation of tile A + positionVector=(/minIndexPTile(1,2)+maxIndexPTile(2,6), & + minIndexPTile(2,2)-maxIndexPTile(1,6)-1/), & + rc=rc) + + ! - create the DistGrid with 6 tiles and 12 connections + distgrid = ESMF_DistGridCreate(minIndexPTile=minIndexPTile, & + maxIndexPTile=maxIndexPTile, connectionList=connectionList, rc=rc) ++ +
+For better visualization the resulting cubic topology is plotted in 3D. + Each index space point is associated with a longitude and latitude value + of the unit sphere. Combined with the cubic topology formed by the six + index space tiles, this results in a cubed sphere representation shown in + figure 32. + +
+ +
+
+
+ |
+ + +
+ +
+This section will be updated as the implementation of the DistGrid class +nears completion. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + distgrid1 = distgrid2 +ARGUMENTS: +
type(ESMF_DistGrid) :: distgrid1 + type(ESMF_DistGrid) :: distgrid2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign distgrid1 as an alias to the same ESMF DistGrid object in memory + as distgrid2. If distgrid2 is invalid, then distgrid1 will be equally + invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (distgrid1 == distgrid2) then ... endif + OR + result = (distgrid1 == distgrid2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid1 + type(ESMF_DistGrid), intent(in) :: distgrid2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether distgrid1 and distgrid2 are valid aliases to the same ESMF + DistGrid object in memory. For a more general comparison of two + ESMF DistGrids, going beyond the simple alias test, the + ESMF_DistGridMatch() function (not yet fully implemented) must + be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (distgrid1 /= distgrid2) then ... endif + OR + result = (distgrid1 /= distgrid2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid1 + type(ESMF_DistGrid), intent(in) :: distgrid2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether distgrid1 and distgrid2 are not valid aliases to the + same ESMF DistGrid object in memory. For a more general comparison of two + ESMF DistGrids, going beyond the simple alias test, the + ESMF_DistGridMatch() function (not yet fully implemented) must + be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridCreate() + function ESMF_DistGridCreateDG(distgrid, & + firstExtra, lastExtra, indexflag, connectionList, balanceflag, & + delayout, vm, rc) +RETURN VALUE: +
type(ESMF_DistGrid) :: ESMF_DistGridCreateDG +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, target, intent(in), optional :: firstExtra(:) + integer, target, intent(in), optional :: lastExtra(:) + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_DistGridConnection), intent(in), optional :: connectionList(:) + logical, intent(in), optional :: balanceflag + type(ESMF_DELayout), intent(in), optional :: delayout + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create a new DistGrid from an existing DistGrid, keeping the decomposition + unchanged, unless balanceflag=.true. (see below). + The firstExtraPTile and lastExtraPTile arguments allow extra + elements to be added at the first/last edge DE in each dimension. The + method also allows the indexflag to be set. Further, if the + connectionList argument provided in it will be used to set + connections in the newly created DistGrid, otherwise the connections of + the incoming DistGrid will be used. + +
+The balanceflag argument allows a change in the decomposition, and + thus of the number of DEs. An attempt is made to decompose the index + space into as many DEs as there are PETs in the VM for which the DistGrid + is created. See the argument description for details. + +
+Setting the balanceflag argument to .true. is currently + incompatible with providing any of the other optional arguments. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridCreate() + function ESMF_DistGridCreateDGT(distgrid, firstExtraPTile, & + lastExtraPTile, indexflag, connectionList, balanceflag, & + delayout, vm, rc) +RETURN VALUE: +
type(ESMF_DistGrid) :: ESMF_DistGridCreateDGT +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + integer, target, intent(in) :: firstExtraPTile(:,:) + integer, target, intent(in) :: lastExtraPTile(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_DistGridConnection), intent(in), optional :: connectionList(:) + logical, intent(in), optional :: balanceflag + type(ESMF_DELayout), intent(in), optional :: delayout + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create a new DistGrid from an existing DistGrid, keeping the decomposition + unchanged, unless balanceflag=.true. (see below). + The firstExtraPTile and lastExtraPTile arguments allow extra + elements to be added at the first/last edge DE in each dimension. The + method also allows the indexflag to be set. Further, if the + connectionList argument provided in it will be used to set + connections in the newly created DistGrid, otherwise the connections of + the incoming DistGrid will be used. + +
+The balanceflag argument allows a change in the decomposition, and + thus of the number of DEs. An attempt is made to decompose the index + space into as many DEs as there are PETs in the VM for which the DistGrid + is created. See the argument description for details. + +
+Setting the balanceflag argument to .true. is currently + incompatible with providing any of the other optional arguments. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridCreate() + function ESMF_DistGridCreateRD(minIndex, maxIndex, regDecomp, & + decompflag, regDecompFirstExtra, regDecompLastExtra, deLabelList, & + indexflag, connectionList, delayout, vm, indexTK, rc) +RETURN VALUE: +
type(ESMF_DistGrid) :: ESMF_DistGridCreateRD +ARGUMENTS: +
integer, intent(in) :: minIndex(:) + integer, intent(in) :: maxIndex(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, target, intent(in), optional :: regDecomp(:) + type(ESMF_Decomp_Flag), target, intent(in), optional :: decompflag(:) + integer, target, intent(in), optional :: regDecompFirstExtra(:) + integer, target, intent(in), optional :: regDecompLastExtra(:) + integer, target, intent(in), optional :: deLabelList(:) + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_DistGridConnection), intent(in), optional :: connectionList(:) + type(ESMF_DELayout), intent(in), optional :: delayout + type(ESMF_VM), intent(in), optional :: vm + type(ESMF_TypeKind_Flag), intent(in), optional :: indexTK + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_DistGrid from a single logically rectangular tile. + The tile has a regular decomposition, where the tile is decomposed + into a fixed number of DEs along each dimension. A regular decomposition + of a single tile is expressed by a single regDecomp list of DE + counts in each dimension. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridCreate() + function ESMF_DistGridCreateRDT(minIndexPTile, maxIndexPTile, & + regDecompPTile, decompflagPTile, regDecompFirstExtraPTile,& + regDecompLastExtraPTile, deLabelList, indexflag, connectionList, & + delayout, vm, indexTK, rc) +RETURN VALUE: +
type(ESMF_DistGrid) :: ESMF_DistGridCreateRDT +ARGUMENTS: +
integer, intent(in) :: minIndexPTile(:,:) + integer, intent(in) :: maxIndexPTile(:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: regDecompPTile(:,:) + type(ESMF_Decomp_Flag), target, intent(in), optional :: decompflagPTile(:,:) + integer, target, intent(in), optional :: regDecompFirstExtraPTile(:,:) + integer, target, intent(in), optional :: regDecompLastExtraPTile(:,:) + integer, intent(in), optional :: deLabelList(:) + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_DistGridConnection), intent(in), optional :: connectionList(:) + type(ESMF_DELayout), intent(in), optional :: delayout + type(ESMF_VM), intent(in), optional :: vm + type(ESMF_TypeKind_Flag), intent(in), optional :: indexTK + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_DistGrid from multiple logically rectangular tiles. + Each tile has a regular decomposition, where the tile is decomposed + into a fixed number of DEs along each dimension. A regular decomposition + of a multi-tile DistGrid is expressed by a list of DE count vectors, one + vector for each tile. If a DELayout is specified, it must contain at least + as many DEs as there are tiles. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridCreate() + function ESMF_DistGridCreateDB(minIndex, maxIndex, deBlockList, & + deLabelList, indexflag, connectionList, delayout, vm, & + indexTK, rc) +RETURN VALUE: +
type(ESMF_DistGrid) :: ESMF_DistGridCreateDB +ARGUMENTS: +
integer, intent(in) :: minIndex(:) + integer, intent(in) :: maxIndex(:) + integer, intent(in) :: deBlockList(:,:,:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: deLabelList(:) + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_DistGridConnection), intent(in), optional :: connectionList(:) + type(ESMF_DELayout), intent(in), optional :: delayout + type(ESMF_VM), intent(in), optional :: vm + type(ESMF_TypeKind_Flag), intent(in), optional :: indexTK + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_DistGrid from a single logically rectangular + tile with decomposition specified by deBlockList. + +
+The arguments are: +
+ +---------------------------------------> 2nd index + | 1 2 + | 1 minIndex(1) maxIndex(1) + | 2 minIndex(2) maxIndex(2) + | . minIndex(.) maxIndex(.) + | . + v + 1st index ++ It is required that there be no overlap between the DE blocks. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridCreate() + function ESMF_DistGridCreateDBT(minIndexPTile, maxIndexPTile, deBlockList, & + deToTileMap, deLabelList, indexflag, connectionList, & + delayout, vm, indexTK, rc) +RETURN VALUE: +
type(ESMF_DistGrid) :: ESMF_DistGridCreateDBT +ARGUMENTS: +
integer, intent(in) :: minIndexPTile(:,:) + integer, intent(in) :: maxIndexPTile(:,:) + integer, intent(in) :: deBlockList(:,:,:) + integer, intent(in) :: deToTileMap(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: deLabelList(:) + type(ESMF_Index_Flag), intent(in), optional :: indexflag + type(ESMF_DistGridConnection), intent(in), optional :: connectionList(:) + type(ESMF_DELayout), intent(in), optional :: delayout + type(ESMF_VM), intent(in), optional :: vm + type(ESMF_TypeKind_Flag), intent(in), optional :: indexTK + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_DistGrid on multiple logically + rectangular tiles with decomposition specified by deBlockList. + +
+The arguments are: +
+ +---------------------------------------> 2nd index + | 1 2 + | 1 minIndex(1) maxIndex(1) + | 2 minIndex(2) maxIndex(2) + | . minIndex(.) maxIndex(.) + | . + v + 1st index ++ It is required that there be no overlap between the DE blocks. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridCreate() + function ESMF_DistGridCreateDBAI1D1DE(arbSeqIndexList, rc) +RETURN VALUE: +
type(ESMF_DistGrid) :: ESMF_DistGridCreateDBAI1D1DE +ARGUMENTS: +
integer, intent(in) :: arbSeqIndexList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_DistGrid of dimCount 1 from a PET-local list + of sequence indices. The PET-local size of the arbSeqIndexList + argument determines the number of local elements in the created DistGrid. + The sequence indices must be unique across all PETs. A default + DELayout with 1 DE per PET across all PETs of the current VM is + automatically created. + +
+This is a collective method across the current VM. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridCreate() + function ESMF_DistGridCreateDBAI1D1DEI8(arbSeqIndexList, rc) +RETURN VALUE: +
type(ESMF_DistGrid) :: ESMF_DistGridCreateDBAI1D1DEI8 +ARGUMENTS: +
integer(ESMF_KIND_I8), intent(in) :: arbSeqIndexList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_DistGrid of dimCount 1 from a PET-local list + of sequence indices. The PET-local size of the arbSeqIndexList + argument determines the number of local elements in the created DistGrid. + The sequence indices must be unique across all PETs. A default + DELayout with 1 DE per PET across all PETs of the current VM is + automatically created. + +
+This is a collective method across the current VM. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridCreate() + function ESMF_DistGridCreateDBAI1D(arbSeqIndexList, rc) +RETURN VALUE: +
type(ESMF_DistGrid) :: ESMF_DistGridCreateDBAI1D +ARGUMENTS: +
type(ESMF_PtrInt1D), intent(in) :: arbSeqIndexList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create an ESMF_DistGrid of dimCount 1 from a PET-local list + of sequence index lists. The PET-local size of the arbSeqIndexList + argument determines the number of local DEs in the created DistGrid. + Each of the local DEs is associated with as many index space elements as + there are arbitrary sequence indices in the associated list. + The sequence indices must be unique across all DEs. A default + DELayout with the correct number of DEs per PET is automatically created. + +
+This is a collective method across the current VM. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridCreate() + function ESMF_DistGridCreateDBAI(arbSeqIndexList, arbDim, & + minIndexPTile, maxIndexPTile, rc) +RETURN VALUE: +
type(ESMF_DistGrid) :: ESMF_DistGridCreateDBAI +ARGUMENTS: +
integer, intent(in) :: arbSeqIndexList(:) + integer, intent(in) :: arbDim + integer, intent(in) :: minIndexPTile(:) + integer, intent(in) :: maxIndexPTile(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_DistGrid of dimCount , where + size(minIndexPTile) = size(maxIndexPTile). + +
+The resulting DistGrid will have a 1D distribution determined by the + PET-local arbSeqIndexList. The PET-local size of the + arbSeqIndexList argument determines the number of local elements + along the arbitrarily distributed dimension in the created DistGrid. The + sequence indices must be unique across all PETs. The associated, + automatically created DELayout will have 1 DE per PET across all PETs of + the current VM. + +
+In addition to the arbitrarily distributed dimension, regular DistGrid + dimensions can be specified in minIndexPTile and maxIndexPTile. The + dimensional subspace spanned by the regular dimensions is "multiplied" + with the arbitrary dimension on each DE, to form a dimensional + total index space described by the DistGrid object. The arbDim + argument allows to specify which dimension in the resulting DistGrid + corresponds to the arbitrarily distributed one. + +
+This is a collective method across the current VM. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DistGridDestroy(distgrid, noGarbage, rc) +ARGUMENTS: +
type(ESMF_DistGrid), intent(inout) :: distgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroys an ESMF_DistGrid, releasing the resources associated + with the object. + +
+By default a small remnant of the object is kept in memory in order to + prevent problems with dangling aliases. The default garbage collection + mechanism can be overridden with the noGarbage argument. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridGet() + subroutine ESMF_DistGridGetDefault(distgrid, delayout, & + dimCount, tileCount, deCount, localDeCount, minIndexPTile, maxIndexPTile, & + elementCountPTile, elementCountPTileI8, minIndexPDe, maxIndexPDe, & + elementCountPDe, elementCountPDeI8, localDeToDeMap, deToTileMap, & + indexCountPDe, collocation, regDecompFlag, indexTK, indexflag, & + connectionCount, connectionList, rc) +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DELayout), intent(out), optional :: delayout + integer, intent(out), optional :: dimCount + integer, intent(out), optional :: tileCount + integer, intent(out), optional :: deCount + integer, intent(out), optional :: localDeCount + integer, target, intent(out), optional :: minIndexPTile(:,:) + integer, target, intent(out), optional :: maxIndexPTile(:,:) + integer, target, intent(out), optional :: elementCountPTile(:) + integer(ESMF_KIND_I8),target, intent(out), optional :: elementCountPTileI8(:) + integer, target, intent(out), optional :: minIndexPDe(:,:) + integer, target, intent(out), optional :: maxIndexPDe(:,:) + integer, target, intent(out), optional :: elementCountPDe(:) + integer(ESMF_KIND_I8),target, intent(out), optional :: elementCountPDeI8(:) + integer, target, intent(out), optional :: localDeToDeMap(:) + integer, target, intent(out), optional :: deToTileMap(:) + integer, target, intent(out), optional :: indexCountPDe(:,:) + integer, target, intent(out), optional :: collocation(:) + logical, intent(out), optional :: regDecompFlag + type(ESMF_TypeKind_Flag), intent(out), optional :: indexTK + type(ESMF_Index_Flag), intent(out), optional :: indexflag + integer, intent(out), optional :: connectionCount + type(ESMF_DistGridConnection), & + target, intent(out), optional :: connectionList(:) + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Access internal DistGrid information. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridGet() + subroutine ESMF_DistGridGetPLocalDe(distgrid, localDe, & + de, tile, collocation, arbSeqIndexFlag, seqIndexList, seqIndexListI8, & + elementCount, elementCountI8, rc) +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + integer, intent(in) :: localDe + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: de + integer, intent(out), optional :: tile + integer, intent(in), optional :: collocation + logical, intent(out), optional :: arbSeqIndexFlag + integer, target, intent(out), optional :: seqIndexList(:) + integer(ESMF_KIND_I8),target, intent(out), optional :: seqIndexListI8(:) + integer, intent(out), optional :: elementCount + integer, intent(out), optional :: elementCountI8 + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Access internal DistGrid information. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridGet() + subroutine ESMF_DistGridGetPLocalDePDim(distgrid, localDe, dim, & + indexList, rc) +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + integer, intent(in) :: localDe + integer, intent(in) :: dim + integer, target, intent(out) :: indexList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Access internal DistGrid information. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_DistGridIsCreated(distgrid, rc) +RETURN VALUE: +
logical :: ESMF_DistGridIsCreated +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the distgrid has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DistGridLog(distgrid, prefix, logMsgFlag, deepFlag, rc) +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: prefix + type(ESMF_LogMsg_Flag), intent(in), optional :: logMsgFlag + logical, intent(in), optional :: deepFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write information about DistGrid to the ESMF default Log. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_DistGridMatch(distgrid1, distgrid2, rc) +RETURN VALUE: +
type(ESMF_DistGridMatch_Flag) :: ESMF_DistGridMatch +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid1 + type(ESMF_DistGrid), intent(in) :: distgrid2 + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Determine to which level distgrid1 and distgrid2 match. + +
+Returns a range of values of type ESMF_DistGridMatch_Flag, + indicating how closely the DistGrids match. For a description of the + possible return values, see 36.2.1. + Note that this call only performs PET local matching. Different return values + may be returned on different PETs for the same DistGrid pair. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DistGridPrint(distgrid, rc) +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Prints internal information about the specified ESMF_DistGrid
+ object to stdout.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DistGridSet() + subroutine ESMF_DistGridSetPLocalDe(distgrid, localDe, collocation, & + seqIndexList, seqIndexListI8, rc) +ARGUMENTS: +
type(ESMF_DistGrid), intent(inout) :: distgrid + integer, intent(in) :: localDe + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: collocation + integer, target, intent(in), optional :: seqIndexList(:) + integer(ESMF_KIND_I8),target, intent(in), optional :: seqIndexListI8(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set DistGrid information for a specific local DE. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DistGridValidate(distgrid, rc) +ARGUMENTS: +
type(ESMF_DistGrid), intent(in) :: distgrid + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Validates that the distgrid is internally consistent. + The method returns an error code if problems are found. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DistGridConnectionGet(connection, & + tileIndexA, tileIndexB, dimCount, positionVector, orientationVector, rc) +ARGUMENTS: +
type(ESMF_DistGridConnection), intent(in) :: connection + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: tileIndexA + integer, intent(out), optional :: tileIndexB + integer, intent(out), optional :: dimCount + integer, intent(out), optional :: positionVector(:) + integer, intent(out), optional :: orientationVector(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Get connection parameters from an ESMF_DistGridConnection object. + This interface provides access to all variables required to create a new + connection using the ESMF_DistGridConnectionSet() method. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DistGridConnectionSet(connection, tileIndexA, tileIndexB, & + positionVector, orientationVector, rc) +ARGUMENTS: +
type(ESMF_DistGridConnection),intent(out) :: connection + integer, intent(in) :: tileIndexA + integer, intent(in) :: tileIndexB + integer, intent(in) :: positionVector(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: orientationVector(:) + integer, intent(out), optional:: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+ Set an ESMF_DistGridConnection object to represent a connection + according to the provided index space information. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DistGridRegDecompSetCubic(regDecomp, deCount, rc) +ARGUMENTS: +
integer, target, intent(out) :: regDecomp(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: deCount + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Construct a regular decomposition argument for DistGrid that is most cubic + in dimCount dimensions, and multiplies out to deCount DEs. The + factorization is stable monotonic decreasing, ensuring that earlier entries + in regDecomp are larger or equal to the later entires. + +
+The arguments are: +
+ + +
+The ESMF RouteHandle class provides a unified interface for all route-based communication methods across the Field, FieldBundle, Array, and ArrayBundle classes. All route-based communication methods implement a pre-computation step, returning a RouteHandle, an execution step, and a release step. Typically the pre-computation, or Store() step will be a lot more expensive (both in memory and time) than the execution step. The idea is that once precomputed, a RouteHandle will be executed many times over during a model run, making the execution time a very performance critical piece of code. In ESMF, Regridding, Redisting, and Haloing are implemented as route-based communication methods. The following sections discuss the RouteHandle concepts that apply uniformly to all route-based communication methods, across all of the above mentioned classes. + +
+ +
+The user interacts with the RouteHandle class through the route-based communication methods of Field, FieldBundle, Array, and ArrayBundle. The usage of these methods are described in detail under their respective class documentation section. The following examples focus on the RouteHandle aspects common across classes and methods. + +
+ +
+ +
+ +
+Bit-for-bit (bfb) reproducibility is at the core of the regression testing + schemes of many scientific model codes. The bfb requirement makes it possible + to easily compare the numerical results of simulation runs using standard + binary diff tools. + +
+While bfb reproducibility is desirable (and often required) for regression + testing, it does limit the available performance optimization + opportunities. Especially in highly parallelized code, best performance is + often achieved by allowing operations to occur in a flexible order. Under + some conditions, however, a change in the order of numerical operations + leads to small numerical differences in the results, breaking bfb + reproducibility. + +
+ESMF provides the following three levels of bfb reproducibility + support, with the associated performance optimization implications: + +
+ +
+
+
+
+The following discussion uses very simple numerical examples to demonstrate + how the order of terms in a sum can lead to results that are not + bit-for-bit identical. The examples use single precision, + ESMF_KIND_R4 numbers, but the concepts apply the same + to double precision, ESMF_KIND_R8; only that the decimals, for + which bfb differences in the sums occur, are different ones. + +
+With sumA, sumB, sumC, sumD, and sumE all of + type real(ESMF_KIND_R4), one finds the following bfb differences: +
+
+ sumA = (0.5 + 0.1) + 0.1 ! results in 0.700000048 + sumB = 0.5 + (0.1 + 0.1) ! results in 0.699999988 + + sumC = 0.5 + 0.2 + 0.1 + 0.1 ! results in 0.900000036 + sumD = 0.5 + (0.2 + 0.1) + 0.1 ! results in 0.900000036 + sumE = 0.5 + (0.2 + 0.1 + 0.1) ! results in 0.899999976 ++ +
+These differences result from the fact that many decimals (even very simple + ones like 0.1 or 0.2) lead to periodic binary floating point numbers. + Periodic floating point numbers must be truncated when represented by a + finite number of bits, leading to small rounding errors. Further truncation + occurs when the radix point of two numbers must be aligned during + floating point arithmetic, resulting in bit shifts for one of the + numbers. The resulting truncation error depends on the precise numbers that + need alignment. As a result, executing the "same" sum in a different order + can lead to different truncation steps and consequently in results that are + not bit-for-bit identical. + +
+In order to help users with the implementation of their bfb requirement, + ESMF provides different levels of control over the term order in sparse + matrix multiplications, while at the same time offering performance + optimization options. In all there are three arguments that will be + introduced in the following paragraphs: srcTermProcessing, + termorderflag, and pipelineDepth. + +
+For the purpose of demonstration, a one-dimensional, arbitrarily distributed + source Array is constructed. There are three Array elements on each of the + four PETs. Their local storage indices, sequence indices, and data values + are as follows: + +
+
+ + +-----+-------+----------------+------------+ + | PET | index | sequence index | data value | + +-----+-------+----------------+------------+ + | 0 | 1 | 1 | 0.5 | + | 0 | 2 | 6 | 0.1 | + | 0 | 3 | 9 | 0.1 | + +-----+-------+----------------+------------+ + | 1 | 1 | 4 | 0.5 | + | 1 | 2 | 3 | 0.1 | + | 1 | 3 | 10 | 0.1 | + +-----+-------+----------------+------------+ + | 2 | 1 | 11 | 0.5 | + | 2 | 2 | 7 | 0.1 | + | 2 | 3 | 5 | 0.1 | + +-----+-------+----------------+------------+ + | 3 | 1 | 8 | 0.1 | + | 3 | 2 | 2 | 0.2 | + | 3 | 3 | 12 | 0.1 | + +-----+-------+----------------+------------+ ++ +
+The destination Array consists of only a single element, located on PET 0: + +
+
+ + +-----+-------+----------------+------------+ + | PET | index | sequence index | data value | + +-----+-------+----------------+------------+ + | 0 | 1 | 1 | n/a | + +-----+-------+----------------+------------+ ++ +
+As a first example consider the following sparse matrix with three entries: +
+
+ factorIndexList(1,1) = 1 ! src seq index + factorIndexList(2,1) = 1 ! dst seq index + factorList(1) = 1. + factorIndexList(1,2) = 6 ! src seq index + factorIndexList(2,2) = 1 ! dst seq index + factorList(2) = 1. + factorIndexList(1,3) = 9 ! src seq index + factorIndexList(2,3) = 1 ! dst seq index + factorList(3) = 1. ++ +
+In ESMF, the order in which the sparse matrix entries are specified in + factorIndexList and factorList, or on which PET they + are provided, is completely irrelevant. The term order in the resulting + sparse matrix sums is not affected by it. + +
+There is one aspect of the sparse matrix format, however, that is relevant + to the bfb considerations: When multiple entries for the same (src, dst) + pair are present in a sparse matrix definition, the entries are summed + into a single (src, dst) entry. Therefore, even if there are multiple + sparse matrix entries for the same (src, dst) pair, there will only be a + single term for it in the resulting expression. + +
+Going back to the three term sparse matrix definition above, the + canonical term order is defined by the source sequence indices in + ascending order. With (src,dst) denoting the sparse matrix factors, + and s(src) and d(dst) denoting source and destination Array + elements, respectively, for src and dst sequence indices, the + sum in canonical order is: + +
+d(1) = (1,1)*s(1) + (6,1)*s(6) + (9,1)*s(9) + +
+For simplicity, the factors in all of the examples are set to 1.0, allowing us + to drop them in the expressions. This helps focus on the critical issue - + term order: + +
+d(1) = s(1) + s(6) + s(9) + +
+There are two parameters that affect term order in the ESMF sparse matrix + multiplication (SMM), and therefore must be considered in the context of bfb + reproducibility. First there is the srcTermProcessing parameter which + controls grouping of source terms located on the same PET. The value of the + srcTermProcessing parameter indicates the maximum number of terms that + may be grouped into partial sums on the source PET. Setting + srcTermProcessing to 1 means that no partial sums are formed on the + source side, however, the source terms are multiplied with their + respective sparse matrix factor before being sent to the destination PET. + Setting srcTermProcessing to 0 prevents these products from being carried + out on the source side, and the source Array elements are sent unmodified. + Depending on the distribution of the source Array, values greater than 1 + for srcTermProcessing can lead to partial sums and thus may have + impact on the bfb reproducibility of the SMM. + +
+The second parameter that may have bfb effects comes into play at + execution-time of a precomputed + RouteHandle. It is accessible via the termorderflag argument; a typed + flag with the following values: + +
+ESMF_TERMORDER_SRCSEQ + +
+First using srcTermProcessing=0 at store time and + termorderflag=ESMF_TERMORDER_SRCSEQ at execution time, + the canonical term order is expected: + +
+d(1) = s(1) + s(6) + s(9) = 0.5 + 0.1 + 0.1 = sumA + +
+
+ ! forced srcTermProcessing + srcTermProcessing = 0 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCSEQ, rc=rc) ++ +
+
+ if (localPet == 0) then + print *, "result SRCSEQ#1 = ", farrayPtr(1), " expect: ", sumA + if (farrayPtr(1) /= sumA) & + finalrc = ESMF_FAILURE + endif ++ +
+The order of source terms across PETs is expected to have no effect on the + bfb reproducibility of the result for ESMF_TERMORDER_SRCSEQ. To test + this, a sparse matrix is used where the source terms originate from different + PETs. +
+
+ factorIndexList(1,1) = 4 ! src seq index + factorIndexList(2,1) = 1 ! dst seq index + factorList(1) = 1. + factorIndexList(1,2) = 5 ! src seq index + factorIndexList(2,2) = 1 ! dst seq index + factorList(2) = 1. + factorIndexList(1,3) = 12 ! src seq index + factorIndexList(2,3) = 1 ! dst seq index + factorList(3) = 1. ++ +
+Again the srcTermProcessing argument is kept at 0, ensuring that none + of the source terms are grouped into partial sums. + +
+
+ ! forced srcTermProcessing + srcTermProcessing = 0 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCSEQ, rc=rc) ++ +
+Under ESMF_TERMORDER_SRCSEQ it does not matter on which PET a + source term is located, the order of source terms is strictly defined by the + order of source sequence indices: + +
+d(1) = s(4) + s(5) + s(12) = 0.5 + 0.1 + 0.1 = sumA + +
+
+ if (localPet == 0) then + print *, "result SRCSEQ#2 = ", farrayPtr(1), " expect: ", sumA + if (farrayPtr(1) /= sumA) & + finalrc = ESMF_FAILURE + endif ++ +
+The same sparse matrix leads to bfb differences in the result when executed + with the ESMF_TERMORDER_SRCPET option. This is demonstrated further + down in result SRCPET#4. + +
+ESMF_TERMORDER_SRCPET + +
+All source terms coming from the same PET + +
+In the following examples the srcTermProcessing argument at store-time + is first set to 0, forcing all of the source terms to be sent to the + destination PET unmodified. We start by going back to the initial sparse + matrix where all of the source terms are located on the same PET. +
+
+ factorIndexList(1,1) = 1 ! src seq index + factorIndexList(2,1) = 1 ! dst seq index + factorList(1) = 1. + factorIndexList(1,2) = 6 ! src seq index + factorIndexList(2,2) = 1 ! dst seq index + factorList(2) = 1. + factorIndexList(1,3) = 9 ! src seq index + factorIndexList(2,3) = 1 ! dst seq index + factorList(3) = 1. ++ +
+
+ ! forced srcTermProcessing + srcTermProcessing=0 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+Then, at execution time, the ESMF_TERMORDER_SRCPET option is used. +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCPET, rc=rc) ++ +
+Here all of the source elements originate from the same PET (PET 0). This + fact, together with the ESMF_TERMORDER_SRCPET execution-time option, + results in the following canonical term order: + +
+d(1) = s(1) + s(6) + s(9) = 0.5 + 0.1 + 0.1 = sumA + +
+This is exactly the same term order that was used above to produce the + result stored in sumA. +
+
+ if (localPet == 0) then + print *, "result SRCPET#1 = ", farrayPtr(1), " expect: ", sumA + if (farrayPtr(1) /= sumA) & + finalrc = ESMF_FAILURE + endif ++ +
+The sequence indices of the source terms are the only relevant aspect in + determining the source term order. Consider, for example, the following + sparse matrix, where again all source terms are located on the same PET + (PET 2): +
+
+ factorIndexList(1,1) = 11 ! src seq index + factorIndexList(2,1) = 1 ! dst seq index + factorList(1) = 1. + factorIndexList(1,2) = 5 ! src seq index + factorIndexList(2,2) = 1 ! dst seq index + factorList(2) = 1. + factorIndexList(1,3) = 7 ! src seq index + factorIndexList(2,3) = 1 ! dst seq index + factorList(3) = 1. ++ +
+This time the source term order in memory is not the same + as their sequence index order. Specifically, the sequence indices of the + source terms, in the order they are stored in memory, is 11, 7, 5 (see the + source Array diagram above for reference). + Further, as mentioned already, the order of entries in the sparse matrix + also have not bearing on the term order in the SMM sums. + Then, for the ESMF_TERMORDER_SRCPET option, and because all source + terms are located on the same PET, the resulting source term order is the + canonical one determined by the source term sequence indices alone: + +
+d(1) = s(5) + s(7) + s(11) + +
+Filling in the source element data, we find + +
+d(1) = 0.1 + 0.1 + 0.5, + +
+which is expected to be bfb equivalent to the result stored in sumB + from above. +
+
+ ! forced srcTermProcessing + srcTermProcessing=0 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCPET, rc=rc) ++ +
+
+ if (localPet == 0) then + print *, "result SRCPET#2 = ", farrayPtr(1), " expect: ", sumB + if (farrayPtr(1) /= sumB) & + finalrc = ESMF_FAILURE + endif ++ +
+Source terms coming from different PETs + +
+When the source terms are distributed across multiple PETs, the + ESMF_TERMORDER_SRCPET option first bundles the terms according to + the PET on which they are stored. These source term "bundles" are then + arranged in an order that depends on the source PET position relative to the + destination PET: starting with the bundle for which the source PET is the + same as the destination PET, the source term bundles are placed in descending + order with respect to their source PET, modulo petCount. The terms within + each source term bundle are further sorted in the canonical order according + to their sequence index. + +
+The following sparse matrix demonstrates the effect of the + ESMF_TERMORDER_SRCPET option. +
+
+ factorIndexList(1,1) = 1 ! src seq index + factorIndexList(2,1) = 1 ! dst seq index + factorList(1) = 1. + factorIndexList(1,2) = 3 ! src seq index + factorIndexList(2,2) = 1 ! dst seq index + factorList(2) = 1. + factorIndexList(1,3) = 7 ! src seq index + factorIndexList(2,3) = 1 ! dst seq index + factorList(3) = 1. ++ +
+Here the source terms are located on PETs 0, 1, and 2. Using a [] notion to + indicate the source PET of each term, the term order under + ESMF_TERMORDER_SRCPET is given by: + +
+d(1) = s(1)[0] + s(7)[2] + s(3)[1] = 0.5 + 0.1 + 0.1 + +
+This is again the same order of terms that was used to produce the result + stored in sumA above. +
+
+ ! forced srcTermProcessing + srcTermProcessing=0 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCPET, rc=rc) ++ +
+
+ if (localPet == 0) then + print *, "result SRCPET#3 = ", farrayPtr(1), " expect: ", sumA + if (farrayPtr(1) /= sumA) & + finalrc = ESMF_FAILURE + endif ++ +
+In the above example, the fact that the terms were ordered by source PET + first, did not lead to numerical bfb differences compared to the canonical + source term order. However, this was purely coincidental in the way the + numbers worked out for this example. The following case looks at a situation + where the source PET order does lead to a result that shows bfb + differences compared to the canonical term order. +
+
+ factorIndexList(1,1) = 4 ! src seq index + factorIndexList(2,1) = 1 ! dst seq index + factorList(1) = 1. + factorIndexList(1,2) = 5 ! src seq index + factorIndexList(2,2) = 1 ! dst seq index + factorList(2) = 1. + factorIndexList(1,3) = 12 ! src seq index + factorIndexList(2,3) = 1 ! dst seq index + factorList(3) = 1. ++ +
+The canonical source term order of this SMM sum, determined by the source + sequence indices alone, is: + +
+d(1) = s(4) + s(5) + s(12) = 0.5 + 0.1 + 0.1, + +
+which again would lead to a result that is bfb identical to sumA. + However, this is not the term order resulting from the + ESMF_TERMORDER_SRCPET option. The actual order for this option is: + +
+d(1) = s(12)[3] + s(5)[2] + s(4)[1] = 0.1 + 0.1 + 0.5, + +
+resulting in a sum that is bfb identical to sumB instead. +
+
+ ! forced srcTermProcessing + srcTermProcessing=0 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCPET, rc=rc) ++ +
+
+ if (localPet == 0) then + print *, "result SRCPET#4 = ", farrayPtr(1), " expect: ", sumB + if (farrayPtr(1) /= sumB) & + finalrc = ESMF_FAILURE + endif ++ +
+Grouping of source terms coming from the same PET + +
+So far the srcTermProcessing argument was kept at 0, and therefore + source term grouping had not to be considered. Source term grouping is only + possible for terms that originate from the same PET. In preparation + for a closer look at the bfb effects of source term grouping, consider a + sparse matrix where two of the source terms are located on the same PET. +
+
+ factorIndexList(1,1) = 1 ! src seq index + factorIndexList(2,1) = 1 ! dst seq index + factorList(1) = 1. + factorIndexList(1,2) = 5 ! src seq index + factorIndexList(2,2) = 1 ! dst seq index + factorList(2) = 1. + factorIndexList(1,3) = 7 ! src seq index + factorIndexList(2,3) = 1 ! dst seq index + factorList(3) = 1. ++ +
+Here one of the source terms is located on PET 0 while the other two + source terms are originating on PET 2. Keeping the srcTermProcessing + argument at 0 first, the term order under ESMF_TERMORDER_SRCPET is + given by: + +
+d(1) = s(1)[0] + s(5)[2] + s(7)[2] = 0.5 + 0.1 + 0.1 + +
+And again the result is expected to be bfb identical to the number stored + in sumA. +
+
+ ! forced srcTermProcessing + srcTermProcessing=0 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCPET, rc=rc) ++ +
+
+ if (localPet == 0) then + print *, "result SRCPET#5 = ", farrayPtr(1), " expect: ", sumA + if (farrayPtr(1) /= sumA) & + finalrc = ESMF_FAILURE + endif ++ +
+The same result is also expected with srcTermProcessing set to 1. A + value of 1 indicates that the multiplication of the source term with its + sparse matrix factor is carried out on the source side before being sent to + the destination PET. The final sum is still carried out in the same order on + the destination PET, essentially resulting in the exact same bfb identical + sum as for srcTermProcessing set to 0. +
+
+ ! forced srcTermProcessing + srcTermProcessing=1 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCPET, rc=rc) ++ +
+
+ if (localPet == 0) then + print *, "result SRCPET#6 = ", farrayPtr(1), " expect: ", sumA + if (farrayPtr(1) /= sumA) & + finalrc = ESMF_FAILURE + endif ++ +
+Increasing the srcTermProcessing argument to 2 (or higher) results in + source term grouping of the terms (up to the number specified in + srcTermProcessing) that are on the same source PET. + +
+d(1) = s(1)[0] + ( s(5)[2] + s(7)[2] ) = 0.5 + (0.1 + 0.1) + +
+This result is bfb identical to first adding 0.1 and 0.1 into a partial sum, + and then adding this sum to 0.5. This is the exact grouping of + terms that was used to obtain the result stored in sumB from above. +
+
+ ! forced srcTermProcessing + srcTermProcessing=2 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCPET, rc=rc) ++ +
+
+ if (localPet == 0) then + print *, "result SRCPET#7 = ", farrayPtr(1), " expect: ", sumB + if (farrayPtr(1) /= sumB) & + finalrc = ESMF_FAILURE + endif ++ +
+In order to explore the effects of the srcTermProcessing argument + further, more terms on the same source PET are needed in the SMM sum. + The following sparse matrix has four entries, three of which originate from + the same PET (PET 3). +
+
+ factorIndexList(1,1) = 1 ! src seq index + factorIndexList(2,1) = 1 ! dst seq index + factorList(1) = 1. + factorIndexList(1,2) = 2 ! src seq index + factorIndexList(2,2) = 1 ! dst seq index + factorList(2) = 1. + factorIndexList(1,3) = 8 ! src seq index + factorIndexList(2,3) = 1 ! dst seq index + factorList(3) = 1. + factorIndexList(1,4) = 12 ! src seq index + factorIndexList(2,4) = 1 ! dst seq index + factorList(4) = 1. ++ +
+Setting the srcTermProcessing argument back to 0 puts the terms in + PET order, and canonical order for each PET bundle. + +
+d(1) = s(1)[0] + s(2)[3] + s(8)[3] + s(12)[3] = 0.5 + 0.2 + 0.1 + 0.1 + +
+The bfb identical result for this sum was calculated and stored in variable + sumC above. +
+
+ ! forced srcTermProcessing + srcTermProcessing=0 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCPET, rc=rc) ++ +
+
+ if (localPet == 0) then + print *, "result SRCPET#8 = ", farrayPtr(1), " expect: ", sumC + if (farrayPtr(1) /= sumC) & + finalrc = ESMF_FAILURE + endif ++ +
+Setting the srcTermProcessing argument to a value of 2 results in the + following source term grouping: + +
+d(1) = s(1)[0] + ( s(2)[3] + s(8)[3] ) + s(12)[3] + = 0.5 + ( 0.2 + 0.1 ) + 0.1, + +
+where the (0.2 + 0.1) partial sum is carried out on source PET 3, and + then sent to the destination PET (PET 0), together with the unmodified data + from source element 8 (0.1). The final sum is performed on PET 0. The + result is identical to the precomputed value stored in sumD. The + numbers work out in a way where this result is bfb identical to the + previous result, i.e. sumC. However, this bfb match is purely + coincidental. +
+
+ ! forced srcTermProcessing + srcTermProcessing=2 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCPET, rc=rc) ++ +
+
+ if (localPet == 0) then + print *, "result SRCPET#9 = ", farrayPtr(1), " expect: ", sumD + if (farrayPtr(1) /= sumD) & + finalrc = ESMF_FAILURE + endif ++ +
+Increasing the srcTermProcessing argument up to 3 results in a three + term partial sum on PET 3: + +
+d(1) = s(1)[0] + ( s(2)[3] + s(8)[3] + s(12)[3] ) + = 0.5 + ( 0.2 + 0.1 + 0.1 ). + +
+Again the final sum is performed on PET 0. The result is bfb identical to + the number stored in sumE, which, for the chosen numbers, works out to + have a bfb difference compared to sumC and sumD. +
+
+ ! forced srcTermProcessing + srcTermProcessing=3 + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCPET, rc=rc) ++ +
+
+ if (localPet == 0) then + print *, "result SRCPET#10 = ", farrayPtr(1), " expect: ", sumE + if (farrayPtr(1) /= sumE) & + finalrc = ESMF_FAILURE + endif ++ +
+Reproducibility and Performance + +
+The above examples show how bit-for-bit (bfb) reproducibility is a result of + controlling the term order. ESMF offers several options to control the term + order in the sparse matrix multiplication (SMM) implementation: + +
+The term order in a SMM operation does not only affect the bfb + reproducibility of the result, but also affects the SMM performance. + The precise performance implications of a specific term order are + complicated and strongly depend on the exact problem structure, as well as + on the details of the compute hardware. ESMF implements an auto-tuning + mechanism that can be used to conveniently determine a close to optimal set + of SMM performance parameters. + +
+There are two SMM performance parameters in ESMF that are encoded into a + RouteHandle during store-time: srcTermProcessing and + pipelineDepth. The first one affects the term order in the SMM sums and + has been discussed in detail above. The second parameter, pipelineDepth, + determines how many in- and out-bound messages may be outstanding on each + PET. It has no effect on the term order and does not lead to bfb differences + in the SMM results. However, in order to achieve good performance + reproducibility, the user has the option to pass in a fixed value of the + pipelineDepth argument when precomputing RouteHandles. + +
+Store calls that take the srcTermProcessing and/or pipelineDepth + argument specify them as optional with intent(inout). Omitting the + argument when calling, or passing a variable that is set to a negative + number, indicates that the respective parameter needs to be determined by + the library. Further, if a variable with a negative value was passed in, then + the variable is overwritten and replaced by the auto-tuned value on return. Through + this mechanism a user can leverage the built-in auto-tuning feature of ESMF to + obtain the best possible performance for a specific problem on a particular + compute hardware, while still ensuring bfb and performance + reproducibility between runs. The following example shows code that first + checks if previously stored SMM performance parameters are available in a + file on disk, and then either reads and uses them, or else uses auto-tuning + to determine the parameters before writing them to file. For simplicity the + same sparse matrix as in the previous example is used. + +
+
+ ! precondition the arguments for auto-tuning and overwriting + srcTermProcessing = -1 ! init negative value + pipelineDepth = -1 ! init negative value + + ! get a free Fortran i/o unit + call ESMF_UtilIOUnitGet(unit=iounit, rc=rc) ++ +
+
+ ! try to open the file that holds the SMM parameters + open(unit=iounit, file="smmParameters.dat", status="old", action="read", & + form="unformatted", iostat=iostat) + + if (iostat == 0) then + ! the file was present -> read from it and close it again + read(unit=iounit, iostat=iostat) srcTermProcessing, pipelineDepth, & + sumCompare + close(unit=iounit) + endif + + if ((localPet == 0) .and. (iostat == 0)) then + print *, "SMM parameters successfully read from file" + print *, " srcTermProcessing=", srcTermProcessing, " pipelineDepth=", & + pipelineDepth, " ==>> sumCompare=", sumCompare + endif + + call ESMF_ArraySMMStore(srcArray, dstArray, & + factorIndexList=factorIndexList, factorList=factorList, & + routehandle=rh, srcTermProcessing=srcTermProcessing, & + pipelineDepth=pipelineDepth, rc=rc) ++ +
+
+ call ESMF_ArraySMM(srcArray, dstArray, routehandle=rh, & + termorderflag=ESMF_TERMORDER_SRCPET, rc=rc) ++ +
+
+ if ((localPet == 0) .and. (iostat /= 0)) then + print *, "SMM parameters determined via auto-tuning -> dump to file" + open(unit=iounit, file="smmParameters.dat", status="unknown", & + action="write", form="unformatted") + write(unit=iounit) srcTermProcessing, pipelineDepth, farrayPtr(1) + close(unit=iounit) + endif + + if (localPet == 0) then + if (iostat /= 0) then + ! cannot do bfb comparison of the result without reference + print *, "result SRCPET#11 = ", farrayPtr(1) + else + ! do bfb comparison of the result against reference + print *, "result SRCPET#11 = ", farrayPtr(1), " expect: ", sumCompare + if (farrayPtr(1) /= sumCompare) then + finalrc = ESMF_FAILURE + write (msg, *) "Numerical difference detected: ", & + farrayPtr(1)-sumCompare + call ESMF_LogWrite(msg, ESMF_LOGMSG_INFO) + endif + endif + endif ++ +
+Running this example for the first time exercises the auto-tuning branch. The + auto-tuned srcTermProcessing and pipelineDepth parameters are + then used in the SMM execution, as well as written to file. The SMM result + variable is also written to the same file for test purposes. + Any subsequent execution of the same example branches into the code that + reads the previously determined SMM execution parameters from file, re-using + them during store-time. This ensures bfb reproducibility of the SMM result, + which is tested in this example by comparing to the previously stored value. + + +
+ +
+ +
+ +
+The RouteHandle based communication calls of the Array and Field classes + provide the routesyncflag argument. This argument allows the user to + specify that the initiated call should not block. Additional calls are + necessary to wait for a previously initiated communication call to finish. + For a detailed discussion see section 28.2.20. + Building on these primitives, asynchronous communications patterns can be + implemented in user code. However, a more elegant option to achive + asynchronous behavior between sending and receiving PETs of RouteHandle based + communications is provided by the VMEpoch feature discussed here. + +
+The VMEpoch is a low level message aggregation and buffering approach. + The VM level details are discussed under the ESMF_VM section in + 51.3.11. + +
+There are several advantages of VMEpoch over the direct use of non-blocking + RouteHandle based communication calls: + +
+ +
+
+
+
+The ESMF_VMEpoch API consists of two interfaces: + ESMF_VMEpochEnter() and ESMF_VMEpochExit(). Inside an epoch, + communication calls are aggregated. Data transfers on the + src side are not issued until the epoch is exited. On the dst + side, a single data transfer is received from any of the sending PETs, and + then divided over the individual receive calls. + +
+In the following code example, the srcArray has DEs on PET 0 and 1, + while dstArray has DEs on PET 2 and 3. Both Arrays are operating on + the same global index space. A Redist() RouteHandle rh is created in + the usual manner. +
+
+ call ESMF_ArrayRedistStore(srcArray, dstArray, routehandle=rh, rc=rc) ++ +
+The precomputed rh can be used as usual. Here the use inside an active + VMEpoch is demonstrated. + +
+First enter the VMEpoch using ESMF_VMEpochEnter(), specifying the kind + of epoch. Currently only a single VMEpoch kind is available: + ESMF_VMEPOCH_BUFFER. +
+
+ call ESMF_VMEpochEnter(epoch=ESMF_VMEPOCH_BUFFER, rc=rc) ++ +
+SRC side (PET 0 & 1): + The sending PETs do not block. + +
+DST side (PET 2 & 3): + The receiving PETs do not block. + +
+Notice that ESMF implements a throttle on the VMEpoch as to limit the number + of queued message between PETs. This is necessary to protect the receiving + side in the EAGER regime where MPI implementations send the + data from the sending to the receiving side, assuming the receiving side + will always be able to buffer. In cases where the sending side runs far + ahead of the receiving side, this strategy can lead to + increasing memory pressure on the receiving side, ultimatily resulting in + out-of-memory conditions. The default throttle in VMEpoch is set to + outstanding message between any two PETs. It can be adjusted by specifying + the throttle argument when calling ESMF_VMEpochEnter(). + +
+Next the actual communication method, ESMF_ArrayRedist(), is called in + the usual manner. +
+
+ call ESMF_ArrayRedist(srcArray, dstArray, routehandle=rh, rc=rc) ++ +
+SRC side (PET 0 & 1): + The sending PETs block until the locally needed send buffers are available, + and all local data manipulations and data movements into the send buffers have + completed. + +
+Waiting for the send buffers comes into play when a VMEpoch is entered and + exited multiple times. The same send buffer is reused each time for the + same src-dst-PET pairs (and grown automatically if needed). Each send buffer + becomes available once the MPI layer has indicated that the associated, + previous MPI_Isend() has completed locally. + +
+Once the send buffer for a specific PET pair is available, the local data + movements defined by the rh and message aggregation must complete before + returning. For Regrid() and SMM() operations the + srcTermProcessing argument specified during Store() determines the + amount of local data processing. Once returned, it is safe to modify the + srcArray data on the local PET. + +
+DST side (PET 2 & 3): + The receiving PETs block on the aggregated data from the src side for which + the local PET has a dependency defined via the rh. Once received, the + data is processed locally, and moved into the final location under the + dstArray. On return, it is safe to access the data in dstArray + on the local PET. + +
+Notice that any number of RouteHandle based communication calls can be made + inside the same active VMEpoch. In fact, aggregating messages from multiple + exchanges is the typical use case of the VMEpoch approach. Additional + communication calls cam either involve different RouteHandles, or even the + same rh for different src/dst Array pairs. + +
+When using communication calls that allow the specification of the + termorderflag, e.g. ESMF_FieldRegrid(), ESMF_ArraySMM(), + etc. inside a VMEpoch, it is important to set it to either + ESMF_TERMORDER_SRCPET or ESMF_TERMORDER_SRCSEQ. The default + value of ESMF_TERMORDER_FREE is not compatible with VMEpoch. + +
+Finally the active VMEpoch is exited by calling ESMF_VMEpochExit(). +
+
+ call ESMF_VMEpochExit(rc=rc) ++ +
+SRC side (PET 0 & 1): + The sending PETs post their local MPI_Isend() calls. This is + non-blocking. + +
+DST side (PET 2 & 3): + The receiving PETs do not block. + +
+As part of the final clean-up the rh is being released as usual. +
+
+ call ESMF_ArrayRedistRelease(routehandle=rh, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+Typically a RouteHandle object is created indirectly, i.e. without explicitly + calling the ESMF_RouteHandleCreate() method. The RouteHandle + object is a byproduct of calling communication Store() methods like + ESMF_FieldRegridStore(). + +
+One exception to this rule is when creating a duplicate RouteHandle from an + existing RouteHandle object. In this case the ESMF_RouteHandleCreate() + method is used explicitly. While this method allows to create a duplicate + RouteHandle on the exact same set of PETs as the original RouteHandle, the + real purpose of duplication is the transfer of a precomputed RouteHandle to a + different set of PETs. This is an efficient way to reduce the total time + spent in Store() calls, for situations where the same communication pattern + repeats for multiple components. + +
+This example demonstrates the transfer of a RouteHandle from one set of PETs + to another by first introducing three components. Component A is defined + on the first half of available PETs. +
+
+ petCountA = petCount/2 ! component A gets half the PETs + + allocate(petListA(petCountA)) + do i=1, petCountA + petListA(i) = i-1 ! PETs are base 0 + enddo + + compA = ESMF_GridCompCreate(petList=petListA, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+The other two components, B1 and B2, split the remaining PETs evenly. +
+
+ petCountR = petCount - petCountA + petCountB1 = petCountR / 2 + + allocate(petListB1(petCountB1)) + do i=1, petCountB1 + petListB1(i) = petCountA + i-1 ! PETs are base 0 + enddo + + allocate(petListB2(petCountR-petCountB1)) + do i=1, petCountR-petCountB1 + petListB2(i) = petCountA + petCountB1 + i-1 ! PETs are base 0 + enddo + + compB1 = ESMF_GridCompCreate(petList=petListB1, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) + + compB2 = ESMF_GridCompCreate(petList=petListB2, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+Skipping all of the standard superstructure code, assume that fieldA + has been created by component A, has been reconciled across all PETs via + a StateReconcile() call, and accessed via a StateGet(). The same is true for + fieldB1 and fieldB2 from components B1 and B2, respectively. + +
+Now the RouteHandle rh1 for a Redist operation is precomputed between + fieldA and fieldB1. +
+
+ call ESMF_FieldRedistStore(srcField=fieldA, dstField=fieldB1, & + routehandle=rh1, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+The communication pattern stored in rh1 is between the PETs associated + with component A and those associated with component B1. Now component B2 is + simply a second instance of the same component code as B1, but on a different + set of PETs. The ESMF_RouteHandleCreate() method can be used to + transfer rh1 to the set of PETs that is consistent with fieldA to + fieldB2 communication. + +
+In order to transfer a RouteHandle to a different set of PETs, the + originPetList and targetPetList must be constructed. The + originPetList is the union of source and destination PETs (in that + order) for which rh1 was explicitly computed via the Store() call: +
+
+ allocate(originPetList(size(petListA)+size(petListB1))) + originPetList(1:size(petListA)) = petListA(:) + originPetList(size(petListA)+1:) = petListB1(:) ++ +
+The targetPetList is the union of source and destination PETs (in that + order) for which the target RouteHandle (i.e. rh2) will be defined: +
+
+ allocate(targetPetList(size(petListA)+size(petListB2))) + targetPetList(1:size(petListA)) = petListA(:) + targetPetList(size(petListA)+1:) = petListB2(:) ++ +
+Now the new RouteHandle rh2 can be created easily from the exising + RouteHandle rh1, suppling the origin and target petLists. +
+
+ rh2 = ESMF_RouteHandleCreate(rh1, originPetList=originPetList, & + targetPetList=targetPetList, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+The new RouteHandle rh2 is completely independent of the original + RouteHandle. In fact, it is perfectly fine to destroy (or release) rh1 + while holding on to rh2. +
+
+ call ESMF_RouteHandleDestroy(rh1, noGarbage=.true., rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+Finally the rh2 object can be used to redistribute data from + fieldA to fieldB2. +
+
+ call ESMF_FieldRedist(srcField=fieldA, dstField=fieldB2, & + routehandle=rh2, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+The communication pattern held by rh2 + is idential to what whould have been created by an explicit + ESMF_FieldRedistStore() call. However, the + ESMF_RouteHandleCreate() call used to create rh2 from rh1 + is much faster than the full RedistStore() operation. + + +
+ +
+ +
+ +
+Communication Store() methods, like ESMF_FieldRegridStore(), are used + to create RouteHandles. These methods can be expensive, both with respect to + temporary memory requirements as well as the time they require to execute. + Often the associated cost is acceptable because Store() calls are typically + used during the initialization phase of the application. The cost of + RouteHandle generation is therefore armorized over the entire run phase + of the application, where the RouteHandle is applied over and over to + transfer data according to the same communication pattern. + +
+However, especially for short production runs, an expensive initialization + time can become problematic. In such cases it is useful to write the + RouteHandle to file. Subsequent application runs can then re-create the + RouteHandle during initialization, simply from file at a fraction of the time + of the original Store() call. + +
+First a RouteHandle must be created using one of the ESMF Store() methods. +
+
+ call ESMF_FieldRedistStore(srcField=fieldA, dstField=fieldB, & + routehandle=rh1, rc=rc) ++ +
+Now the RouteHandle object rh1 can be written to file using the + collective ESMF_RouteHandleWrite() method. +
+
+ call ESMF_RouteHandleWrite(rh1, fileName="testWrite.RH", rc=rc) ++ +
+This creates a single binary file with name testWrite.RH. The + information from across all PETs that define rh1 is contained in this + file. + +
+At this point, the original RouteHandle is no longer needed and can be + destroyed. +
+
+ call ESMF_RouteHandleDestroy(rh1, noGarbage=.true., rc=rc) ++ +
+The RouteHandle just deleted can easily be re-created using the + ESMF_RouteHandleCreate() method that accepts the file name as an + argument. This is a collective method that must be called on exactly + the same number of PETs that was used for the original Store() and Write() + calls that generated the file. +
+
+ rh2 = ESMF_RouteHandleCreate(fileName="testWrite.RH", rc=rc) ++ +
+Finally the re-created RouteHandle, rh2, can be used to execute the + communication pattern originally computed in rh1. +
+
+ call ESMF_FieldRedist(srcField=fieldA, dstField=fieldB, & + routehandle=rh2, rc=rc) ++ +
+Once done with rh2, the RouteHandle can be destroyed as usual. +
+
+ call ESMF_RouteHandleDestroy(rh2, noGarbage=.true., rc=rc) ++ +
+ + +
+ +
+ +
+ +
+A RouteHandle object is typically created during a communication Store() + call, e.g. an ESMF_FieldRegridStore(). Other communication methods + with Store() are Halo, Redist, and SMM. The primary + input objects of a Store() call are either Fields, Arrays, + FieldBundles, or ArrayBundles. There will be an object for the source side, + and another object for the destination side. Both objects must be of the + same type. +
+
+ srcField = ESMF_FieldCreate(srcGrid, ESMF_TYPEKIND_R8, rc=rc) ++ +
+
+ dstField = ESMF_FieldCreate(dstGrid, ESMF_TYPEKIND_R8, rc=rc) ++ +
+
+ call ESMF_FieldRegridStore(srcField=srcField, dstField=dstField, & + routehandle=routehandle, rc=rc) ++ +
+The purpose of the explicit Store() call is to separate out the + expensive part of creating the RouteHandle object for a specific + communication patter, from the less expensive part of applying it. + Applying the RouteHandle results in data movement between + the source and destination objects. Once a RouteHandle is available, it is + reusable. This means it can be applied over and over again to communicate + data from the source to the destination object. +
+
+ do i=1, 10 + ! repeatedly applying the routehandle + call ESMF_FieldRegrid(srcField=srcField, dstField=dstField, & + routehandle=routehandle, rc=rc) + enddo ++ +
+Reusability of a RouteHandle object extends beyond re-applying it to the same + source/destination object pair that was used during Store(). The same + RouteHandle can be applied to a different object pair, as long as these + criterial are met: + +
+First consider the case where a second pair of source and destination Fields + is created identical to the first set. The precomputed RouteHandle is + immediatly reusable for this new Field pair to carry out the regrid operation. +
+
+ srcField2 = ESMF_FieldCreate(srcGrid, ESMF_TYPEKIND_R8, rc=rc) ++ +
+
+ dstField2 = ESMF_FieldCreate(dstGrid, ESMF_TYPEKIND_R8, rc=rc) ++ +
+
+ ! applying the same routehandle to a different pair of fields + call ESMF_FieldRegrid(srcField=srcField2, dstField=dstField2, & + routehandle=routehandle, rc=rc) ++ +
+The same RouteHandle stays re-usable even for a Field pair where source and + destination have one or more additional undistributed dimensions. Here a + single undistributed dimension is added. By default all undistributed + dimensions will be ordered after the distributed dimensions provided + by the Grid object. +
+
+ srcField3 = ESMF_FieldCreate(srcGrid, ESMF_TYPEKIND_R8, & + ungriddedLBound=(/1/), ungriddedUBound=(/10/), & ! undistributed dim last + rc=rc) ++ +
+
+ dstField3 = ESMF_FieldCreate(dstGrid, ESMF_TYPEKIND_R8, & + ungriddedLBound=(/1/), ungriddedUBound=(/10/), & ! undistributed dim last + rc=rc) ++ +
+
+ ! applying the same routehandle to a different pair of fields + call ESMF_FieldRegrid(srcField=srcField3, dstField=dstField3, & + routehandle=routehandle, rc=rc) ++ +
+The undistributed dimension can also be moved into the first position, + and the same RouteHandle can still be re-used. Specifying the order + of dimensions in a Field is accomplished by providing the + gridToFieldMap. Here the Grid dimensions are mapped to 2nd and 3rd + Field dimensions, moving the undistributed dimension into the leading + position. +
+
+ srcField4 = ESMF_FieldCreate(srcGrid, ESMF_TYPEKIND_R8, & + ungriddedLBound=(/1/), ungriddedUBound=(/10/), & + gridToFieldMap=(/2,3/), rc=rc) ! undistributed dim 1st ++ +
+
+ dstField4 = ESMF_FieldCreate(dstGrid, ESMF_TYPEKIND_R8, & + ungriddedLBound=(/1/), ungriddedUBound=(/10/), & + gridToFieldMap=(/2,3/), rc=rc) ! undistributed dim 1st ++ +
+
+ ! applying the same routehandle to a different pair of fields + call ESMF_FieldRegrid(srcField=srcField4, dstField=dstField4, & + routehandle=routehandle, rc=rc) ++ +
+It is not necessary that the undistributed dimension is in the same position + on the source and destination Field. The only criteria that needs to be + satisfied is that both source and destination have the same number of + undistributed elements. Here the RouteHandle is re-used for a + Field pair where the destination Field interleaves the undistributed dimension + between the two distributed dimensions. At the same time the source Field + keeps the undistributed dimension in leading position. +
+
+ srcField5 = ESMF_FieldCreate(srcGrid, ESMF_TYPEKIND_R8, & + ungriddedLBound=(/1/), ungriddedUBound=(/10/), & + gridToFieldMap=(/2,3/), rc=rc) ! undistributed dim 1st ++ +
+
+ dstField5 = ESMF_FieldCreate(dstGrid, ESMF_TYPEKIND_R8, & + ungriddedLBound=(/1/), ungriddedUBound=(/10/), & + gridToFieldMap=(/1,3/), rc=rc) ! undistributed dim 2nd ++ +
+
+ ! applying the same routehandle to a different pair of fields + call ESMF_FieldRegrid(srcField=srcField5, dstField=dstField5, & + routehandle=routehandle, rc=rc) ++ +
+In the following example the undistributed elements on the source side are + spread across two undistributed dimensions. Of course the product of the two + dimension sizes must equal the number of undistributed elements on the + destination side, in order to fulfil the element count criteria. Here this + number is 10. At two undistributed dimension on the source side are placed + in first and fourth position using the gridToFieldMap. The same + RouteHandle is applied to this Field pair, resulting in the desired + regrid operation. +
+
+ srcField6 = ESMF_FieldCreate(srcGrid, ESMF_TYPEKIND_R8, & + ungriddedLBound=(/1,1/), ungriddedUBound=(/2,5/), & + gridToFieldMap=(/2,3/), rc=rc) ! undistributed dims 1st and 4th ++ +
+
+ dstField6 = ESMF_FieldCreate(dstGrid, ESMF_TYPEKIND_R8, & + ungriddedLBound=(/1/), ungriddedUBound=(/10/), & + gridToFieldMap=(/1,3/), rc=rc) ! undistributed dim 2nd ++ +
+
+ ! applying the same routehandle to a different pair of fields + call ESMF_FieldRegrid(srcField=srcField6, dstField=dstField6, & + routehandle=routehandle, rc=rc) ++ +
+While the RouteHandle was precomputed using a specific source/destination + Field pair, we have seen how it can be re-used as long as the memory layout + associated with the distributed (i.e. gridded) dimensions does not change. + A natural extension of this feature is to allow the same RouteHandle to be + re-used when source and destination are FieldBundles instead of Fields. The + only requirement here is that both sides contain the same number of elements, + and that + each pair constructed from the source and destination side is compatible with + the original pair used as shown in the examples above. Here this criteria is + simply met by constructing the source and destination FieldBundles from the + exact Fields used in the previous examples. +
+
+ srcFieldBundle = ESMF_FieldBundleCreate(fieldList=(/srcField, & + srcField2, srcField3, srcField4, srcField5, srcField6/), rc=rc) ++ +
+
+ dstFieldBundle = ESMF_FieldBundleCreate(fieldList=(/dstField, & + dstField2, dstField3, dstField4, dstField5, dstField6/), rc=rc) ++ +
+
+ ! applying the same routehandle to a pair of FieldBundles + call ESMF_FieldBundleRegrid(srcFieldBundle, dstFieldBundle, & + routehandle=routehandle, rc=rc) ++ +
+On a fundamental level, RouteHandles are re-usable across objects that + have the same memory layout for their distributed dimensions. Since ESMF + Fields are built on top of ESMF Arrays, it is + possible to re-use the same RouteHandle that was precomputed for a Field + pair and apply it to a matching Array pair. + +
+For this example, the easiest way to create Arrays with the same memory + layout in the distributed dimensions is to query the source and destination + Grid objects for their DistGrids. Then source and destination Arrays can be + easily constructed. +
+
+ call ESMF_GridGet(srcGrid, distgrid=srcDistGrid, rc=rc) ++ +
+
+ call ESMF_GridGet(dstGrid, distgrid=dstDistGrid, rc=rc) ++ +
+
+ srcArray = ESMF_ArrayCreate(srcDistGrid, ESMF_TYPEKIND_R8, rc=rc) ++ +
+
+ dstArray = ESMF_ArrayCreate(dstDistGrid, ESMF_TYPEKIND_R8, rc=rc) ++ +
+
+ ! applying the same routehandle to an Array pair + call ESMF_ArraySMM(srcArray=srcArray, dstArray=dstArray, & + routehandle=routehandle, rc=rc) ++ +
+Finally the resources associated with the RouteHandle object are released. + The recommended way to do this is by calling into the Release() method + associated with the Store() method used to create the RouteHandle. +
+
+ call ESMF_FieldRegridRelease(routehandle, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+When a RouteHandle object is created during an ESMF_FieldRegridStore() + call, masking information can be provided by the user. This type of masking + is said to be static, and is described in section 24.2.10. + It is static, because the masks set the maximum limits of the regrid + operation, which cannot be changed later. All subsequent executions of the + same RouteHandle can only use elements - source or destination - + that were not masked during the Store() call. + +
+Once a RouteHandle object is available, whether it was created with or without + static masking, the associated regrid operation can further be masking + during RouteHandle execution . This is called dynamic masking, because + it can dynamically change between subsequent RouteHandle executions. The + RouteHandle itself remains unchange during this process. The dynamic + masking information is processed on the fly as the RouteHandle is applied. + +
+The following example demonstrates dynamic masking for a regrid operation + between two Field objects. Although it is supported, here + the regrid operation between srcField and dstField is computed + without static masking. + +
+Note that since the intention is to later use the generated RouteHandle for + dynamic masking, it is important to provide the srcTermProcessing + argument, which must be set equal to 0. Doing this ensures that all + of the multiplying with interpolation weights, and summing of terms, is + carried out on the destination side. This is critical for dynamic masking. +
+
+ srcTermProcessing=0 + + call ESMF_FieldRegridStore(srcField=srcField, dstField=dstField, & + srcTermProcessing=srcTermProcessing, routehandle=routehandle, rc=rc) ++ +
+Now that routehandle is available, it can be used to execute the + regrid operation over and over during the course of the simualtion run. +
+
+ call ESMF_FieldRegrid(srcField=srcField, dstField=dstField, & + routehandle=routehandle, rc=rc) ++ +
+Assume that during the course of the simulation the srcField becomes + partially masked. This masking may be dynamically changing, as would be the + case for the ice cover over the arctic ocean. Then the regrid operation + represented by routehandle should dynamically adjust to only use + unmasked source elements. + +
+The dynamic masking behavior can be achieved in ESMF by setting srcField + elements to a special value. +
+
+ call ESMF_FieldGet(srcField, farrayPtr=farrayPtr, rc=rc) ++ +
+
+ ! setting an arbitrary local source element to special value 'srcMaskValue' + farrayPtr(lbound(farrayPtr,1)+3,lbound(farrayPtr,2)+3) = srcMaskValue ++ +
+Then set up an ESMF_DynamicMask object that holds information about + the special mask value. The dynamic mask object + further holds a pointer to the routine that will be called in order to handle + dynamically masked elements. +
+
+ call ESMF_DynamicMaskSetR8R8R8(dynamicMask, & + dynamicSrcMaskValue=srcMaskValue, & + dynamicMaskRoutine=simpleDynMaskProc, & + rc=rc) ++ +
+The names of the specific DynamicMaskSet methods all carry a + typekind-triplet suffix. Here the suffix is R8R8R8. + This indicates that the dynamicMaskRoutine argument + provided is expected to deal with real(ESMF_KIND_R8) destination data + (first R8 typekind), real(ESMF_KIND_R8) factors (second R8 typekind), + and real(ESMF_KIND_R8) source data (third R8 typekind). + +
+Now when the routehandle is executed, and the dynamicMask object + is passed into the ESMF_FieldRegrid() call, +
+
+ call ESMF_FieldRegrid(srcField=srcField, dstField=dstField, & + routehandle=routehandle, dynamicMask=dynamicMask, rc=rc) ++ +
+ESMF will scan the srcField for elements that have data equal to + that set by dynamicSrcMaskValue. If any are found, they + are passed into the routine provided via the dynamicMaskRoutine + argument. + +
+The procedure passed through the dynamicMaskRoutine argument must + satisfy exactly the following predefined interface: + +
+
+ interface + subroutine ESMF_DynamicMaskRoutineR8R8R8(dynMaskList, & + dynamicSrcMaskValue, dynamicDstMaskValue, rc) + use ESMF_UtilTypesMod + implicit none + type(ESMF_DynamicMaskElementR8R8R8), pointer :: dynMaskList(:) + real(ESMF_KIND_R8), intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R8), intent(in), optional :: dynamicDstMaskValue + integer, intent(out) :: rc + end subroutine + end interface ++ +
+The first argument accepted according to this interface is an array of type + ESMF_DynamicMaskElement. Each element of this array corresponds to a + single element in the dstField that is affected by dynamic masking. + For each such dstElement the complete interpolation stencile is + provided by the ESMF_DynamicMaskElement derived type: + +
+
+ type ESMF_DynamicMaskElementR8R8R8 + real(ESMF_KIND_R8), pointer :: dstElement + real(ESMF_KIND_R8), allocatable :: factor(:) + real(ESMF_KIND_R8), allocatable :: srcElement(:) + end type ++ +
+Here the dstElement is a pointer to the actual element in the + dstField. Thus, assigning dstElement to a value, immediately + results in a value change of the element inside the dstField object. + Further, the size of the factor(:) and srcElement(:) arrays is + identical to each other and corresponds to the number of source elements in + the interpolation stencile. Without dynamic masking, the dstElement + would simply be calculated as the scalar product of factor(:) and + srcElement(:). + +
+By providing the dynamicMaskRoutine, the user has full control as to + what exactly happens to destination elements that are affected by dynamic + masking. For the current example, where some source elements may be marked by + a special masking value, a simple scheme could be to only use non-masked + source elements to calculate destination elements. The result then needs to + be renormalized in order to account for the missing source elements. This + could be implemented similar to the following subroutine: + +
+
+ subroutine simpleDynMaskProc(dynamicMaskList, dynamicSrcMaskValue, & + dynamicDstMaskValue, rc) + type(ESMF_DynamicMaskElementR8R8R8), pointer :: dynamicMaskList(:) + real(ESMF_KIND_R8), intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R8), intent(in), optional :: dynamicDstMaskValue + integer, intent(out) :: rc + integer :: i, j + real(ESMF_KIND_R8) :: renorm + if (associated(dynamicMaskList)) then + do i=1, size(dynamicMaskList) + dynamicMaskList(i)%dstElement = 0.d0 ! set to zero + renorm = 0.d0 ! reset + do j=1, size(dynamicMaskList(i)%factor) + if (.not. & + match(dynamicSrcMaskValue,dynamicMaskList(i)%srcElement(j))) then + dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement & + + dynamicMaskList(i)%factor(j) & + * dynamicMaskList(i)%srcElement(j) + renorm = renorm + dynamicMaskList(i)%factor(j) + endif + enddo + if (renorm > 0.d0) then + dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement / renorm + else if (present(dynamicSrcMaskValue)) then + dynamicMaskList(i)%dstElement = dynamicSrcMaskValue + else + rc = ESMF_RC_ARG_BAD ! error detected + return + endif + enddo + endif + ! return successfully + rc = ESMF_SUCCESS + end subroutine ++ +
+So far in the example only the srcField had been dynamically masked. + However, elements in the dstField can be masked as well, following + exactly the same manner. + +
+First ensure that the dstField is in a well defined condition. This can + be achived by reseting it, e.g. to zero, using the ESMF_FieldFill() + method. +
+
+ call ESMF_FieldFill(dstField, dataFillScheme="const", const1=0.d0, rc=rc) ++ +
+Now some of the destination elements are set to a defined masking value. +
+
+ call ESMF_FieldGet(dstField, farrayPtr=farrayPtr, rc=rc) ++ +
+
+ ! setting an arbitrary local destination element to special value 'dstMaskValue' + farrayPtr(lbound(farrayPtr,1)+1,lbound(farrayPtr,2)+1) = dstMaskValue ++ +
+The dynamicMask is reset using the same DynamicMaskSet method as + before, but in addition to the previous arguments, dynamicDstMaskValue + is also specified. +
+
+ call ESMF_DynamicMaskSetR8R8R8(dynamicMask, & + dynamicSrcMaskValue=srcMaskValue, & + dynamicDstMaskValue=dstMaskValue, & + dynamicMaskRoutine=simpleDynMaskProc, & + rc=rc) ++ +
+Passing the reset dynamicMask object into ESMF_FieldRegrid() + causes ESMF to not only look for source elements that match + dynamicSrcMaskValue, but also destination elements that + match dynamicDstMaskValue. +
+
+ call ESMF_FieldRegrid(srcField=srcField, dstField=dstField, & + routehandle=routehandle, zeroregion=ESMF_REGION_EMPTY, & + dynamicMask=dynamicMask, rc=rc) ++ +
+Again an adequate procedure is supplied through + dynamicMaskRoutine. For the current case, however, a suitable procedure + would be inspecting the dstElement as well as all the dstElements + provided via the dynMaskList argument. + +
+Notice the zeroregion = ESMF_REGION_EMPTY specification in the + ESMF_FieldRegrid() call. This setting ensures that values in the + dstField remain unchanged until they are checked for + dynamicDstMaskValue. + +
+The DynamicMaskSet methods provide an argument of logical type, + called handleAllElements. By default it is set to .false., + which means that only elements affected by dynamic masking - as described + above - are passed to the dynamicMaskRoutine. However, when + handleAllElements is set to .true., all local + elements on each PET are made available to the dynamicMaskRoutine. + This allows the user supplied procedure to implement fully customized + handling of the interpolation from source to destination, using the + information supplied by ESMF. + +
+To demonstrate this, a custom routine simpleHandleAllProc() is + passed in as dynamicMaskRoutine, and handleAllElements is + set to .true.. All other aspects of the user interface remain unchanged. +
+
+ call ESMF_DynamicMaskSetR8R8R8(dynamicMask, & + dynamicSrcMaskValue=srcMaskValue, & + dynamicDstMaskValue=-2.d0, & + dynamicMaskRoutine=simpleHandleAllProc, & + handleAllElements=.true., & + rc=rc) ++ +
+
+ call ESMF_FieldRegrid(srcField=srcField, dstField=dstField, & + routehandle=routehandle, zeroregion=ESMF_REGION_EMPTY, & + dynamicMask=dynamicMask, rc=rc) ++ +
+Dynamic masking is also available for source and destination fields that + contain leading undistributed dimensions. When ESMF applies the regridding + weights, it interprets the product space of leading undistributed dimensions + of a Field or Array as the elements of a vector. In this approach the + interpolation becomes a vector operation. When applying the concept + of dynamic masking to such a vector operation, without making further + assumptions, it must be assumed that different vector elements may be + affected differently by the dynamic mask. ESMF therefore unrolls the vector + dimension when constructing the information passed to the + dynamicMaskRoutine. As a consequence of this, masking routines + do not generally have to consider vectorization explicitly. + +
+The concept is demonstrated by creating source and destination fields + with one leading undistributed dimension. +
+
+ srcField = ESMF_FieldCreate(srcGrid, ESMF_TYPEKIND_R8, & + gridToFieldMap=(/2,3/), ungriddedLBound=(/1/), ungriddedUBound=(/20/), & + rc=rc) ++ +
+
+ dstField = ESMF_FieldCreate(dstGrid, ESMF_TYPEKIND_R8, & + gridToFieldMap=(/2,3/), ungriddedLBound=(/1/), ungriddedUBound=(/20/), & + rc=rc) ++ +
+A regrid operation is computed in the usual manner. In order to make the + resulting RouteHandle object suitable for dynamic masking, computations are + pushed completely onto the destination PETs, as in previous examples, by + setting the srcTermProcessing argument to zero. +
+
+ srcTermProcessing=0 + + call ESMF_FieldRegridStore(srcField=srcField, dstField=dstField, & + srcTermProcessing=srcTermProcessing, routehandle=routehandle, rc=rc) ++ +
+The same dynamicMaskRoutine as before can be used when setting up + the ESMF_DynamicMask object. However, the source and destination + Fields now contain 20 undistributed elements at each distributed location, + and the dynamic mask routine will handle all elements that are affected + by the dynamic mask conditions. +
+
+ call ESMF_DynamicMaskSetR8R8R8(dynamicMask, & + dynamicSrcMaskValue=srcMaskValue, & + dynamicDstMaskValue=dstMaskValue, & + dynamicMaskRoutine=simpleDynMaskProc, & + rc=rc) ++ +
+
+ call ESMF_FieldRegrid(srcField=srcField, dstField=dstField, & + routehandle=routehandle, zeroregion=ESMF_REGION_EMPTY, & + dynamicMask=dynamicMask, rc=rc) ++ +
+Setting the handleAllElements to .true. will pass all elements + to the dynamicMaskRoutine. There are 20 times as many elements + on the source and destination side, and therefore the dynamic masking routine + will handle exactly 20 times as many elements compared to the case without + undistributed dimension. +
+
+ call ESMF_DynamicMaskSetR8R8R8(dynamicMask, & + dynamicSrcMaskValue=srcMaskValue, & + dynamicDstMaskValue=-2.d0, & + dynamicMaskRoutine=simpleHandleAllProc, & + handleAllElements=.true., & + rc=rc) ++ +
+
+ call ESMF_FieldRegrid(srcField=srcField, dstField=dstField, & + routehandle=routehandle, zeroregion=ESMF_REGION_EMPTY, & + dynamicMask=dynamicMask, rc=rc) ++ +
+For the case with handleAllElements=.true., where the entire + vector of undistributed elements is passed to dynamicMaskRoutine at + every distributed location, an alternative implementation option exists for + the dynamic masking routine. In some cases this alternative may result in + more efficient code because it allows to vectorize over the undistributed + elements when summing up the interpolation terms. The alternative interface + for dynamicMaskRoutine is: + +
+
+ interface + subroutine ESMF_DynamicMaskRoutineR8R8R8V(dynMaskList, & + dynamicSrcMaskValue, dynamicDstMaskValue, rc) + use ESMF_UtilTypesMod + implicit none + type(ESMF_DynamicMaskElementR8R8R8V), pointer :: dynMaskList(:) + real(ESMF_KIND_R8), intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R8), intent(in), optional :: dynamicDstMaskValue + integer, intent(out) :: rc + end subroutine + end interface ++ +
+The difference compared to the previously used interface is that the first + argument now is of type ESMF_DynamicMaskElementR8R8R8V. This type is + declared as follows: + +
+
+ type ESMF_DynamicMaskElementR8R8R8V + real(ESMF_KIND_R8), pointer :: dstElement(:) + real(ESMF_KIND_R8), allocatable :: factor(:) + type(ESMF_PtrR8D1), allocatable :: srcElement(:) + end type ++ +
+Here size(dstElement) for every element in dynMaskList is + identical to the vector size, i.e. the number of undistributed elements to + be handled. The same is true for size(srcElement(j)%ptr)), for every + element j of the interpolation stencile. +
+
+ call ESMF_DynamicMaskSetR8R8R8V(dynamicMask, & + dynamicSrcMaskValue=srcMaskValue, & + dynamicDstMaskValue=-2.d0, & + dynamicMaskRoutine=simpleHandleAllProcV, & + handleAllElements=.true., & + rc=rc) ++ +
+
+ call ESMF_FieldRegrid(srcField=srcField, dstField=dstField, & + routehandle=routehandle, zeroregion=ESMF_REGION_EMPTY, & + dynamicMask=dynamicMask, rc=rc) ++ +
+Applying dynamic masking to source and destination fields of other typekind + than R8 only requires that the correct DynamicMaskSet method is chosen. + Here we create real(ESMF_KIND_R4) source and destination fields. +
+
+ srcField = ESMF_FieldCreate(srcGrid, ESMF_TYPEKIND_R4, rc=rc) ++ +
+
+ dstField = ESMF_FieldCreate(dstGrid, ESMF_TYPEKIND_R4, rc=rc) ++ +
+Computing a suitable RouteHandle is unchanged. +
+
+ srcTermProcessing=0 + + call ESMF_FieldRegridStore(srcField=srcField, dstField=dstField, & + srcTermProcessing=srcTermProcessing, routehandle=routehandle, rc=rc) ++ +
+Now setting some source and destination elements to defined special values + of the correct typekind. +
+
+ call ESMF_FieldGet(srcField, farrayPtr=farrayPtrR4, rc=rc) ++ +
+
+ farrayPtrR4(lbound(farrayPtrR4,1)+3,lbound(farrayPtrR4,2)+3) = srcMaskValueR4 ++ +
+
+ call ESMF_FieldFill(dstField, dataFillScheme="const", const1=0.d0, rc=rc) ++ +
+
+ call ESMF_FieldGet(dstField, farrayPtr=farrayPtrR4, rc=rc) ++ +
+
+ farrayPtrR4(lbound(farrayPtrR4,1)+1,lbound(farrayPtrR4,2)+1) = dstMaskValueR4 ++ +
+Setting up the ESMF_DynamicMask object is practically the same as + before, just that the correct typekind-triplet suffix for the + DynamicMaskSet method must be selected, indicating that the + destination data is of typekind R4, the factors are still of typekind R8, + and the source data is of typekind R4. +
+
+ call ESMF_DynamicMaskSetR4R8R4(dynamicMask, & + dynamicSrcMaskValue=srcMaskValueR4, & + dynamicDstMaskValue=dstMaskValueR4, & + dynamicMaskRoutine=simpleDynMaskProcR4R8R4, & + rc=rc) ++ +
+Finally calling into ESMF_FieldRegrid() with the dynamicMask + object is unchanged. +
+
+ call ESMF_FieldRegrid(srcField=srcField, dstField=dstField, & + routehandle=routehandle, zeroregion=ESMF_REGION_EMPTY, & + dynamicMask=dynamicMask, rc=rc) ++ +
+ + +
+ +
+
+ +
+
+
+
+
+
+Internally all route-based communication calls are implemented as sparse matrix multiplications. The precompute step for all of the supported communication methods can be broken up into three steps: + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_RouteHandleCreate() + function ESMF_RouteHandleCreateRH(routehandle, & + originPetList, targetPetList, rc) +RETURN VALUE: +
type(ESMF_RouteHandle) :: ESMF_RouteHandleCreateRH +ARGUMENTS: +
type(ESMF_RouteHandle), intent(in) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: originPetList(:) + integer, intent(in), optional :: targetPetList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a new ESMF_RouteHandle object from and existing RouteHandle. + The new RouteHandle can be created to function on a different petList than + the incoming RouteHandle. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_RouteHandleCreate() + function ESMF_RouteHandleCreateFile(fileName, rc) +RETURN VALUE: +
type(ESMF_RouteHandle) :: ESMF_RouteHandleCreateFile +ARGUMENTS: +
character(*), intent(in) :: fileName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a new ESMF_RouteHandle object from a file. This method must + be called from a VM context that holds exactly as many PETs as were used + when generating the file. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_RouteHandleDestroy(routehandle, & + noGarbage, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Destroys an ESMF_RouteHandle, releasing the resources associated + with the object. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_RouteHandleGet() + subroutine ESMF_RouteHandleGetP(routehandle, name, vm, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(in) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(out), optional :: name + type(ESMF_VM), intent(out), optional :: vm + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Returns information about an ESMF_RouteHandle. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_RouteHandleIsCreated(routehandle, rc) +RETURN VALUE: +
logical :: ESMF_RouteHandleIsCreated +ARGUMENTS: +
type(ESMF_RouteHandle), intent(in) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the routehandle has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_RouteHandleSet() + subroutine ESMF_RouteHandleSetP(routehandle, name, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len = *), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set an ESMF_RouteHandle attribute with the given value. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_RouteHandleWrite(routehandle, fileName, rc) +ARGUMENTS: +
type(ESMF_RouteHandle), intent(inout) :: routehandle + character(*), intent(in) :: fileName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write the RouteHandle to file. The generated file can then be used to + re-create the same RouteHandle, on the same number of PETs, using the + ESMF_RouteHandleCreate(fileName=...) method. + +
+The arguments are: +
+ + +
+The ESMF I/O provides a unified interface for input and output of +high level ESMF objects such as Fields. ESMF I/O capability is integrated +with third-party software such as Parallel I/O (PIO) +to read and write Fortran array data in NetCDF format, and +JSON for Modern C++ +Library to read Info attribute data in JSON format. Other file I/O +functionalities, such as writing of error and log messages, input of +configuration parameters from an ASCII file, and lower-level I/O utilities are +covered in different sections of this document. See the Log Class +49.1, the Config Class 47.1, and the Fortran +I/O Utilities, 53.1 respectively. + +
+ +
+ESMF provides interfaces for high performance, parallel I/O using ESMF data +objects such as Arrays and Fields. Currently ESMF only supports I/O of +NetCDF files. The current ESMF implementation relies on the +Parallel I/O (PIO) +library developed as a collaboration between NCAR and DOE laboratories. PIO +is built as part of the ESMF build when the environment variable ESMF_PIO is +set to "internal", or is linked against when ESMF_PIO is set to "external"; by +default ESMF_PIO is not set (which results in using the internal PIO if other +aspects of the ESMF build configuration allow it). When PIO is built with ESMF, +the ESMF methods internally call the PIO interfaces. When ESMF is not built with +PIO, the ESMF methods are non-operable (no-op) stubs that simply return with +a return code of ESMF_RC_LIB_NOT_PRESENT. Details about the environment +variables can be found in ESMF User Guide, "Building and Installing the ESMF", +"Third Party Libraries". + +
+The following methods support parallel data I/O using PIO: + +
+
+ +
+The only format currently supported is NetCDF. The environment variables +ESMF_NETCDF and/or ESMF_PNETCDF must be set to enable this NetCDF-based I/O. +Details about the environment variables can be found in ESMF User Guide, +"Building and Installing the ESMF", "Third Party Libraries". + +
+
+To the extent that data on unstructured grids (or even observations) can be +represented as one-dimensional arrays, NetCDF can also be used to store these +data. However, it does not provide a high-level abstraction for this type of +data. + +
+
+ +
+ +
+
+
+
+ +
+For data I/O, the ESMF I/O capability relies on the +PIO +and +NetCDF +libraries, and optionally the +PNetCDF +library. For Info attribute I/O, the ESMF I/O capability uses the +JSON for Modern C++ +library to perform reading of JSON files. PIO and JSON for Modern C++ +are included with the ESMF distribution; the other libraries must be +installed on the machine of interest. + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_refdoc/node6.html b/docs/nightly/fix/reconcile-info/ESMF_refdoc/node6.html new file mode 100644 index 000000000..416ec07e6 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_refdoc/node6.html @@ -0,0 +1,30400 @@ + + + + + ++ +
+The ESMF utilities are a set of tools for quickly assembling modeling applications. + +
+The ESMF Info class enables models to be self-describing via metadata, which are instances of JSON-compatible key-value pairs. + +
+The Time Management Library provides utilities for time and time interval representation and calculation, and higher-level utilities that control model time stepping, via clocks, as well as alarming. + +
+The ESMF Config class provides configuration management based on NASA DAO's Inpak package, a collection of methods for accessing files containing input parameters stored in an ASCII format. + +
+The ESMF LogErr class consists of a variety of methods for writing error, warning, and informational messages to log files. A default Log is created during ESMF initialization. Other Logs can be created later in the code by the user. + +
+The DELayout class provides a layer of abstraction on top of the Virtual Machine (VM) layer. DELayout does this by introducing DEs (Decomposition Elements) as logical resource units. The DELayout object keeps track of the relationship between its DEs and the resources of the associated VM object. A DELayout can be shaped by the user at creation time to best match the computational problem or other design criteria. + +
+The ESMF VM (Virtual Machine) class is a generic representation of hardware and system software resources. There is exactly one VM object per ESMF Component, providing the execution environment for the Component code. The VM class handles all resource management tasks for the Component class and provides a description of the underlying configuration of the compute resources used by a Component. In addition to resource description and management, the VM class offers the lowest level of ESMF communication methods. + +
+The ESMF Fortran I/O utilities provide portable methods to access capabilities which are often implemented in different ways amongst different environments. Currently, two utility methods are implemented: one to find an unopened unit number, and one to flush an I/O buffer. + +
+All ESMF base objects (i.e. Array, ArrayBundle, Field, FieldBundle, Grid, Mesh, DistGrid) contain a key-value attribute storage object called ESMF_Info. ESMF_Info objects may also be created independent of a base object. ESMF_Info supports setting and getting key-value pairs where the key is a string and the value is a scalar or a list of common data types. An ESMF_Info object may have a flat or nested data structure. The purpose of ESMF_Info is to support I/O-compatible metadata structures (i.e. netCDF), internal record-keeping for model execution (NUOPC), and provide a mechanism for custom user metadata attributes. + +
+ESMF_Info is designed for interoperability. To achieve this goal, ESMF_Info adopted the JSON (Javascript Object Notation) specification. Internally, ESMF_Info uses JSON for Modern C++ [1] to manage its storage map. There are numerous resources for JSON on the web [11]. Quoting from the json.org site [11] when it introduces the format: +
+JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language. + JSON is built on two structures: ++
+ These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangeable with programming languages also be based on these structures. + ++ +
+By adopting JSON compliance for ESMF_Info, ESMF made its core metadata capabilities explicitly interoperable with a widely used data structure. If data may be represented with JSON, then it is compatible with ESMF_Info. + +
+There are some aspects of the ESMF_Info implementation related to JSON and JSON for Modern C++ that should be noted: + +
+ +
+Below are examples for setting and getting an attribute using ESMF_Info and the legacy ESMF_Attribute. The ESMF_Info interfaces are not overloaded for ESMF object types but rather work off a handle retrieved via a get call. + +
+ +
+call ESMF_AttributeSet(array, "aKey", 15, rc=rc) ++With ESMF_Info: +
+call ESMF_InfoGetFromHost(array, info, rc=rc) +call ESMF_InfoSet(info, "aKey", 15, rc=rc) ++ +
+Notice that the legacy ESMF_Attribute API expects the usage of what was called an "Attribute Package". This essentially corresponds to a namespace similar to what ESMF_Info provides for keys via the JSON Pointer syntax (see 40.2). In the above ESMF_AttributeSet() call, without specification of convention and purpose arguments, the resulting JSON pointer of the key is "/ESMF/General/aKey". This is important to account for when mixing deprecated ESMF_Attribute calls with the ESMF_Info API. + +
+ +
+call ESMF_AttributeGet(array, "aKey", aKeyValue, rc=rc) ++With ESMF_Info: +
+call ESMF_InfoGetFromHost(array, info, rc=rc) +call ESMF_InfoGet(info, "aKey", aKeyValue, rc=rc) ++ +
+Notice again that the ESMF_Attribute API automatically prepends "/ESMF/General/" to the JSON pointer used for key in the absence of convention and purpose arguments. + +
+ +
+Some examples for valid "key" arguments: + +
+ +
+ +
+ +
+Variable declarations: +
+
+ type(ESMF_DistGrid) :: distgrid + type(ESMF_Array) :: array + type(ESMF_Info) :: infoh + real(ESMF_KIND_R8), dimension(10,10) :: farray + integer :: rc ++ +
+Create an ESMF Array. +
+
+ distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), maxIndex=(/10,10/), rc=rc) ++ +
+
+ array = ESMF_ArrayCreate(distgrid, farray, indexflag=ESMF_INDEX_DELOCAL, rc=rc) ++ +
+Get the ESMF_Info handle from the object. See example 40.3.2 for + additional usage examples. +
+
+ call ESMF_InfoGetFromHost(array, infoh, rc=rc) ++ +
+
++ +
+Destroy everything except the ESMF_Info object. Attempting to destroy + the ESMF_Info handle will result in an error. +
+
+ call ESMF_ArrayDestroy(array, rc=rc) ++ +
+
+ call ESMF_DistGridDestroy(distgrid, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+Variable declarations: +
+
+ type(ESMF_Info) :: info, infoCopy, infoFromCh + type(ESMF_TypeKind_Flag) :: typekind + character(len=ESMF_MAXSTR) :: ikey + character(:), allocatable :: output, getCh + real(ESMF_KIND_R8), dimension(4) :: realList + real(ESMF_KIND_R8), dimension(:), allocatable :: realListAlloc + integer(ESMF_KIND_I4) :: getInt + real(ESMF_KIND_R8) :: getReal + integer :: rc, infoSize, ii + logical :: isPresent, isSet ++ +
+Create an ESMF_Info object. This object contains an empty key-value + store called a JSON object [8]. + +
+An ESMF_Info handle may also be retrieved from an ESMF object as opposed to + creating a standalone ESMF_Info object. See example 40.3.1. +
+
+ info = ESMF_InfoCreate(rc=rc) ++ +
+Add an integer value. +
+
+ call ESMF_InfoSet(info, "myIntegerKey", 54, rc=rc) ++ +
+Get the integer value we just set. +
+
+ call ESMF_InfoGet(info, "myIntegerKey", getInt, rc=rc) ++ +
+Set a list of reals. +
+
+ call ESMF_InfoSet(info, "myListOfReals", (/ 33.3, 44.4, 0.0, 99.0 /), rc=rc) ++ +
+Set an index in the new list then retrieve the value. +
+
+ call ESMF_InfoSet(info, "myListOfReals", 1234.0, idx=3, rc=rc) ++ +
+
+ call ESMF_InfoGet(info, "myListOfReals", getReal, idx=3, rc=rc) ++ +
+Get the values from a list. +
+
+ call ESMF_InfoGet(info, "myListOfReals", realList, rc=rc) ++ +
+Allocatable lists may be used through a specific interface. +
+
+ call ESMF_InfoGetAlloc(info, "myListOfReals", realListAlloc, rc=rc) ++ +
+The storage contents may be printed directly or dumped to a character. +
+
+ call ESMF_InfoPrint(info, indent=4, rc=rc) ++ +
+
+ output = ESMF_InfoDump(info, rc=rc) ++ +
+
+ print *, "the Info dump: "//output ++ +
+Check if a key is present. +
+
+ isPresent = ESMF_InfoIsPresent(info, "myIntegerKey", rc=rc) ++ +
+
+ if (.not. isPresent) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+Add a null value and check if it is set (has a non-null value). +
+
+ call ESMF_InfoSetNULL(info, "aNullKey", rc=rc) ++ +
+
+ isSet = ESMF_InfoIsSet(info, "aNullKey", rc=rc) ++ +
+
+ if (isSet) call ESMF_Finalize(endflag=ESMF_END_ABORT) + + isSet = ESMF_InfoIsSet(info, "myIntegerKey", rc=rc) ++ +
+
+ if (.not. isSet) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+The force flag, when set to false, will cause an error if the key exists in the + map. The force flag is set to true by default. +
+
+ call ESMF_InfoSet(info, "myIntegerKey", 33, force=.false., rc=rc) + if (rc .ne. ESMC_RC_CANNOT_SET) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+Nesting uses the JSON Pointer 40.2 syntax. All key arguments + in ESMF_Info may use this syntax unless noted otherwise. When creating + a nested object, objects are created if they do not exist. Hence, it is not necessary + to create the individual nested elements for deep hierarchies. +
+
+ call ESMF_InfoSet(info, "/Universe/Galaxy/Star/Planet", "Venus", rc=rc) ++ +
+Using the get interface, it is possible to iterate over the storage contents. + In the call below, we are retrieving the number of elements (key-value pairs) + that exist in our root storage object. We then select the target element in root + using an index and retrieve some additional metadata for the target object. +
+
+ call ESMF_InfoGet(info, size=infoSize, rc=rc) ++ +
+
+ do ii=1,infoSize + call ESMF_InfoGet(info, idx=ii, ikey=ikey, typekind=typekind, rc=rc) ++ +
+
+ if (localPet == 0) then + print *, "ESMF_Info inquire loop: " + print *, " idx= ", ii + print *, " ikey= ", trim(ikey) + print *, " typekind= ", typekind + endif + enddo ++ +
+Copying the ESMF_Info object requires the copy to be destroyed/deallocated. +
+
+ infoCopy = ESMF_InfoCreate(info, rc=rc) ++ +
+Comparison operators = and /= are implemented for ESMF_Info objects. +
+
+ if (infoCopy /= info) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+After removing a key from the copied ESMF_Info object, the two objects will no + longer be equal. +
+
+ call ESMF_InfoRemove(infoCopy, "myIntegerKey", rc=rc) ++ +
+
+ if (infoCopy == info) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+Destroy the copied object. +
+
+ call ESMF_InfoDestroy(infoCopy, rc=rc) ++ +
+An ESMF_Info object may be created from a JSON string. Note the usage of quotes + is required as below. +
+
+ infoFromCh = ESMF_InfoCreate('{"hello":"world"}', rc=rc) ++ +
+The contents of an ESMF_Info object may be set in another ESMF_Info object. +
+
+ call ESMF_InfoSet(info, "infoFromCh", infoFromCh, rc=rc) ++ +
+
+ call ESMF_InfoDestroy(infoFromCh, rc=rc) ++ +
+An allocatable character get interface is available. +
+
+ call ESMF_InfoGetCharAlloc(info, "/infoFromCh/hello", getCh, rc=rc) ++ +
+Destroy the ESMF_Info object. +
+
+ call ESMF_InfoDestroy(info, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + info1 = info2 +ARGUMENTS: +
type(ESMF_Info) :: info1 + type(ESMF_Info) :: info2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign info1 as an alias to the same ESMF Info object in memory + as info2. If info2 is invalid, then info1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info1 + type(ESMF_Info), intent(in) :: info2 ++DESCRIPTION: +
+Test if the contents of two ESMF_Info objects are equal. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info1 + type(ESMF_Info), intent(in) :: info2 ++DESCRIPTION: +
+Test if the contents of two ESMF_Info objects are not equal. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoBroadcast(info, rootPet, rc) +ARGUMENTS: +
type(ESMF_Info), intent(inout) :: info + integer, intent(in) :: rootPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Broadcast an ESMF_Info object collectively across the current VM. + +
+Users wishing to synchronize via broadcast an attribute hierarchy associated + with an ESMF object should consult the ESMF_InfoSync documentation + 40.4.29 + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_InfoCreate() + function ESMF_InfoCreateEmpty(rc) +ARGUMENTS: +
integer, intent(out), optional :: rc +RETURN VALUE: +
type(ESMF_Info) :: ESMF_InfoCreateEmpty ++DESCRIPTION: +
+Create an ESMF_Info object. This object must be destroyed using + ESMF_InfoDestroy to free its memory allocation + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_InfoCreate() + function ESMF_InfoCreateByKey(info, key, rc) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + character(len=*), intent(in) :: key + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc +RETURN VALUE: +
type(ESMF_Info) :: ESMF_InfoCreateByKey ++DESCRIPTION: +
+Create an ESMF_Info object from a location in info + defined by key. Returned object is a deep copy. The value associated + with key must be a nested object (i.e. a collection of key/value + pairs). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_InfoCreate() + function ESMF_InfoCreateFromInfo(info, rc) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc +RETURN VALUE: +
type(ESMF_Info) :: ESMF_InfoCreateFromInfo ++DESCRIPTION: +
+Create an ESMF_Info object from another ESMF_Info object. + The returned object is a deep copy of the source object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_InfoCreate() + function ESMF_InfoCreateByParse(jsonString, rc) +ARGUMENTS: +
character(len=*), intent(in) :: jsonString + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc +RETURN VALUE: +
type(ESMF_Info) :: ESMF_InfoCreateByParse ++DESCRIPTION: +
+Create an ESMF_Info object by parsing a JSON-formatted string. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoDestroy(info, rc) +ARGUMENTS: +
type(ESMF_Info), intent(inout) :: info + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Destroy an ESMF_Info object. Destroying an ESMF_Info + object created internally by an ESMF object results in an error + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_InfoDump(info, key, indent, rc) result(output) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(*), intent(in), optional :: key + integer, intent(in), optional :: indent + integer, intent(out), optional :: rc + RESULT: + character(:), allocatable :: output ++DESCRIPTION: +
+Dump the contents of an ESMF_Info object as a JSON string. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoGet(info, key, value, default, idx, attnestflag, rc) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + character(len=*), intent(in) :: key + <value>, see below for supported value + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + <default, optional> see below for supported default value + integer, intent(in), optional :: idx + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get a value from an ESMF_Info object using a key. If the key is + not found, rc will not equal ESMF_SUCCESS. The returned + value is always a copy including gets with a default. + +
+Overloaded value for the following types: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoGetCharAlloc(info, key, value, default, idx, attnestflag, rc) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + character(len=*), intent(in) :: key + character(:), allocatable, intent(out) :: value + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: default + integer, intent(in), optional :: idx + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get a value from an ESMF_Info object using a key. If the key is + not found, rc will not equal ESMF_SUCCESS. The returned + value is always a copy including gets with a default. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoGet(info, key, values, itemCount, attnestflag, scalarToArray, rc) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + character(len=*), intent(in) :: key + <values>, see below for supported values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: itemCount + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + logical, intent(in), optional :: scalarToArray + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get a value list from an ESMF_Info object using a key. If the key + is not found, rc will not equal ESMF_SUCCESS. The returned + value is always a copy. + +
+The length of values must match its length in storage. + +
+Overloaded values for the following types: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoGetAlloc(info, key, values, itemCount, attnestflag, scalarToArray, rc) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + character(len=*), intent(in) :: key + <values>, see below for supported values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: itemCount + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + logical, intent(in), optional :: scalarToArray + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get a value list from an ESMF_Info object using a key. If the key + is not found, rc will not equal ESMF_SUCCESS. The returned + value is always a copy. + +
+Overloaded values for the following types: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_InfoGet() + subroutine ESMF_InfoInquire(info, size, key, jsonType, isArray, & + isDirty, idx, typekind, ikey, isPresent, isStructured, isNull, rc) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: size + character(len=*), intent(in), optional :: key + character(len=*), intent(out), optional :: jsonType + logical, intent(out), optional :: isArray + logical, intent(out), optional :: isDirty + integer, intent(in), optional :: idx + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + character(len=*), intent(out), optional :: ikey + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isStructured + logical, intent(out), optional :: isNull + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Inquire an ESMF_Info object for metadata. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoGetFromHost(host, info, rc) +ARGUMENTS: +
type(ESMF_*), intent(inout) :: host + type(ESMF_Info), intent(out) :: info + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get an ESMF_Info object handle from a host ESMF object. The returned + handle should not be destroyed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_InfoGetTK(info, key, attnestflag, rc) result(typekind) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + character(len=*), intent(in) :: key + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(out), optional :: rc +RETURN VALUE: +
type(ESMF_TypeKind_Flag) :: typekind ++DESCRIPTION: +
+Return the ESMF TypeKind of the value associated with key. + See section 54.61 for valid return values. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoGetArrayMeta(info, key, isArray, size, attnestflag, rc) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + character(len=*), intent(in) :: key + logical, intent(out) :: isArray + integer(C_INT), intent(out) :: size + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return a value's array status and size using a key. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_InfoIsPresent(info, key, attnestflag, isPointer, rc) result(is_present) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + character(len=*), intent(in) :: key + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + logical, intent(in), optional :: isPointer + integer, intent(out), optional :: rc +RETURN VALUE: +
logical :: is_present ++DESCRIPTION: +
+Return true if key exists in ESMF_Info's storage. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_InfoIsSet(info, key, rc) result(is_set) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + character(len=*), intent(in) :: key + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc +RETURN VALUE: +
logical :: is_set ++DESCRIPTION: +
+Returns true if the target value is not null [7]. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoPrint(info, indent, preString, unit, rc) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(*), intent(in), optional :: preString + character(*), intent(out), optional :: unit + integer, intent(in), optional :: indent + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Print ESMF_Info contents in JSON format. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_InfoReadJSON(filename, rc) result(info_r) +ARGUMENTS: +
character(len=*), intent(in) :: filename + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc +RETURN VALUE: +
type(ESMF_Info) :: info_r ++DESCRIPTION: +
+Read JSON data from a file and return a new ESMF_Info object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoRemove(info, keyParent, keyChild, attnestflag, rc) +ARGUMENTS: +
type(ESMF_Info), intent(inout) :: info + character(len=*), intent(in) :: keyParent + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: keyChild + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Remove a key-value pair from an ESMF_Info object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoSet(info, key, value, force, idx, pkey, rc) +ARGUMENTS: +
type(ESMF_Info), intent(inout) :: info + character(len=*), intent(in) :: key + <value>, see below for supported value + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: force + integer, intent(in), optional :: idx + character(len=*), intent(in), optional :: pkey + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set a value in an ESMF_Info object using a key. + +
+Overloaded value for the following types: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_InfoSet + subroutine ESMF_InfoSetINFO(info, key, value, force, rc) +ARGUMENTS: +
type(ESMF_Info), intent(inout) :: info + character(len=*), intent(in) :: key + type(ESMF_Info), intent(in) :: value + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: force + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set a value to the contents of an ESMF_Info object. A copy of + the source contents is made. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_InfoSet + recursive subroutine ESMF_InfoSetHConfig(info, value, keyPrefix, force, rc) +ARGUMENTS: +
type(ESMF_Info), intent(inout) :: info + type(ESMF_HConfig), intent(in) :: value + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: keyPrefix + logical, intent(in), optional :: force + integer, intent(out), optional :: rc ++DESCRIPTION: +
+The provided ESMF_HConfig object is expected to be a map. + An error is returned if this condition is not met. Each key-value pair + held by the ESMF_HConfig object is added to the + ESMF_Info object. A copy of the source contents is made. + +
+Transfer of scalar, sequence, and map values + from ESMF_HConfig to ESMF_Info are supported. + Maps are treated recursively. Sequences are restricted to scalar elements + of the same typekind. + +
+The keys of any map provided by the ESMF_HConfig object must + be of scalar type. Keys are interpreted as strings when transferred to the + ESMF_Info object. YAML merge keys "«" are supported. + +
+When existing keys in info are overridden by this operation, the + typekind of the associated value element is allowed to change. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoSet(info, key, values, force, pkey, rc) +ARGUMENTS: +
type(ESMF_Info), intent(inout) :: info + character(len=*), intent(in) :: key + <values>, see below for supported values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: force + character(len=*), intent(in), optional :: pkey + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set a value list in an ESMF_Info object using a key. List values + are initialized to null. + +
+Overloaded values for the following types: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoSetNULL(info, key, force, rc) +ARGUMENTS: +
type(ESMF_Info), intent(inout) :: info + character(len=*), intent(in) :: key + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: force + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set a value to null [7]. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoSync(host, rootPet, vm, markClean, & + rc) +ARGUMENTS: +
type(ESMF_*), intent(inout) :: host + integer, intent(in) :: rootPet + type(ESMF_VM), intent(in) :: vm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: markClean + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Synchronize ESMF_Info contents collectively across the current VM. + Contents on the rootPet are set as the contents on matching objects + sharing the VM. An attempt is made to optimize by only communicating updated + contents (i.e. something set or modified). This subroutine will traverse + the ESMF object hierarchy associated with host (i.e. Arrays in + an ArrayBundle, Fields in a FieldBundle, etc.). + +
+Users interested in broadcasting only the ESMF_Info object should + consult the ESMF_InfoBroadcast documentation 40.4.4. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoUpdate(lhs, rhs, recursive, overwrite, rc) +ARGUMENTS: +
type(ESMF_Info), intent(inout) :: lhs + type(ESMF_Info), intent(in) :: rhs + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: recursive + logical, intent(in), optional :: overwrite + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Update the contents of lhs using the contents of rhs. The + operation inserts or overwrites any key in lhs if it exists in rhs. + Otherwise, the contents of lhs is left unaltered. See the JSON + documentation for implementation details [10]. + If recursive is .true. (default is .false.), + nested objects will be updated by their component key/values. Otherwise, + the first instance or top-level key is replaced without the child contents + being updated element-by-element. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_InfoWriteJSON(info, filename, rc) +ARGUMENTS: +
type(ESMF_Info), intent(in) :: info + character(len=*), intent(in) :: filename + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write ESMF_Info contents to file using the JSON format. + +
+The arguments are: +
+The ESMF Time Manager utility includes software for time and date +representation and calculations, model time advancement, and the +identification of unique and periodic events. Since multi-component +geophysical applications often require synchronization across +the time management schemes of the individual components, the +Time Manager's standard calendars and consistent time representation +promote component interoperability. +
+ +Key Features |
+
Drift-free timekeeping through an integer-based internal time +representation. Both integers and reals can be specified at the interface. | +
The ability to represent time as a rational fraction, to support +exact timekeeping in applications that involve grid refinement. | +
Support for many calendar kinds, including user-customized calendars. | +
Support for both concurrent and sequential modes of component execution. | +
Support for varying and negative time steps. | +
+ +
+
+In the remainder of this section, we briefly summarize the +functionality that the Time Manager classes provide. Detailed +descriptions and usage examples precede the API listing for each +class. + +
+ +
+ +
+TimeIntervals and Time instants (simply called Times) are the computational +building blocks of the Time Manager utility. TimeIntervals support operations +such as add, subtract, compare size, reset value, copy value, and subdivide +by a scalar. Times, which are moments in time associated with specific +Calendars, can be incremented or decremented by TimeIntervals, compared to +determine which of two Times is later, differenced to obtain the TimeInterval +between two Times, copied, reset, and manipulated in other useful ways. +Times support a host of different queries, both for values of individual Time +components such as year, month, day, and second, and for derived values such +as day of year, middle of current month and Julian day. It is also possible +to retrieve the value of the hardware realtime clock in the form of a +Time. See Sections 43.1 and 44.1, respectively, +for use and examples of Times and TimeIntervals. + +
+Since climate modeling, numerical weather prediction and other +Earth and space applications have widely varying time scales and require +different sorts of calendars, Times and TimeIntervals must support +a wide range of time specifiers, spanning nanoseconds to years. The +interfaces to these time classes are defined so that the user can specify a time +using a combination of units selected from the list shown in +Table 41.4. + +
+ +
Unit | +Meaning | +
<yy|yy_i8> | +Year. | +
mm | +Month of the year. | +
dd | +Day of the month. | +
<d|d_i8|d_r8> | +Julian or Modified Julian day. | +
<h|h_r8> | +Hour. | +
<m|m_r8> | +Minute. | +
<s|s_i8|s_r8> | +Second. | +
<ms|ms_r8> | +Millisecond. | +
<us|us_r8> | +Microsecond. | +
<ns|ns_r8> | +Nanosecond. | +
O | +Time zone offset in integer number of hours and minutes. | +
<sN|sN_i8> | +Numerator for times of the form s +, where s is seconds and s, sN, and +sD are integers. This format provides a mechanism for supporting +exact behavior. | +
<sD|sD_i8 | +Denominator for times of the form s +, where s is seconds and s, sN, and +sD are integers. | +
+ +
+The result of this strategy is that Time Intervals and +Times gain a consistent core representation of time as well a set +of basic methods. + +
+The BaseTime class can be designed with a minimum number of elements +to represent any required time. The design is based on the idea used +in the real-time POSIX 1003.1b-1993 standard. That is, to represent +time simply as a pair of integers: one for seconds (whole) and one for +nanoseconds (fractional). These can then be converted at the interface +level to any desired format. + +
+For ESMF, this idea can be modified and extended, in order to handle the +requirements for a large time range (> 200,000 years) and to exactly +represent any rational fraction, not just nanoseconds. To handle the +large time range, a 64-bit or greater integer is used for whole seconds. +Any rational fractional second is expressed using two additional integers: +a numerator and a denominator. Both the whole seconds and fractional +numerator are signed to handle negative time intervals and instants. +For arithmetic consistency both must carry the same sign (both positive +or both negative), except, of course, for zero values. The fractional +seconds element (numerator) is bounded with respect to whole seconds. +If the absolute value of the +numerator becomes greater than or equal to the denominator, whole +seconds are incremented or decremented accordingly and the numerator is +reset to the remainder. Conversions are performed upon demand by +interface methods within the TimeInterval and +Time classes. This is done because different applications require different +representations of time intervals and time instances. Floating point values as well as integers can be specified for the various time units in the interfaces, see Table 41.4. Floating point values are represented internally as integer-based rational fractions. + +
+The BaseTime class defines increment and decrement methods for basic +TimeInterval calculations between Time instants. It is done here rather +than in the Calendar class because it can be done with simple +second-based arithmetic that is calendar independent. + +
+Comparison methods can also be defined in the BaseTime class. These +perform equality/inequality, less than, and greater than comparisons +between any two TimeIntervals or Times. These methods capture +the common comparison logic between TimeIntervals and Times and +hence are defined here for sharing. + +
+
+
+ +
+ +
+The following is a simplified UML diagram showing the structure of the +Time Manager utility. See Appendix A, A Brief Introduction to UML, +for a translation table that lists the symbols in the diagram and their +meaning. + +
+
+The Calendar class represents the standard calendars used in +geophysical modeling: Gregorian, Julian, Julian Day, Modified Julian Day, +no-leap, 360-day, and no-calendar. It also supports a user-customized +calendar. Brief descriptions are provided for each calendar below. For more +information on standard calendars, see [30] and [26]. + +
+ +
+DESCRIPTION:
+
+Supported calendar kinds.
+
+
+The type of this flag is: + +
+type(ESMF_CalKind_Flag) + +
+The valid values are: +
+
+
+
+
+
+MJD = JD - 2400000.5 + +
+The half day is subtracted so that the day starts at midnight. + +
+
+
+
+In most multi-component Earth system applications, the timekeeping in +each component +must refer to the same standard calendar in order for the components +to properly synchronize. It therefore makes sense to create as few +ESMF Calendars as possible, preferably one per application. +A typical strategy would be to create a single Calendar at the start +of an application, and use that Calendar in all subsequent calls that +accept a Calendar, such as ESMF_TimeSet. + +
+The following example shows how to set up an ESMF Calendar. + +
+ +
+ +
+
+! !PROGRAM: ESMF_CalendarEx - Calendar creation examples +! +! !DESCRIPTION: +! +! This program shows examples of how to create different calendar kinds +!----------------------------------------------------------------------------- +#include "ESMF.h" + + ! ESMF Framework module + use ESMF + use ESMF_TestMod + implicit none + + ! instantiate calendars + type(ESMF_Calendar) :: gregorianCalendar + type(ESMF_Calendar) :: julianDayCalendar + type(ESMF_Calendar) :: marsCalendar + + ! local variables for Get methods + integer :: sols + integer(ESMF_KIND_I8) :: dl + type(ESMF_Time) :: time, marsTime + type(ESMF_TimeInterval) :: marsTimeStep + + ! return code + integer:: rc ++ +
+
+ ! initialize ESMF framework + call ESMF_Initialize(defaultlogfilename="CalendarEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+ +
+This example shows how to create three ESMF_Calendars. +
+
+ ! create a Gregorian calendar + gregorianCalendar = ESMF_CalendarCreate(ESMF_CALKIND_GREGORIAN, & + name="Gregorian", rc=rc) ++ +
+
+ ! create a Julian Day calendar + julianDayCalendar = ESMF_CalendarCreate(ESMF_CALKIND_JULIANDAY, & + name="JulianDay", rc=rc) ++ +
+
+ ! create a Custom calendar for the planet Mars + ! 1 Mars solar day = 24 hours, 39 minutes, 35 seconds = 88775 seconds + ! 1 Mars solar year = 668.5921 Mars solar days = 668 5921/10000 sols/year + ! http://www.giss.nasa.gov/research/briefs/allison_02 + ! http://www.giss.nasa.gov/tools/mars24/help/notes.html + marsCalendar = ESMF_CalendarCreate(secondsPerDay=88775, & + daysPerYear=668, & + daysPerYearDn=5921, & + daysPerYearDd=10000, & + name="MarsCalendar", rc=rc) ++ +
+ +
+This example shows how to compare an ESMF_Calendar with a known + calendar kind. +
+
+ ! compare calendar kind against a known type + if (gregorianCalendar == ESMF_CALKIND_GREGORIAN) then + print *, "gregorianCalendar is of type ESMF_CALKIND_GREGORIAN." + else + print *, "gregorianCalendar is not of type ESMF_CALKIND_GREGORIAN." + end if ++ +
+ +
+This example shows how to convert a time from one ESMF_Calendar + to another. +
+
+ call ESMF_TimeSet(time, yy=2004, mm=4, dd=17, & + calendar=gregorianCalendar, rc=rc) ++ +
+
+ ! switch time's calendar to perform conversion + call ESMF_TimeSet(time, calendar=julianDayCalendar, rc=rc) ++ +
+
+ call ESMF_TimeGet(time, d_i8=dl, rc=rc) + print *, "Gregorian date 2004/4/17 is ", dl, & + " days in the Julian Day calendar." ++ +
+ +
+This example shows how to increment a time using a custom ESMF_Calendar. +
+
+ ! Set a time to Mars solar year 3, sol 100 + call ESMF_TimeSet(marsTime, yy=3, d=100, & + calendar=marsCalendar, rc=rc) ++ +
+
+ ! Set a 1 solar year time step + call ESMF_TimeIntervalSet(marsTimeStep, yy=1, rc=rc) ++ +
+
+ ! Perform the increment + marsTime = marsTime + marsTimeStep ++ +
+
+ ! Get the result in sols (2774 = (3+1)*668.5921 + 100) + call ESMF_TimeGet(marsTime, d=sols, rc=rc) + print *, "For Mars, 3 solar years, 100 sols + 1 solar year = ", & + sols, "sols." ++ +
+ +
+This example shows how to destroy three ESMF_Calendars. +
+
+ call ESMF_CalendarDestroy(julianDayCalendar, rc=rc) ++ +
+
+ call ESMF_CalendarDestroy(gregorianCalendar, rc=rc) ++ +
+
+ call ESMF_CalendarDestroy(marsCalendar, rc=rc) ++ +
+
+ ! finalize ESMF framework + call ESMF_Finalize(rc=rc) ++ +
+
+ end program ESMF_CalendarEx ++ +
+ + +
+ +
+
+
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + calendar1 = calendar2 +ARGUMENTS: +
type(ESMF_Calendar) :: calendar1 + type(ESMF_Calendar) :: calendar2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign calendar1 as an alias to the same ESMF_Calendar + object in memory as calendar2. If calendar2 is invalid, then + calendar1 will be equally invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (<calendar argument 1> == <calendar argument 2>) then ... endif + OR + result = (<calendar argument 1> == <calendar argument 2>) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
<calendar argument 1>, see below for supported values + <calendar argument 2>, see below for supported values ++DESCRIPTION: +
+Overloads the (==) operator for the ESMF_Calendar class. + Compare an ESMF_Calendar object or ESMF_CalKind_Flag with + another calendar object or calendar kind for equality. Return + .true. if equal, .false. otherwise. Comparison is based on + calendar kind, which is a property of a calendar object. + +
+If both arguments are ESMF_Calendar objects, and both are of + type ESMF_CALKIND_CUSTOM, then all the calendar's properties, + except name, are compared. + +
+If both arguments are ESMF_Calendar objects, and either of them + is not in the ESMF_INIT_CREATED status, an error will be logged. + However, this does not affect the return value, which is .true. + when both arguments are in the same status, and .false. + otherwise. + +
+If one argument is an ESMF_Calendar object, and the other is an + ESMF_CalKind_Flag, and the calendar object is not in the + ESMF_INIT_CREATED status, an error will be logged and + .false. will be returned. + +
+Supported values for <calendar argument 1> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (<calendar argument 1> /= <calendar argument 2>) then ... endif + OR + result = (<calendar argument 1> /= <calendar argument 2>) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
<calendar argument 1>, see below for supported values + <calendar argument 2>, see below for supported values ++DESCRIPTION: +
+Overloads the (/=) operator for the ESMF_Calendar class. + Compare a ESMF_Calendar object or ESMF_CalKind_Flag with + another calendar object or calendar kind for inequality. Return + .true. if not equal, .false. otherwise. Comparison is based + on calendar kind, which is a property of a calendar object. + +
+If both arguments are ESMF_Calendar objects, and both are of + type ESMF_CALKIND_CUSTOM, then all the calendar's properties, + except name, are compared. + +
+If both arguments are ESMF_Calendar objects, and either of them + is not in the ESMF_INIT_CREATED status, an error will be logged. + However, this does not affect the return value, which is .true. + when both arguments are not in the same status, and + .false. otherwise. + +
+If one argument is an ESMF_Calendar object, and the other is an + ESMF_CalKind_Flag, and the calendar object is not in the + ESMF_INIT_CREATED status, an error will be logged and + .true. will be returned. + +
+Supported values for <calendar argument 1> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CalendarCreate() + function ESMF_CalendarCreateBuiltIn(calkindflag, & + name, rc) +RETURN VALUE: +
type(ESMF_Calendar) :: ESMF_CalendarCreateBuiltIn +ARGUMENTS: +
type(ESMF_CalKind_Flag), intent(in) :: calkindflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Creates and sets a calendar to the given built-in + ESMF_CalKind_Flag. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CalendarCreate() + function ESMF_CalendarCreateCopy(calendar, rc) +RETURN VALUE: +
type(ESMF_Calendar) :: ESMF_CalendarCreateCopy +ARGUMENTS: +
type(ESMF_Calendar), intent(in) :: calendar + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Creates a complete (deep) copy of a given ESMF_Calendar. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CalendarCreate() + function ESMF_CalendarCreateCustom(& + daysPerMonth, secondsPerDay, & + daysPerYear, daysPerYearDn, daysPerYearDd, name, rc) +RETURN VALUE: +
type(ESMF_Calendar) :: ESMF_CalendarCreateCustom +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: daysPerMonth(:) + integer(ESMF_KIND_I4), intent(in), optional :: secondsPerDay + integer(ESMF_KIND_I4), intent(in), optional :: daysPerYear + integer(ESMF_KIND_I4), intent(in), optional :: daysPerYearDn + integer(ESMF_KIND_I4), intent(in), optional :: daysPerYearDd + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Creates a custom ESMF_Calendar and sets its properties. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CalendarDestroy(calendar, rc) +ARGUMENTS: +
type(ESMF_Calendar), intent(inout) :: calendar + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Releases resources associated with this ESMF_Calendar. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CalendarGet(calendar, & + name, calkindflag, daysPerMonth, monthsPerYear, & + secondsPerDay, secondsPerYear, & + daysPerYear, daysPerYearDn, daysPerYearDd, rc) +ARGUMENTS: +
type(ESMF_Calendar), intent(in) :: calendar + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_CalKind_Flag),intent(out), optional :: calkindflag + integer, intent(out), optional :: daysPerMonth(:) + integer, intent(out), optional :: monthsPerYear + integer(ESMF_KIND_I4), intent(out), optional :: secondsPerDay + integer(ESMF_KIND_I4), intent(out), optional :: secondsPerYear + integer(ESMF_KIND_I4), intent(out), optional :: daysPerYear + integer(ESMF_KIND_I4), intent(out), optional :: daysPerYearDn + integer(ESMF_KIND_I4), intent(out), optional :: daysPerYearDd + character (len=*), intent(out), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets one or more of an ESMF_Calendar's properties. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_CalendarIsCreated(calendar, rc) +RETURN VALUE: +
logical :: ESMF_CalendarIsCreated +ARGUMENTS: +
type(ESMF_Calendar), intent(in) :: calendar + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the calendar has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CalendarIsLeapYear() + function ESMF_CalendarIsLeapYear<kind>(calendar, yy, rc) +RETURN VALUE: +
logical :: ESMF_CalendarIsLeapYear<kind> +ARGUMENTS: +
type(ESMF_Calendar), intent(in) :: calendar + integer(ESMF_KIND_<kind>), intent(in) :: yy + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns .true. if the given year is a leap year within the given + calendar, and .false. otherwise. Custom calendars do not define + leap years, so .false. will always be returned in this case; + see Section 42.4. + See also ESMF_TimeIsLeapYear(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CalendarPrint(calendar, options, rc) +ARGUMENTS: +
type(ESMF_Calendar), intent(in) :: calendar + character (len=*), intent(in), optional :: options + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Prints out an ESMF_Calendar's properties to stdio,
+ in support of testing and debugging. The options control the
+ type of information and level of detail.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CalendarSet() + subroutine ESMF_CalendarSetBuiltIn(calendar, calkindflag, & + name, rc) +ARGUMENTS: +
type(ESMF_Calendar), intent(inout) :: calendar + type(ESMF_CalKind_Flag), intent(in) :: calkindflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets calendar to the given built-in ESMF_CalKind_Flag. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CalendarSet() + subroutine ESMF_CalendarSetCustom(calendar, & + daysPerMonth, secondsPerDay, & + daysPerYear, daysPerYearDn, daysPerYearDd, name, rc) +ARGUMENTS: +
type(ESMF_Calendar), intent(inout) :: calendar + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: daysPerMonth(:) + integer(ESMF_KIND_I4),intent(in), optional :: secondsPerDay + integer(ESMF_KIND_I4),intent(in), optional :: daysPerYear + integer(ESMF_KIND_I4),intent(in), optional :: daysPerYearDn + integer(ESMF_KIND_I4),intent(in), optional :: daysPerYearDd + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets properties in a custom ESMF_Calendar. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CalendarSetDefault() + subroutine ESMF_CalendarSetDefaultKind(calkindflag, rc) +ARGUMENTS: +
type(ESMF_CalKind_Flag), intent(in) :: calkindflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets the default calendar to the given type. Subsequent Time + Manager operations requiring a calendar where one isn't specified will + use the internal calendar of this type. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_CalendarSetDefault() + subroutine ESMF_CalendarSetDefaultCal(calendar, rc) +ARGUMENTS: +
type(ESMF_Calendar), intent(in) :: calendar + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets the default calendar to the one given. Subsequent Time + Manager operations requiring a calendar where one isn't specified will + use this calendar. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_CalendarValidate(calendar, rc) +ARGUMENTS: +
type(ESMF_Calendar), intent(in) :: calendar + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Checks whether a calendar is valid. + Must be one of the defined calendar kinds. daysPerMonth, daysPerYear, + secondsPerDay must all be greater than or equal to zero. + +
+The arguments are: +
+ + +
+A Time represents a specific point in time. In order to accommodate +the range of time scales in Earth system applications, Times in +the ESMF can be specified in many different ways, from years to +nanoseconds. The Time interface is designed so that you select one or +more options from a list of time units in order to specify a +Time. The options for specifying a Time are shown in +Table 41.4. + +
+There are Time methods defined for setting and getting a +Time, incrementing and decrementing a Time by a TimeInterval, +taking the difference between two Times, and comparing Times. +Special quantities such as the middle of the month and the +day of the year associated with a particular Time can be retrieved. +There is a method for returning the Time value as a string in +the ISO 8601 format YYYY-MM-DDThh:mm:ss [24]. + +
+A Time that is specified in hours, minutes, seconds, or subsecond intervals +does not need to be associated with a standard calendar; a Time whose +specification includes time units of a day and greater must be. The +ESMF representation +of a calendar, the Calendar class, is described in Section 42.1. +The ESMF_TimeSet method is used to initialize a Time as well as +associate it with a Calendar. If a Time method is invoked in which a Calendar +is necessary and one has not been set, the ESMF method will return an error +condition. + +
+In the ESMF the TimeInterval class is used to represent time periods. +This class is frequently used in combination with the Time class. +The Clock class, for example, advances model time by incrementing a +Time with a TimeInterval. + +
+ +
+Times are most frequently used to represent start, stop, and current +model times. The following examples show how to create, initialize, and +manipulate Time. + +
+ +
+ +
+ +
+
+! !PROGRAM: ESMF_TimeEx - Time initialization and manipulation examples +! +! !DESCRIPTION: +! +! This program shows examples of Time initialization and manipulation +!----------------------------------------------------------------------------- +#include "ESMF.h" + + ! ESMF Framework module + use ESMF + use ESMF_TestMod + implicit none + + ! instantiate two times + type(ESMF_Time) :: time1, time2 + + type(ESMF_VM) :: vm + + ! instantiate a time interval + type(ESMF_TimeInterval) :: timeinterval1 + + ! local variables for Get methods + integer :: YY, MM, DD, H, M, S + + ! return code + integer:: rc ++ +
+
+ ! initialize ESMF framework + call ESMF_Initialize(vm=vm, defaultCalKind=ESMF_CALKIND_GREGORIAN, & + defaultlogfilename="TimeEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+ +
+This example shows how to initialize an ESMF_Time. +
+
+ ! initialize time1 to 2/28/2000 2:24:45 + call ESMF_TimeSet(time1, yy=2000, mm=2, dd=28, h=2, m=24, s=45, rc=rc) ++ +
+
+ print *, "Time1 = " + call ESMF_TimePrint(time1, options="string", rc=rc) ++ +
+ +
+This example shows how to increment an ESMF_Time by + an ESMF_TimeInterval. +
+
+ ! initialize a time interval to 2 days, 8 hours, 36 minutes, 15 seconds + call ESMF_TimeIntervalSet(timeinterval1, d=2, h=8, m=36, s=15, rc=rc) ++ +
+
+ print *, "Timeinterval1 = " + call ESMF_TimeIntervalPrint(timeinterval1, options="string", rc=rc) ++ +
+
+ ! increment time1 with timeinterval1 + time2 = time1 + timeinterval1 + + call ESMF_TimeGet(time2, yy=YY, mm=MM, dd=DD, h=H, m=M, s=S, rc=rc) + print *, "time2 = time1 + timeinterval1 = ", YY, "/", MM, "/", DD, & + " ", H, ":", M, ":", S ++ +
+ +
+This example shows how to compare two ESMF_Times. +
+
+ if (time2 > time1) then + print *, "time2 is larger than time1" + else + print *, "time1 is smaller than or equal to time2" + endif ++ +
+
+ ! finalize ESMF framework + call ESMF_Finalize(rc=rc) ++ +
+
+ end program ESMF_TimeEx ++ +
+ + +
+ +
+For fractional seconds, a signed 64-bit integer will handle a resolution of ++/- -1, or +/- 9,223,372,036,854,775,807 parts of a second. + +
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + time1 = time2 +ARGUMENTS: +
type(ESMF_Time) :: time1 + type(ESMF_Time) :: time2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Set time1 equal to time2. This is the default Fortran + assignment, which creates a complete, independent copy of time2 + as time1. If time2 is an invalid ESMF_Time object then + time1 will be equally invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(+) + time2 = time1 + timeinterval +RETURN VALUE: +
type(ESMF_Time) :: time2 +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time1 + type(ESMF_TimeInterval), intent(in) :: timeinterval ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (+) operator for the ESMF_Time class to increment + time1 with timeinterval and return the result as an + ESMF_Time. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(-) + time2 = time1 - timeinterval +RETURN VALUE: +
type(ESMF_Time) :: time2 +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time1 + type(ESMF_TimeInterval), intent(in) :: timeinterval ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (-) operator for the ESMF_Time class to decrement + time1 with timeinterval, and return the result as an + ESMF_Time. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(-) + timeinterval = time1 - time2 +RETURN VALUE: +
type(ESMF_TimeInterval) :: timeinterval +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time1 + type(ESMF_Time), intent(in) :: time2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (-) operator for the ESMF_Time class to return the + difference between time1 and time2 as an + ESMF_TimeInterval. It is assumed that time1 is later than + time2; if not, the resulting ESMF_TimeInterval will have a + negative value. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (time1 == time2) then ... endif + OR + result = (time1 == time2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time1 + type(ESMF_Time), intent(in) :: time2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (==) operator for the ESMF_Time class to return + .true. if time1 and time2 represent the same instant + in time, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (time1 /= time2) then ... endif + OR + result = (time1 /= time2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time1 + type(ESMF_Time), intent(in) :: time2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (/=) operator for the ESMF_Time class to return + .true. if time1 and time2 do not represent the same + instant in time, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(<) + if (time1 < time2) then ... endif + OR + result = (time1 < time2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time1 + type(ESMF_Time), intent(in) :: time2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (<) operator for the ESMF_Time class to return + .true. if time1 is earlier in time than time2, and + .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(<=) + if (time1 <= time2) then ... endif + OR + result = (time1 <= time2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time1 + type(ESMF_Time), intent(in) :: time2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (<=) operator for the ESMF_Time class to return + .true. if time1 is earlier in time or the same time as + time2, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(>) + if (time1 > time2) then ... endif + OR + result = (time1 > time2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time1 + type(ESMF_Time), intent(in) :: time2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (>) operator for the ESMF_Time class to return + .true. if time1 is later in time than time2, and + .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(>=) + if (time1 >= time2) then ... endif + OR + result = (time1 >= time2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time1 + type(ESMF_Time), intent(in) :: time2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (>=) operator for the ESMF_Time class to return + .true. if time1 is later in time or the same time as + time2, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_TimeGet(time, & + yy, yy_i8, & + mm, dd, & + d, d_i8, & + h, m, & + s, s_i8, & + ms, us, ns, & + d_r8, h_r8, m_r8, s_r8, & + ms_r8, us_r8, ns_r8, & + sN, sN_i8, sD, sD_i8, & + calendar, calkindflag, timeZone, & + timeString, timeStringISOFrac, & + dayOfWeek, midMonth, & + dayOfYear, dayOfYear_r8, & + dayOfYear_intvl, rc) +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(out), optional :: yy + integer(ESMF_KIND_I8), intent(out), optional :: yy_i8 + integer, intent(out), optional :: mm + integer, intent(out), optional :: dd + integer(ESMF_KIND_I4), intent(out), optional :: d + integer(ESMF_KIND_I8), intent(out), optional :: d_i8 + integer(ESMF_KIND_I4), intent(out), optional :: h + integer(ESMF_KIND_I4), intent(out), optional :: m + integer(ESMF_KIND_I4), intent(out), optional :: s + integer(ESMF_KIND_I8), intent(out), optional :: s_i8 + integer(ESMF_KIND_I4), intent(out), optional :: ms + integer(ESMF_KIND_I4), intent(out), optional :: us + integer(ESMF_KIND_I4), intent(out), optional :: ns + real(ESMF_KIND_R8), intent(out), optional :: d_r8 + real(ESMF_KIND_R8), intent(out), optional :: h_r8 + real(ESMF_KIND_R8), intent(out), optional :: m_r8 + real(ESMF_KIND_R8), intent(out), optional :: s_r8 + real(ESMF_KIND_R8), intent(out), optional :: ms_r8 + real(ESMF_KIND_R8), intent(out), optional :: us_r8 + real(ESMF_KIND_R8), intent(out), optional :: ns_r8 + integer(ESMF_KIND_I4), intent(out), optional :: sN + integer(ESMF_KIND_I8), intent(out), optional :: sN_i8 + integer(ESMF_KIND_I4), intent(out), optional :: sD + integer(ESMF_KIND_I8), intent(out), optional :: sD_i8 + type(ESMF_Calendar), intent(out), optional :: calendar + type(ESMF_CalKind_Flag), intent(out), optional :: calkindflag + integer, intent(out), optional :: timeZone ! not imp + character (len=*), intent(out), optional :: timeString + character (len=*), intent(out), optional :: timeStringISOFrac + integer, intent(out), optional :: dayOfWeek + type(ESMF_Time), intent(out), optional :: midMonth + integer(ESMF_KIND_I4), intent(out), optional :: dayOfYear + real(ESMF_KIND_R8), intent(out), optional :: dayOfYear_r8 + type(ESMF_TimeInterval), intent(out), optional :: dayOfYear_intvl + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets the value of time in units specified by the user + via Fortran optional arguments. See ESMF_TimeSet() above for a + description of time units and calendars. + +
+The ESMF Time Manager represents and manipulates time internally with + integers to maintain precision. Hence, user-specified floating point + values are converted internally from integers. For example, if a time + value is 5 and 3/8 seconds (s=5, sN=3, sD=8), and you want to get it as + floating point seconds, you would get 5.375 (s_r8=5.375). + +
+Units are bound (normalized) by the next larger unit specified. For + example, if a time is defined to be 2:00 am on February 2, 2004, then + ESMF_TimeGet(dd=day, h=hours, s=seconds) would return + day = 2, hours = 2, seconds = 0, + whereas ESMF_TimeGet(dd = day, s=seconds) would return + day = 2, seconds = 7200. + Note that hours and seconds are bound by a day. If bound + by a month, + ESMF_TimeGet(mm=month, h=hours, s=seconds) would return + month = 2, hours = 26, seconds = 0, + and ESMF_TimeGet(mm = month, s=seconds) would return + month = 2, seconds = 93600 (26 * 3600). + Similarly, if bound to a year, + ESMF_TimeGet(yy=year, h=hours, s=seconds) would return + year = 2004, hours = 770 (32*24 + 2), seconds = 0, + and ESMF_TimeGet(yy = year, s=seconds) would return + year = 2004, seconds = 2772000 (770 * 3600). + +
+For timeString, timeStringISOFrac, dayOfWeek,
+ midMonth, dayOfYear, dayOfYear_intvl, and
+ dayOfYear_r8 described below, valid calendars are Gregorian,
+ Julian, No Leap, 360 Day and Custom calendars. Not valid for
+ Julian Day, Modified Julian Day, or No Calendar.
+
+
+For timeString and timeStringISOFrac, YYYY format returns + at least 4 digits; years <= 999 are padded on the left with zeroes and + years >= 10000 return the number of digits required. + +
+For timeString, convert ESMF_Time's value into partial ISO 8601 + format YYYY-MM-DDThh:mm:ss[:n/d]. See [24] and [14]. + See also method ESMF_TimePrint(). + +
+For timeStringISOFrac, convert ESMF_Time's value into full ISO 8601 + format YYYY-MM-DDThh:mm:ss[.f]. See [24] and [14]. + See also method ESMF_TimePrint(). + +
+For dayOfWeek, gets the day of the week the given ESMF_Time + instant falls on. ISO 8601 standard: Monday = 1 through Sunday = 7. + See [24] and [14]. + +
+For midMonth, gets the middle time instant of the month that the given + ESMF_Time instant falls on. + +
+For dayOfYear, gets the day of the year that the given ESMF_Time + instant falls on. See range discussion in argument list below. + Return as an integer value. + +
+For dayOfYear_r8, gets the day of the year the given ESMF_Time + instant falls on. See range discussion in argument list below. + Return as floating point value; fractional part represents the time of + day. + +
+For dayOfYear_intvl, gets the day of the year the given ESMF_Time + instant falls on. Return as an ESMF_TimeInterval. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_TimeIsLeapYear(time, rc) +RETURN VALUE: +
logical :: ESMF_TimeIsLeapYear +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns .true. if given time is in a leap year, and .false. + otherwise. See also ESMF_CalendarIsLeapYear(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_TimeIsSameCalendar(time1, time2, rc) +RETURN VALUE: +
logical :: ESMF_TimeIsSameCalendar +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time1 + type(ESMF_Time), intent(in) :: time2 + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns .true. if the Calendars in these Times are + the same, .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_TimePrint(time, options, preString, unit, rc) +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len=*), intent(in), optional :: options + character(*), intent(in), optional :: preString + character(*), intent(out), optional :: unit + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Prints out the contents of an ESMF_Time to stdout, in
+ support of testing and debugging. The options control the type of
+ information and level of detail. For options "string" and "string
+ isofrac", YYYY format returns at least 4 digits; years <= 999 are
+ padded on the left with zeroes and years >= 10000 return the number
+ of digits required.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeSet() + subroutine ESMF_TimeSetDefault(time, & + yy, yy_i8, & + mm, dd, & + d, d_i8, & + h, m, & + s, s_i8, & + ms, us, ns, & + d_r8, h_r8, m_r8, s_r8, & + ms_r8, us_r8, ns_r8, & + sN, sN_i8, sD, sD_i8, & + calendar, calkindflag, & + timeZone, rc) +ARGUMENTS: +
type(ESMF_Time), intent(inout) :: time + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(in), optional :: yy + integer(ESMF_KIND_I8), intent(in), optional :: yy_i8 + integer, intent(in), optional :: mm + integer, intent(in), optional :: dd + integer(ESMF_KIND_I4), intent(in), optional :: d + integer(ESMF_KIND_I8), intent(in), optional :: d_i8 + integer(ESMF_KIND_I4), intent(in), optional :: h + integer(ESMF_KIND_I4), intent(in), optional :: m + integer(ESMF_KIND_I4), intent(in), optional :: s + integer(ESMF_KIND_I8), intent(in), optional :: s_i8 + integer(ESMF_KIND_I4), intent(in), optional :: ms + integer(ESMF_KIND_I4), intent(in), optional :: us + integer(ESMF_KIND_I4), intent(in), optional :: ns + real(ESMF_KIND_R8), intent(in), optional :: d_r8 + real(ESMF_KIND_R8), intent(in), optional :: h_r8 + real(ESMF_KIND_R8), intent(in), optional :: m_r8 + real(ESMF_KIND_R8), intent(in), optional :: s_r8 + real(ESMF_KIND_R8), intent(in), optional :: ms_r8 + real(ESMF_KIND_R8), intent(in), optional :: us_r8 + real(ESMF_KIND_R8), intent(in), optional :: ns_r8 + integer(ESMF_KIND_I4), intent(in), optional :: sN + integer(ESMF_KIND_I8), intent(in), optional :: sN_i8 + integer(ESMF_KIND_I4), intent(in), optional :: sD + integer(ESMF_KIND_I8), intent(in), optional :: sD_i8 + type(ESMF_Calendar), intent(in), optional :: calendar + type(ESMF_CalKind_Flag), intent(in), optional :: calkindflag + integer, intent(in), optional :: timeZone ! not imp + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Initializes an ESMF_Time with a set of user-specified units + via Fortran optional arguments. + +
+The range of valid values for mm and dd depend on the calendar used. + For Gregorian, Julian, and No-Leap calendars, mm is [1-12] and dd is + [1-28,29,30, or 31], depending on the value of mm and whether yy or + yy_i8 is a leap year. For the 360-day calendar, mm is [1-12] and dd is + [1-30]. For Julian Day, Modified Julian Day, and No-Calendar, + yy, yy_i8, mm, and dd are invalid inputs, since these calendars do not + define them. When valid, the yy and yy_i8 arguments should be fully + specified, e.g. 2003 instead of 03. yy and yy_i8 ranges are only + limited by machine word size, except for the Gregorian and Julian + calendars, where the lowest (proleptic) date limits are 3/1/-4800 and + 3/1/-4712, respectively. This is a limitation of the Gregorian + date-to-Julian day and Julian date-to-Julian day conversion algorithms + used to convert Gregorian and Julian dates to the internal representation + of seconds. See [21] for a description of the Gregorian + date-to-Julian day algorithm and [23] for a description of the + Julian date-to-Julian day algorithm. The Custom calendar will have + user-defined values for yy, yy_i8, mm, and dd. + +
+The Julian day specifier, d or d_i8, can only be used with the + Julian Day and Modified Julian Day calendars, and has a valid range + depending on the word size. For a signed 32-bit d, the range for + Julian day is [+/- 24855]. For a signed 64-bit d_i8, the valid + range for Julian day is [+/- 106,751,991,167,300]. The Julian day + number system adheres to the conventional standard where the reference + day of d=0 corresponds to 11/24/-4713 in the proleptic Gregorian calendar + and 1/1/-4712 in the proleptic Julian calendar. See [27] and + [12]. + +
+The Modified Julian Day system, introduced by space scientists in the late + 1950's, is defined as Julian Day - 2400000.5. See [31]. + +
+Note that d and d_i8 are not valid for the No-Calendar. To remain + consistent with non-Earth calendars added to ESMF in the future, ESMF + requires a calendar to be planet-specific. Hence the No-Calendar does + not know what a day is; it cannot assume an Earth day of 86400 seconds. + +
+Hours, minutes, seconds, and sub-seconds can be used with any calendar, + since they are standardized units that are the same for any planet. + +
+Time manager represents and manipulates time internally with integers + to maintain precision. Hence, user-specified floating point values are + converted internally to integers. Sub-second values are represented + internally with an integer numerator and denominator fraction (sN/sD). + The smallest required resolution is nanoseconds (denominator). + For example, pi can be represented as s=3, + sN=141592654, sD=1000000000. However, via sN_i8 and sD_i8, larger + values can be used. If specifying a constant floating point value, be + sure to provide at least 16 digits to take full advantage of double + precision, for example s_r8=2.718281828459045d0 for 'e' seconds. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeSet() + subroutine ESMF_TimeSetString(time, timeString, rc) +ARGUMENTS: +
type(ESMF_Time), intent(inout) :: time + character(*), intent(in) :: timeString + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Initializes an ESMF_Time with a set of user-specified string. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_TimeSyncToRealTime(time, rc) +ARGUMENTS: +
type(ESMF_Time), intent(inout) :: time + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets the system real time (wall clock time), and returns it as an + ESMF_Time. Accurate to the nearest second. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_TimeValidate(time, options, rc) +ARGUMENTS: +
type(ESMF_Time), intent(in) :: time + character (len=*), intent(in), optional :: options + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Checks whether an ESMF_Time is valid. + Must be a valid date/time on a valid calendar. + The options control the type of validation. + +
+The arguments are: +
+ + +
+There are TimeInterval methods defined for setting and getting +a TimeInterval, for incrementing and decrementing a TimeInterval +by another TimeInterval, and for multiplying and dividing +TimeIntervals by integers, reals, fractions and other TimeIntervals. +Methods are also defined to take the absolute value and negative +absolute value of a TimeInterval, and for comparing the length of two +TimeIntervals. + +
+The class used to represent time instants in ESMF is Time, +and this class is frequently used in operations along with +TimeIntervals. For example, the difference between two +Times is a TimeInterval. + +
+When a TimeInterval is used in calculations that involve an absolute +reference time, such as incrementing a Time with a TimeInterval, calendar +dependencies may be introduced. The length of the time period that the +TimeInterval represents will depend on the reference Time and the +standard calendar that is associated with it. The calendar dependency becomes +apparent when, for example, adding a TimeInterval of 1 day to the Time +of February 28, 1996, at 4:00pm EST. In a 360 day calendar, the +resulting date would be February 29, 1996, at 4:00pm EST. In a no-leap +calendar, the result would be March 1, 1996, at 4:00pm EST. + +
+TimeIntervals are used by other parts of the ESMF timekeeping +system, such as Clocks (Section 45.1) and Alarms +(Section 46.1). + +
+ +
+A typical use for a TimeInterval in a geophysical model +is representation of the time step by which the model is +advanced. Some models change the size of their time step as +the model run progresses; this could +be done by incrementing or decrementing the original time +step by another TimeInterval, or by dividing or multiplying +the time step by an integer value. An example of advancing +model time using a TimeInterval representation of a time +step is shown in Section 45.1. + +
+The following brief example shows how to create, initialize +and manipulate TimeInterval. + +
+ +
+ +
+ +
+
+! !PROGRAM: ESMF_TimeIntervalEx - Time Interval initialization and +! manipulation examples +! +! !DESCRIPTION: +! +! This program shows examples of Time Interval initialization and manipulation +!----------------------------------------------------------------------------- +#include "ESMF.h" + + ! ESMF Framework module + use ESMF + use ESMF_TestMod + implicit none + + ! instantiate some time intervals + type(ESMF_TimeInterval) :: timeinterval1, timeinterval2, timeinterval3 + + ! local variables + integer :: d, h, m, s + + ! return code + integer:: rc ++ +
+
+ ! initialize ESMF framework + call ESMF_Initialize(defaultCalKind=ESMF_CALKIND_GREGORIAN, & + defaultlogfilename="TimeIntervalEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+ +
+This example shows how to initialize two ESMF_TimeIntervals. +
+
+ ! initialize time interval1 to 1 day + call ESMF_TimeIntervalSet(timeinterval1, d=1, rc=rc) ++ +
+
+ call ESMF_TimeIntervalPrint(timeinterval1, options="string", rc=rc) ++ +
+
+ ! initialize time interval2 to 4 days, 1 hour, 30 minutes, 10 seconds + call ESMF_TimeIntervalSet(timeinterval2, d=4, h=1, m=30, s=10, rc=rc) ++ +
+
+ call ESMF_TimeIntervalPrint(timeinterval2, options="string", rc=rc) ++ +
+ +
+This example shows how to convert ESMF_TimeIntervals into + different units. +
+
+ call ESMF_TimeIntervalGet(timeinterval1, s=s, rc=rc) + print *, "Time Interval1 = ", s, " seconds." ++ +
+
+ call ESMF_TimeIntervalGet(timeinterval2, h=h, m=m, s=s, rc=rc) + print *, "Time Interval2 = ", h, " hours, ", m, " minutes, ", & + s, " seconds." ++ +
+ +
+This example shows how to calculate the difference between two + ESMF_TimeIntervals. +
+
+ ! difference between two time intervals + timeinterval3 = timeinterval2 - timeinterval1 + call ESMF_TimeIntervalGet(timeinterval3, d=d, h=h, m=m, s=s, rc=rc) + print *, "Difference between TimeInterval2 and TimeInterval1 = ", & + d, " days, ", h, " hours, ", m, " minutes, ", s, " seconds." ++ +
+ +
+This example shows how to multiply an ESMF_TimeInterval. +
+
+ ! multiply time interval by an integer + timeinterval3 = timeinterval2 * 3 + call ESMF_TimeIntervalGet(timeinterval3, d=d, h=h, m=m, s=s, rc=rc) + print *, "TimeInterval2 multiplied by 3 = ", d, " days, ", h, & + " hours, ", m, " minutes, ", s, " seconds." ++ +
+ +
+This example shows how to compare two ESMF_TimeIntervals. +
+
+ ! comparison + if (timeinterval1 < timeinterval2) then + print *, "TimeInterval1 is smaller than TimeInterval2" + else + print *, "TimeInterval1 is larger than or equal to TimeInterval2" + end if ++ +
+
+ end program ESMF_TimeIntervalEx ++ +
+ + +
+ +
+For fractional seconds, a signed 64-bit integer will handle a resolution of ++/- -1, or +/- 9,223,372,036,854,775,807 parts of a second. + +
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + timeinterval1 = timeinterval2 +ARGUMENTS: +
type(ESMF_TimeInterval) :: timeinterval1 + type(ESMF_TimeInterval) :: timeinterval2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Set timeinterval1 equal to timeinterval2. This is the default + Fortran assignment, which creates a complete, independent copy of + timeinterval2 as timeinterval1. If timeinterval2 is an + invalid ESMF_TimeInterval object then timeinterval1 will be + equally invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(+) + sum = timeinterval1 + timeinterval2 +RETURN VALUE: +
type(ESMF_TimeInterval) :: sum +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval1 + type(ESMF_TimeInterval), intent(in) :: timeinterval2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (+) operator for the ESMF_TimeInterval class to + add timeinterval1 to timeinterval2 and return the + sum as an ESMF_TimeInterval. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(-) + difference = timeinterval1 - timeinterval2 +RETURN VALUE: +
type(ESMF_TimeInterval) :: difference +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval1 + type(ESMF_TimeInterval), intent(in) :: timeinterval2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (-) operator for the ESMF_TimeInterval class to + subtract timeinterval2 from timeinterval1 and return + the difference as an ESMF_TimeInterval. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(-) + timeinterval = -timeinterval +RETURN VALUE: +
type(ESMF_TimeInterval) :: -timeInterval +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (-) operator for the ESMF_TimeInterval class to + perform unary negation on timeinterval and return the result. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/) + quotient = timeinterval1 / timeinterval2 +RETURN VALUE: +
real(ESMF_KIND_R8) :: quotient +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval1 + type(ESMF_TimeInterval), intent(in) :: timeinterval2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (/) operator for the ESMF_TimeInterval class to + return timeinterval1 divided by timeinterval2 as a + double precision quotient. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/) + quotient = timeinterval / divisor +RETURN VALUE: +
type(ESMF_TimeInterval) :: quotient +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval + integer(ESMF_KIND_I4), intent(in) :: divisor ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (/) operator for the ESMF_TimeInterval class to + divide a timeinterval by an integer divisor, and + return the quotient as an ESMF_TimeInterval. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface MOD + function MOD(timeinterval1, timeinterval2) +RETURN VALUE: +
type(ESMF_TimeInterval) :: MOD +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval1 + type(ESMF_TimeInterval), intent(in) :: timeinterval2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the Fortran intrinsic MOD() function for the + ESMF_TimeInterval class to return the remainder of + timeinterval1 divided by timeinterval2 as an + ESMF_TimeInterval. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(*) + product = timeinterval * multiplier + OR + product = multiplier * timeinterval +RETURN VALUE: +
type(ESMF_TimeInterval) :: product +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval + integer(ESMF_KIND_I4), intent(in) :: multiplier ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (*) operator for the ESMF_TimeInterval class to + multiply a timeinterval by an integer multiplier, + and return the product as an ESMF_TimeInterval. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (timeinterval1 == timeinterval2) then ... endif + OR + result = (timeinterval1 == timeinterval2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval1 + type(ESMF_TimeInterval), intent(in) :: timeinterval2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (==) operator for the ESMF_TimeInterval class to + return .true. if timeinterval1 and timeinterval2 + represent an equal duration of time, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (timeinterval1 /= timeinterval2) then ... endif + OR + result = (timeinterval1 /= timeinterval2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval1 + type(ESMF_TimeInterval), intent(in) :: timeinterval2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (/=) operator for the ESMF_TimeInterval class to + return .true. if timeinterval1 and timeinterval2 do not + represent an equal duration of time, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(<) + if (timeinterval1 < timeinterval2) then ... endif + OR + result = (timeinterval1 < timeinterval2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval1 + type(ESMF_TimeInterval), intent(in) :: timeinterval2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (<) operator for the ESMF_TimeInterval class to + return .true. if timeinterval1 is a lesser duration of time + than timeinterval2, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(<=) + if (timeinterval1 <= timeinterval2) then ... endif + OR + result = (timeinterval1 <= timeinterval2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval1 + type(ESMF_TimeInterval), intent(in) :: timeinterval2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (<=) operator for the ESMF_TimeInterval class to + return .true. if timeinterval1 is a lesser or equal duration + of time than timeinterval2, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(>) + if (timeinterval1 > timeinterval2) then ... endif + OR + result = (timeinterval1 > timeinterval2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval1 + type(ESMF_TimeInterval), intent(in) :: timeinterval2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (>) operator for the ESMF_TimeInterval class to + return .true. if timeinterval1 is a greater duration of time + than timeinterval2, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(>=) + if (timeinterval1 >= timeinterval2) then ... endif + OR + result = (timeinterval1 >= timeinterval2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval1 + type(ESMF_TimeInterval), intent(in) :: timeinterval2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Overloads the (>=) operator for the ESMF_TimeInterval class to + return .true. if timeinterval1 is a greater or equal + duration of time than timeinterval2, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_TimeIntervalAbsValue(timeinterval) +RETURN VALUE: +
type(ESMF_TimeInterval) :: ESMF_TimeIntervalAbsValue +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns the absolute value of timeinterval. + +
+The argument is: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeIntervalGet() + subroutine ESMF_TimeIntervalGetDur(timeinterval, & + yy, yy_i8, & + mm, mm_i8, & + d, d_i8, & + h, m, & + s, s_i8, & + ms, us, ns, & + d_r8, h_r8, m_r8, s_r8, & + ms_r8, us_r8, ns_r8, & + sN, sN_i8, sD, sD_i8, & + startTime, calendar, calkindflag, & + timeString, timeStringISOFrac, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(out), optional :: yy + integer(ESMF_KIND_I8), intent(out), optional :: yy_i8 + integer(ESMF_KIND_I4), intent(out), optional :: mm + integer(ESMF_KIND_I8), intent(out), optional :: mm_i8 + integer(ESMF_KIND_I4), intent(out), optional :: d + integer(ESMF_KIND_I8), intent(out), optional :: d_i8 + integer(ESMF_KIND_I4), intent(out), optional :: h + integer(ESMF_KIND_I4), intent(out), optional :: m + integer(ESMF_KIND_I4), intent(out), optional :: s + integer(ESMF_KIND_I8), intent(out), optional :: s_i8 + integer(ESMF_KIND_I4), intent(out), optional :: ms + integer(ESMF_KIND_I4), intent(out), optional :: us + integer(ESMF_KIND_I4), intent(out), optional :: ns + real(ESMF_KIND_R8), intent(out), optional :: d_r8 + real(ESMF_KIND_R8), intent(out), optional :: h_r8 + real(ESMF_KIND_R8), intent(out), optional :: m_r8 + real(ESMF_KIND_R8), intent(out), optional :: s_r8 + real(ESMF_KIND_R8), intent(out), optional :: ms_r8 + real(ESMF_KIND_R8), intent(out), optional :: us_r8 + real(ESMF_KIND_R8), intent(out), optional :: ns_r8 + integer(ESMF_KIND_I4), intent(out), optional :: sN + integer(ESMF_KIND_I8), intent(out), optional :: sN_i8 + integer(ESMF_KIND_I4), intent(out), optional :: sD + integer(ESMF_KIND_I8), intent(out), optional :: sD_i8 + type(ESMF_Time), intent(out), optional :: startTime + type(ESMF_Calendar), intent(out), optional :: calendar + type(ESMF_CalKind_Flag), intent(out), optional :: calkindflag + character (len=*), intent(out), optional :: timeString + character (len=*), intent(out), optional :: timeStringISOFrac + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets the value of timeinterval in units specified by the + user via Fortran optional arguments. + +
+The ESMF Time Manager represents and manipulates time internally with + integers to maintain precision. Hence, user-specified floating point + values are converted internally from integers. + +
+Units are bound (normalized) to the next larger unit specified. For + example, if a time interval is defined to be one day, then + ESMF_TimeIntervalGet(d = days, s = seconds) would return + days = 1, seconds = 0, + whereas ESMF_TimeIntervalGet(s = seconds) would return + seconds = 86400. + +
+For timeString, converts ESMF_TimeInterval's value into + partial ISO 8601 format PyYmMdDThHmMs[:n/d]S. See [24] and + [14]. See also method ESMF_TimeIntervalPrint(). + +
+For timeStringISOFrac, converts ESMF_TimeInterval's value into + full ISO 8601 format PyYmMdDThHmMs[.f]S. See [24] and + [14]. See also method ESMF_TimeIntervalPrint(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeIntervalGet() + subroutine ESMF_TimeIntervalGetDurStart(timeinterval, startTimeIn, & + & + yy, yy_i8, & + mm, mm_i8, & + d, d_i8, & + h, m, & + s, s_i8, & + ms, us, ns, & + d_r8, h_r8, m_r8, s_r8, & + ms_r8, us_r8, ns_r8, & + sN, sN_i8, sD, sD_i8, & + startTime, & + calendar, calkindflag, & + timeString, timeStringISOFrac, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval + type(ESMF_Time), intent(in) :: startTimeIn ! Input + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(out), optional :: yy + integer(ESMF_KIND_I8), intent(out), optional :: yy_i8 + integer(ESMF_KIND_I4), intent(out), optional :: mm + integer(ESMF_KIND_I8), intent(out), optional :: mm_i8 + integer(ESMF_KIND_I4), intent(out), optional :: d + integer(ESMF_KIND_I8), intent(out), optional :: d_i8 + integer(ESMF_KIND_I4), intent(out), optional :: h + integer(ESMF_KIND_I4), intent(out), optional :: m + integer(ESMF_KIND_I4), intent(out), optional :: s + integer(ESMF_KIND_I8), intent(out), optional :: s_i8 + integer(ESMF_KIND_I4), intent(out), optional :: ms + integer(ESMF_KIND_I4), intent(out), optional :: us + integer(ESMF_KIND_I4), intent(out), optional :: ns + real(ESMF_KIND_R8), intent(out), optional :: d_r8 + real(ESMF_KIND_R8), intent(out), optional :: h_r8 + real(ESMF_KIND_R8), intent(out), optional :: m_r8 + real(ESMF_KIND_R8), intent(out), optional :: s_r8 + real(ESMF_KIND_R8), intent(out), optional :: ms_r8 + real(ESMF_KIND_R8), intent(out), optional :: us_r8 + real(ESMF_KIND_R8), intent(out), optional :: ns_r8 + integer(ESMF_KIND_I4), intent(out), optional :: sN + integer(ESMF_KIND_I8), intent(out), optional :: sN_i8 + integer(ESMF_KIND_I4), intent(out), optional :: sD + integer(ESMF_KIND_I8), intent(out), optional :: sD_i8 + type(ESMF_Time), intent(out), optional :: startTime + type(ESMF_Calendar), intent(out), optional :: calendar + type(ESMF_CalKind_Flag), intent(out), optional :: calkindflag + character (len=*), intent(out), optional :: timeString + character (len=*), intent(out), optional :: timeStringISOFrac + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets the value of timeinterval in units specified by the + user via Fortran optional arguments. + +
+The ESMF Time Manager represents and manipulates time internally with + integers to maintain precision. Hence, user-specified floating point + values are converted internally from integers. + +
+Units are bound (normalized) to the next larger unit specified. For + example, if a time interval is defined to be one day, then + ESMF_TimeIntervalGet(d = days, s = seconds) would return + days = 1, seconds = 0, + whereas ESMF_TimeIntervalGet(s = seconds) would return + seconds = 86400. + +
+For timeString, converts ESMF_TimeInterval's value into + partial ISO 8601 format PyYmMdDThHmMs[:n/d]S. See [24] and + [14]. See also method ESMF_TimeIntervalPrint(). + +
+For timeStringISOFrac, converts ESMF_TimeInterval's value into + full ISO 8601 format PyYmMdDThHmMs[.f]S. See [24] and + [14]. See also method ESMF_TimeIntervalPrint(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeIntervalGet() + subroutine ESMF_TimeIntervalGetDurCal(timeinterval, calendarIn, & + & + yy, yy_i8, & + mm, mm_i8, & + d, d_i8, & + h, m, & + s, s_i8, & + ms, us, ns, & + d_r8, h_r8, m_r8, s_r8, & + ms_r8, us_r8, ns_r8, & + sN, sN_i8, sD, sD_i8, & + startTime, & + calendar, calkindflag, & + timeString, timeStringISOFrac, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval + type(ESMF_Calendar), intent(in) :: calendarIn ! Input + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(out), optional :: yy + integer(ESMF_KIND_I8), intent(out), optional :: yy_i8 + integer(ESMF_KIND_I4), intent(out), optional :: mm + integer(ESMF_KIND_I8), intent(out), optional :: mm_i8 + integer(ESMF_KIND_I4), intent(out), optional :: d + integer(ESMF_KIND_I8), intent(out), optional :: d_i8 + integer(ESMF_KIND_I4), intent(out), optional :: h + integer(ESMF_KIND_I4), intent(out), optional :: m + integer(ESMF_KIND_I4), intent(out), optional :: s + integer(ESMF_KIND_I8), intent(out), optional :: s_i8 + integer(ESMF_KIND_I4), intent(out), optional :: ms + integer(ESMF_KIND_I4), intent(out), optional :: us + integer(ESMF_KIND_I4), intent(out), optional :: ns + real(ESMF_KIND_R8), intent(out), optional :: d_r8 + real(ESMF_KIND_R8), intent(out), optional :: h_r8 + real(ESMF_KIND_R8), intent(out), optional :: m_r8 + real(ESMF_KIND_R8), intent(out), optional :: s_r8 + real(ESMF_KIND_R8), intent(out), optional :: ms_r8 + real(ESMF_KIND_R8), intent(out), optional :: us_r8 + real(ESMF_KIND_R8), intent(out), optional :: ns_r8 + integer(ESMF_KIND_I4), intent(out), optional :: sN + integer(ESMF_KIND_I8), intent(out), optional :: sN_i8 + integer(ESMF_KIND_I4), intent(out), optional :: sD + integer(ESMF_KIND_I8), intent(out), optional :: sD_i8 + type(ESMF_Time), intent(out), optional :: startTime + type(ESMF_Calendar), intent(out), optional :: calendar + type(ESMF_CalKind_Flag), intent(out), optional :: calkindflag + character (len=*), intent(out), optional :: timeString + character (len=*), intent(out), optional :: timeStringISOFrac + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets the value of timeinterval in units specified by the + user via Fortran optional arguments. + +
+The ESMF Time Manager represents and manipulates time internally with + integers to maintain precision. Hence, user-specified floating point + values are converted internally from integers. + +
+Units are bound (normalized) to the next larger unit specified. For + example, if a time interval is defined to be one day, then + ESMF_TimeIntervalGet(d = days, s = seconds) would return + days = 1, seconds = 0, + whereas ESMF_TimeIntervalGet(s = seconds) would return + seconds = 86400. + +
+For timeString, converts ESMF_TimeInterval's value into + partial ISO 8601 format PyYmMdDThHmMs[:n/d]S. See [24] and + [14]. See also method ESMF_TimeIntervalPrint(). + +
+For timeStringISOFrac, converts ESMF_TimeInterval's value into + full ISO 8601 format PyYmMdDThHmMs[.f]S. See [24] and + [14]. See also method ESMF_TimeIntervalPrint(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeIntervalGet() + subroutine ESMF_TimeIntervalGetDurCalTyp(timeinterval, calkindflagIn, & + & + yy, yy_i8, & + mm, mm_i8, & + d, d_i8, & + h, m, & + s, s_i8, & + ms, us, ns, & + d_r8, h_r8, m_r8, s_r8, & + ms_r8, us_r8, ns_r8, & + sN, sN_i8, sD, sD_i8, & + startTime, & + calendar, calkindflag, & + timeString, & + timeStringISOFrac, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval + type(ESMF_CalKind_Flag), intent(in) :: calkindflagIn ! Input + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(out), optional :: yy + integer(ESMF_KIND_I8), intent(out), optional :: yy_i8 + integer(ESMF_KIND_I4), intent(out), optional :: mm + integer(ESMF_KIND_I8), intent(out), optional :: mm_i8 + integer(ESMF_KIND_I4), intent(out), optional :: d + integer(ESMF_KIND_I8), intent(out), optional :: d_i8 + integer(ESMF_KIND_I4), intent(out), optional :: h + integer(ESMF_KIND_I4), intent(out), optional :: m + integer(ESMF_KIND_I4), intent(out), optional :: s + integer(ESMF_KIND_I8), intent(out), optional :: s_i8 + integer(ESMF_KIND_I4), intent(out), optional :: ms + integer(ESMF_KIND_I4), intent(out), optional :: us + integer(ESMF_KIND_I4), intent(out), optional :: ns + real(ESMF_KIND_R8), intent(out), optional :: d_r8 + real(ESMF_KIND_R8), intent(out), optional :: h_r8 + real(ESMF_KIND_R8), intent(out), optional :: m_r8 + real(ESMF_KIND_R8), intent(out), optional :: s_r8 + real(ESMF_KIND_R8), intent(out), optional :: ms_r8 + real(ESMF_KIND_R8), intent(out), optional :: us_r8 + real(ESMF_KIND_R8), intent(out), optional :: ns_r8 + integer(ESMF_KIND_I4), intent(out), optional :: sN + integer(ESMF_KIND_I8), intent(out), optional :: sN_i8 + integer(ESMF_KIND_I4), intent(out), optional :: sD + integer(ESMF_KIND_I8), intent(out), optional :: sD_i8 + type(ESMF_Time), intent(out), optional :: startTime + type(ESMF_Calendar), intent(out), optional :: calendar + type(ESMF_CalKind_Flag), intent(out), optional :: calkindflag + character (len=*), intent(out), optional :: timeString + character (len=*), intent(out), optional :: timeStringISOFrac + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets the value of timeinterval in units specified by the + user via Fortran optional arguments. + +
+The ESMF Time Manager represents and manipulates time internally with + integers to maintain precision. Hence, user-specified floating point + values are converted internally from integers. + +
+Units are bound (normalized) to the next larger unit specified. For + example, if a time interval is defined to be one day, then + ESMF_TimeIntervalGet(d = days, s = seconds) would return + days = 1, seconds = 0, + whereas ESMF_TimeIntervalGet(s = seconds) would return + seconds = 86400. + +
+For timeString, converts ESMF_TimeInterval's value into + partial ISO 8601 format PyYmMdDThHmMs[:n/d]S. See [24] and + [14]. See also method ESMF_TimeIntervalPrint(). + +
+For timeStringISOFrac, converts ESMF_TimeInterval's value into + full ISO 8601 format PyYmMdDThHmMs[.f]S. See [24] and + [14]. See also method ESMF_TimeIntervalPrint(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_TimeIntervalNegAbsValue(timeinterval) +RETURN VALUE: +
type(ESMF_TimeInterval) :: ESMF_TimeIntervalNegAbsValue +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns the negative absolute value of timeinterval. + +
+The argument is: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_TimeIntervalPrint(timeinterval, options, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval + character (len=*), intent(in), optional :: options + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Prints out the contents of an ESMF_TimeInterval to stdout,
+ in support of testing and debugging. The options control the type of
+ information and level of detail.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeIntervalSet() + subroutine ESMF_TimeIntervalSetDur(timeinterval, & + yy, yy_i8, & + mm, mm_i8, & + d, d_i8, & + h, m, & + s, s_i8, & + ms, us, ns, & + d_r8, h_r8, m_r8, s_r8, & + ms_r8, us_r8, ns_r8, & + sN, sN_i8, sD, sD_i8, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(inout) :: timeinterval + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(in), optional :: yy + integer(ESMF_KIND_I8), intent(in), optional :: yy_i8 + integer(ESMF_KIND_I4), intent(in), optional :: mm + integer(ESMF_KIND_I8), intent(in), optional :: mm_i8 + integer(ESMF_KIND_I4), intent(in), optional :: d + integer(ESMF_KIND_I8), intent(in), optional :: d_i8 + integer(ESMF_KIND_I4), intent(in), optional :: h + integer(ESMF_KIND_I4), intent(in), optional :: m + integer(ESMF_KIND_I4), intent(in), optional :: s + integer(ESMF_KIND_I8), intent(in), optional :: s_i8 + integer(ESMF_KIND_I4), intent(in), optional :: ms + integer(ESMF_KIND_I4), intent(in), optional :: us + integer(ESMF_KIND_I4), intent(in), optional :: ns + real(ESMF_KIND_R8), intent(in), optional :: d_r8 + real(ESMF_KIND_R8), intent(in), optional :: h_r8 + real(ESMF_KIND_R8), intent(in), optional :: m_r8 + real(ESMF_KIND_R8), intent(in), optional :: s_r8 + real(ESMF_KIND_R8), intent(in), optional :: ms_r8 + real(ESMF_KIND_R8), intent(in), optional :: us_r8 + real(ESMF_KIND_R8), intent(in), optional :: ns_r8 + integer(ESMF_KIND_I4), intent(in), optional :: sN + integer(ESMF_KIND_I8), intent(in), optional :: sN_i8 + integer(ESMF_KIND_I4), intent(in), optional :: sD + integer(ESMF_KIND_I8), intent(in), optional :: sD_i8 + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets the value of the ESMF_TimeInterval in units specified by + the user via Fortran optional arguments. + +
+The ESMF Time Manager represents and manipulates time internally with + integers to maintain precision. Hence, user-specified floating point + values are converted internally to integers. + +
+Ranges are limited only by machine word size. Numeric defaults are 0, + except for sD, which is 1. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeIntervalSet() + subroutine ESMF_TimeIntervalSetDurStart(timeinterval, startTime, & + & + yy, yy_i8, & + mm, mm_i8, & + d, d_i8, & + h, m, & + s, s_i8, & + ms, us, ns, & + d_r8, h_r8, m_r8, s_r8, & + ms_r8, us_r8, ns_r8, & + sN, sN_i8, sD, sD_i8, & + rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(inout) :: timeinterval + type(ESMF_Time), intent(in) :: startTime + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(in), optional :: yy + integer(ESMF_KIND_I8), intent(in), optional :: yy_i8 + integer(ESMF_KIND_I4), intent(in), optional :: mm + integer(ESMF_KIND_I8), intent(in), optional :: mm_i8 + integer(ESMF_KIND_I4), intent(in), optional :: d + integer(ESMF_KIND_I8), intent(in), optional :: d_i8 + integer(ESMF_KIND_I4), intent(in), optional :: h + integer(ESMF_KIND_I4), intent(in), optional :: m + integer(ESMF_KIND_I4), intent(in), optional :: s + integer(ESMF_KIND_I8), intent(in), optional :: s_i8 + integer(ESMF_KIND_I4), intent(in), optional :: ms + integer(ESMF_KIND_I4), intent(in), optional :: us + integer(ESMF_KIND_I4), intent(in), optional :: ns + real(ESMF_KIND_R8), intent(in), optional :: d_r8 + real(ESMF_KIND_R8), intent(in), optional :: h_r8 + real(ESMF_KIND_R8), intent(in), optional :: m_r8 + real(ESMF_KIND_R8), intent(in), optional :: s_r8 + real(ESMF_KIND_R8), intent(in), optional :: ms_r8 + real(ESMF_KIND_R8), intent(in), optional :: us_r8 + real(ESMF_KIND_R8), intent(in), optional :: ns_r8 + integer(ESMF_KIND_I4), intent(in), optional :: sN + integer(ESMF_KIND_I8), intent(in), optional :: sN_i8 + integer(ESMF_KIND_I4), intent(in), optional :: sD + integer(ESMF_KIND_I8), intent(in), optional :: sD_i8 + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets the value of the ESMF_TimeInterval in units specified by + the user via Fortran optional arguments. + +
+The ESMF Time Manager represents and manipulates time internally with + integers to maintain precision. Hence, user-specified floating point + values are converted internally to integers. + +
+Ranges are limited only by machine word size. Numeric defaults are 0, + except for sD, which is 1. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeIntervalSet() + subroutine ESMF_TimeIntervalSetDurCal(timeinterval, calendar, & + & + yy, yy_i8, & + mm, mm_i8, & + d, d_i8, & + h, m, & + s, s_i8, & + ms, us, ns, & + d_r8, h_r8, m_r8, s_r8, & + ms_r8, us_r8, ns_r8, & + sN, sN_i8, sD, sD_i8, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(inout) :: timeinterval + type(ESMF_Calendar), intent(in) :: calendar + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(in), optional :: yy + integer(ESMF_KIND_I8), intent(in), optional :: yy_i8 + integer(ESMF_KIND_I4), intent(in), optional :: mm + integer(ESMF_KIND_I8), intent(in), optional :: mm_i8 + integer(ESMF_KIND_I4), intent(in), optional :: d + integer(ESMF_KIND_I8), intent(in), optional :: d_i8 + integer(ESMF_KIND_I4), intent(in), optional :: h + integer(ESMF_KIND_I4), intent(in), optional :: m + integer(ESMF_KIND_I4), intent(in), optional :: s + integer(ESMF_KIND_I8), intent(in), optional :: s_i8 + integer(ESMF_KIND_I4), intent(in), optional :: ms + integer(ESMF_KIND_I4), intent(in), optional :: us + integer(ESMF_KIND_I4), intent(in), optional :: ns + real(ESMF_KIND_R8), intent(in), optional :: d_r8 + real(ESMF_KIND_R8), intent(in), optional :: h_r8 + real(ESMF_KIND_R8), intent(in), optional :: m_r8 + real(ESMF_KIND_R8), intent(in), optional :: s_r8 + real(ESMF_KIND_R8), intent(in), optional :: ms_r8 + real(ESMF_KIND_R8), intent(in), optional :: us_r8 + real(ESMF_KIND_R8), intent(in), optional :: ns_r8 + integer(ESMF_KIND_I4), intent(in), optional :: sN + integer(ESMF_KIND_I8), intent(in), optional :: sN_i8 + integer(ESMF_KIND_I4), intent(in), optional :: sD + integer(ESMF_KIND_I8), intent(in), optional :: sD_i8 + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets the value of the ESMF_TimeInterval in units specified by + the user via Fortran optional arguments. + +
+The ESMF Time Manager represents and manipulates time internally with + integers to maintain precision. Hence, user-specified floating point + values are converted internally to integers. + +
+Ranges are limited only by machine word size. Numeric defaults are 0, + except for sD, which is 1. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeIntervalSet() + subroutine ESMF_TimeIntervalSetDurCalTyp(timeinterval, calkindflag, & + & + yy, yy_i8, & + mm, mm_i8, & + d, d_i8, & + h, m, & + s, s_i8, & + ms, us, ns, & + d_r8, h_r8, m_r8, s_r8, & + ms_r8, us_r8, ns_r8, & + sN, sN_i8, sD, sD_i8, & + rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(inout) :: timeinterval + type(ESMF_CalKind_Flag), intent(in) :: calkindflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer(ESMF_KIND_I4), intent(in), optional :: yy + integer(ESMF_KIND_I8), intent(in), optional :: yy_i8 + integer(ESMF_KIND_I4), intent(in), optional :: mm + integer(ESMF_KIND_I8), intent(in), optional :: mm_i8 + integer(ESMF_KIND_I4), intent(in), optional :: d + integer(ESMF_KIND_I8), intent(in), optional :: d_i8 + integer(ESMF_KIND_I4), intent(in), optional :: h + integer(ESMF_KIND_I4), intent(in), optional :: m + integer(ESMF_KIND_I4), intent(in), optional :: s + integer(ESMF_KIND_I8), intent(in), optional :: s_i8 + integer(ESMF_KIND_I4), intent(in), optional :: ms + integer(ESMF_KIND_I4), intent(in), optional :: us + integer(ESMF_KIND_I4), intent(in), optional :: ns + real(ESMF_KIND_R8), intent(in), optional :: d_r8 + real(ESMF_KIND_R8), intent(in), optional :: h_r8 + real(ESMF_KIND_R8), intent(in), optional :: m_r8 + real(ESMF_KIND_R8), intent(in), optional :: s_r8 + real(ESMF_KIND_R8), intent(in), optional :: ms_r8 + real(ESMF_KIND_R8), intent(in), optional :: us_r8 + real(ESMF_KIND_R8), intent(in), optional :: ns_r8 + integer(ESMF_KIND_I4), intent(in), optional :: sN + integer(ESMF_KIND_I8), intent(in), optional :: sN_i8 + integer(ESMF_KIND_I4), intent(in), optional :: sD + integer(ESMF_KIND_I8), intent(in), optional :: sD_i8 + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets the value of the ESMF_TimeInterval in units specified by + the user via Fortran optional arguments. + +
+The ESMF Time Manager represents and manipulates time internally with + integers to maintain precision. Hence, user-specified floating point + values are converted internally to integers. + +
+Ranges are limited only by machine word size. Numeric defaults are 0, + except for sD, which is 1. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
Private name; call using ESMF_TimeIntervalSet() + + subroutine ESMF_TimeIntervalSetStr(timeinterval, timeIntervalString, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(inout) :: timeinterval + character(*), intent(in) :: timeIntervalString + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets the value of an ESMF_TimeInterval using a + string in ISO 8601 duration format P[y]Y[mm]M[d]DT[h]H[m]M[s]S. See [24] and [14] for information about the format. In ESMF's implementation the time values can have the following types: +
+As with the ISO format, in ESMF's implementation the specifier and value can be left out if the value is 0. For example, P1YT1H3M4S is a valid format if the number of months and + days are both 0. The time part including the T can also be left off if the time values are all 0, so P1Y is a valid string if just 1 year is being specified. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeIntervalSet() + subroutine ESMF_TimeIntervalSetStrCal(timeinterval, calendar, & + timeIntervalString, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(inout) :: timeinterval + type(ESMF_Calendar), intent(in) :: calendar + character(*), intent(in) :: timeIntervalString + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets the value of an ESMF_TimeInterval using a + string in ISO 8601 duration format P[y]Y[mm]M[d]DT[h]H[m]M[s]S. See [24] and [14] for + information about the format. Also, see the description for the method + ESMF_TimeIntervalSetStr() 44.4.26 + for the specific types supported by ESMF for the values in the duration string. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeIntervalSet() + subroutine ESMF_TimeIntervalSetStrCalTyp(timeinterval, calkindflag, & + timeIntervalString, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(inout) :: timeinterval + type(ESMF_CalKind_Flag), intent(in) :: calkindflag + character(*), intent(in) :: timeIntervalString + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets the value of an ESMF_TimeInterval using a + string in ISO 8601 duration format P[y]Y[mm]M[d]DT[h]H[m]M[s]S. See [24] and [14] for + information about the format. Also, see the description for the method + ESMF_TimeIntervalSetStr() 44.4.26 + for the specific types supported by ESMF for the values in the duration string. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_TimeIntervalSet() + subroutine ESMF_TimeIntervalSetStrStart(timeinterval, startTime, & + timeIntervalString, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(inout) :: timeinterval + type(ESMF_Time), intent(in) :: startTime + character(*), intent(in) :: timeIntervalString + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Sets the value of an ESMF_TimeInterval using a + string in ISO 8601 duration format P[y]Y[mm]M[d]DT[h]H[m]M[s]S. See [24] and [14] for + information about the format. Also, see the description for the method + ESMF_TimeIntervalSetStr() 44.4.26 + for the specific types supported by ESMF for the values in the duration string. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_TimeIntervalValidate(timeinterval, rc) +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeinterval + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Checks whether a timeinterval is valid. + If fractional value, denominator must be non-zero. + +
+The arguments are: +
+ + +
+The Clock class advances model time and tracks its associated +date on a specified Calendar. It stores start time, stop time, +current time, previous time, and a time step. It can also store +a reference time, typically the time instant at which a simulation +originally began. For a restart run, the reference time can be +different than the start time, when the application execution resumes. + +
+A user can call the ESMF_ClockSet method and reset the time +step as desired. + +
+A Clock also stores a list of Alarms, which can be set to flag +events that occur at a specified time instant or at +a specified time interval. See Section 46.1 for +details on how to use Alarms. + +
+There are methods for setting and getting the Times and +Alarms associated with a Clock. Methods are defined for +advancing the Clock's current time, checking if the +stop time has been reached, reversing direction, and +synchronizing with a real clock. + +
+ +
+DESCRIPTION:
+
+
+Specifies the time-stepping direction of a clock. Use with "direction"
+argument to methods ESMF_ClockSet() and ESMF_ClockGet().
+Cannot be used with method ESMF_ClockCreate(), since it only
+initializes a clock in the default forward mode; a clock must be advanced
+(timestepped) at least once before reversing direction via
+ESMF_ClockSet(). This also holds true for negative timestep clocks
+which are initialized (created) with stopTime < startTime, since "forward"
+means timestepping from startTime towards stopTime
+(see ESMF_DIRECTION_FORWARD below).
+
+
+"Forward" and "reverse" directions are distinct from positive and negative +timesteps. "Forward" means timestepping in the direction established at +ESMF_ClockCreate(), from startTime towards stopTime, regardless +of the timestep sign. "Reverse" means timestepping in the opposite direction, +back towards the clock's startTime, regardless of the timestep sign. + +
+Clocks and alarms run in reverse in such a way that the state of a clock and +its alarms after each time step is precisely replicated as it was in forward +time-stepping mode. All methods which query clock and alarm state will +return the same result for a given timeStep, regardless of the direction of +arrival. + +
+The type of this flag is: + +
+type(ESMF_Direction_Flag) + +
+The valid values are: +
+
+
+The following is a typical sequence for using a Clock in a +geophysical model. + +
+At initialize: + +
+At run: + +
+At finalize: + +
+The following code example illustrates Clock usage. + +
+ +
+ +
+
+! !PROGRAM: ESMF_ClockEx - Clock initialization and time-stepping +! +! !DESCRIPTION: +! +! This program shows an example of how to create, initialize, advance, and +! examine a basic clock +!----------------------------------------------------------------------------- +#include "ESMF.h" + + ! ESMF Framework module + use ESMF + use ESMF_TestMod + implicit none + + ! instantiate a clock + type(ESMF_Clock) :: clock + + ! instantiate time_step, start and stop times + type(ESMF_TimeInterval) :: timeStep + type(ESMF_Time) :: startTime + type(ESMF_Time) :: stopTime + + ! local variables for Get methods + type(ESMF_Time) :: currTime + integer(ESMF_KIND_I8) :: advanceCount + integer :: YY, MM, DD, H, M, S + + ! return code + integer :: rc ++ +
+
+ ! initialize ESMF framework + call ESMF_Initialize(defaultCalKind=ESMF_CALKIND_GREGORIAN, & + defaultlogfilename="ClockEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+ +
+This example shows how to create and initialize an ESMF_Clock. +
+
+ ! initialize time interval to 2 days, 4 hours (6 timesteps in 13 days) + call ESMF_TimeIntervalSet(timeStep, d=2, h=4, rc=rc) ++ +
+
+ ! initialize start time to 4/1/2003 2:24:00 ( 1/10 of a day ) + call ESMF_TimeSet(startTime, yy=2003, mm=4, dd=1, h=2, m=24, rc=rc) ++ +
+
+ ! initialize stop time to 4/14/2003 2:24:00 ( 1/10 of a day ) + call ESMF_TimeSet(stopTime, yy=2003, mm=4, dd=14, h=2, m=24, rc=rc) ++ +
+
+ ! initialize the clock with the above values + clock = ESMF_ClockCreate(timeStep, startTime, stopTime=stopTime, & + name="Clock 1", rc=rc) ++ +
+ +
+This example shows how to time-step an ESMF_Clock. +
+
+ ! time step clock from start time to stop time + do while (.not.ESMF_ClockIsStopTime(clock, rc=rc)) ++ +
+
+ call ESMF_ClockPrint(clock, options="currTime string", rc=rc) ++ +
+
+ call ESMF_ClockAdvance(clock, rc=rc) ++ +
+
+ end do ++ +
+ +
+This example shows how to examine an ESMF_Clock. +
+
+ ! get the clock's final current time + call ESMF_ClockGet(clock, currTime=currTime, rc=rc) ++ +
+
+ call ESMF_TimeGet(currTime, yy=YY, mm=MM, dd=DD, h=H, m=M, s=S, rc=rc) + print *, "The clock's final current time is ", YY, "/", MM, "/", DD, & + " ", H, ":", M, ":", S ++ +
+
+ ! get the number of times the clock was advanced + call ESMF_ClockGet(clock, advanceCount=advanceCount, rc=rc) + print *, "The clock was advanced ", advanceCount, " times." ++ +
+ +
+This example shows how to time-step an ESMF_Clock in reverse mode. +
+
+ call ESMF_ClockSet(clock, direction=ESMF_DIRECTION_REVERSE, rc=rc) ++ +
+
+ ! time step clock in reverse from stop time back to start time; + ! note use of ESMF_ClockIsDone() rather than ESMF_ClockIsStopTime() + do while (.not.ESMF_ClockIsDone(clock, rc=rc)) ++ +
+
+ call ESMF_ClockPrint(clock, options="currTime string", rc=rc) ++ +
+
+ call ESMF_ClockAdvance(clock, rc=rc) ++ +
+
+ end do ++ +
+ +
+This example shows how to destroy an ESMF_Clock. +
+
+ ! destroy clock + call ESMF_ClockDestroy(clock, rc=rc) ++ +
+
+ ! finalize ESMF framework + call ESMF_Finalize(rc=rc) ++ +
+
+ end program ESMF_ClockEx ++ +
+ + +
+ +
+
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + clock1 = clock2 +ARGUMENTS: +
type(ESMF_Clock) :: clock1 + type(ESMF_Clock) :: clock2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign clock1 as an alias to the same ESMF_Clock object in + memory as clock2. If clock2 is invalid, then clock1 + will be equally invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (clock1 == clock2) then ... endif + OR + result = (clock1 == clock2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock1 + type(ESMF_Clock), intent(in) :: clock2 ++DESCRIPTION: +
+Overloads the (==) operator for the ESMF_Clock class. + Compare two clocks for equality; return .true. if equal, + .false. otherwise. Comparison is based on IDs, which are distinct + for newly created clocks and identical for clocks created as copies. + +
+If either side of the equality test is not in the + ESMF_INIT_CREATED status an error will be logged. However, this + does not affect the return value, which is .true. when both + sides are in the same status, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (clock1 /= clock2) then ... endif + OR + result = (clock1 /= clock2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock1 + type(ESMF_Clock), intent(in) :: clock2 ++DESCRIPTION: +
+Overloads the (/=) operator for the ESMF_Clock class. + Compare two clocks for inequality; return .true. if not equal, + .false. otherwise. Comparison is based on IDs, which are distinct + for newly created clocks and identical for clocks created as copies. + +
+If either side of the equality test is not in the + ESMF_INIT_CREATED status an error will be logged. However, this + does not affect the return value, which is .true. when both sides + are not in the same status, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockAdvance(clock, & + timeStep, ringingAlarmList, ringingAlarmCount, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(inout) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_TimeInterval), intent(in), optional :: timeStep + type(ESMF_Alarm), intent(out), optional :: ringingAlarmList(:) + integer, intent(out), optional :: ringingAlarmCount + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Advances the clock's current time by one time step: either the + clock's, or the passed-in timeStep (see below). When the + clock is in ESMF_DIRECTION_FORWARD (default), this method + adds the timeStep to the clock's current time. + In ESMF_DIRECTION_REVERSE, timeStep is subtracted from the + current time. In either case, timeStep can be positive or negative. + See the "direction" argument in method ESMF_ClockSet(). + ESMF_ClockAdvance() optionally returns a list and number of ringing + ESMF_Alarms. See also method ESMF_ClockGetRingingAlarms(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ClockCreate() + function ESMF_ClockCreateNew(timeStep, startTime, & + stopTime, runDuration, runTimeStepCount, refTime, repeatDuration, name, rc) +RETURN VALUE: +
type(ESMF_Clock) :: ESMF_ClockCreateNew +ARGUMENTS: +
type(ESMF_TimeInterval), intent(in) :: timeStep + type(ESMF_Time), intent(in) :: startTime + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Time), intent(in), optional :: stopTime + type(ESMF_TimeInterval), intent(in), optional :: runDuration + integer, intent(in), optional :: runTimeStepCount + type(ESMF_Time), intent(in), optional :: refTime + type(ESMF_TimeInterval), intent(in), optional :: repeatDuration + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Creates and sets the initial values in a new ESMF_Clock. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ClockCreate() + function ESMF_ClockCreateCopy(clock, rc) +RETURN VALUE: +
type(ESMF_Clock) :: ESMF_ClockCreateCopy +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Creates a deep copy of a given ESMF_Clock, but does not copy its + list of ESMF_Alarms (pointers), since an ESMF_Alarm can only + be associated with one ESMF_Clock. Hence, the returned + ESMF_Clock copy has no associated ESMF_Alarms, the same as + with a newly created ESMF_Clock. If desired, new + ESMF_Alarms must be created and associated with this copied + ESMF_Clock via ESMF_AlarmCreate(), or existing + ESMF_Alarms must be re-associated with this copied + ESMF_Clock via ESMF_AlarmSet(...clock=...). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockDestroy(clock, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(inout) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Releases resources associated with this ESMF_Clock. This releases + the list of associated ESMF_Alarms (pointers), but not the + ESMF_Alarms themselves; the user must explicitly call + ESMF_AlarmDestroy() on each ESMF_Alarm to release its + resources. ESMF_ClockDestroy() and corresponding + ESMF_AlarmDestroy()s can be called in either order. + +
+If ESMF_ClockDestroy() is called before ESMF_AlarmDestroy(), + any ESMF_Alarms that were in the ESMF_Clock's list will + no longer be associated with any ESMF_Clock. If desired, + these "orphaned" ESMF_Alarms can be associated with a different + ESMF_Clock via a call to ESMF_AlarmSet(...clock=...). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockGet(clock, & + timeStep, startTime, stopTime, & + runDuration, runTimeStepCount, refTime, currTime, prevTime, & + currSimTime, prevSimTime, calendar, calkindflag, timeZone, & + advanceCount, alarmCount, direction, repeatDuration, repeatCount, & + name, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_TimeInterval), intent(out), optional :: timeStep + type(ESMF_Time), intent(out), optional :: startTime + type(ESMF_Time), intent(out), optional :: stopTime + type(ESMF_TimeInterval), intent(out), optional :: runDuration + real(ESMF_KIND_R8), intent(out), optional :: runTimeStepCount + type(ESMF_Time), intent(out), optional :: refTime + type(ESMF_Time), intent(out), optional :: currTime + type(ESMF_Time), intent(out), optional :: prevTime + type(ESMF_TimeInterval), intent(out), optional :: currSimTime + type(ESMF_TimeInterval), intent(out), optional :: prevSimTime + type(ESMF_Calendar), intent(out), optional :: calendar + type(ESMF_CalKind_Flag), intent(out), optional :: calkindflag + integer, intent(out), optional :: timeZone + integer(ESMF_KIND_I8), intent(out), optional :: advanceCount + integer, intent(out), optional :: alarmCount + type(ESMF_Direction_Flag), intent(out), optional :: direction + type(ESMF_TimeInterval), intent(out), optional :: repeatDuration + integer(ESMF_KIND_I8), intent(out), optional :: repeatCount + character (len=*), intent(out), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets one or more of the properties of an ESMF_Clock. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockGetAlarm(clock, alarmname, alarm, & + rc) +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + character (len=*), intent(in) :: alarmname + type(ESMF_Alarm), intent(out) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets the alarm whose name is the value of alarmname in the + clock's ESMF_Alarm list. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockGetAlarmList(clock, alarmlistflag, & + timeStep, alarmList, alarmCount, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + type(ESMF_AlarmList_Flag), intent(in) :: alarmlistflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_TimeInterval), intent(in), optional :: timeStep + type(ESMF_Alarm), intent(out), optional :: alarmList(:) + integer, intent(out), optional :: alarmCount + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets the clock's list of alarms and/or number of alarms. + +
+The arguments are: +
+ESMF_ALARMLIST_ALL : + Returns the ESMF_Clock's entire list of alarms. + +
+ESMF_ALARMLIST_NEXTRINGING : + Return only those alarms that will ring upon the next + clock time step. Can optionally specify argument + timeStep (see below) to use instead of the clock's. + See also method ESMF_AlarmWillRingNext() for checking a + single alarm. + +
+ESMF_ALARMLIST_PREVRINGING : + + Return only those alarms that were ringing on the previous + ESMF_Clock time step. See also method + ESMF_AlarmWasPrevRinging() for checking a single alarm. + +
+ESMF_ALARMLIST_RINGING : + Returns only those clock alarms that are currently + ringing. See also method ESMF_ClockAdvance() for + getting the list of ringing alarms subsequent to a time step. + See also method ESMF_AlarmIsRinging() for checking a + single alarm. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockGetNextTime(clock, nextTime, & + timeStep, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + type(ESMF_Time), intent(out) :: nextTime + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_TimeInterval), intent(in), optional :: timeStep + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Calculates what the next time of the clock will be, based on + the clock's current time step or an optionally passed-in + timeStep. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_ClockIsCreated(clock, rc) +RETURN VALUE: +
logical :: ESMF_ClockIsCreated +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the clock has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_ClockIsDone(clock, rc) +RETURN VALUE: +
logical :: ESMF_ClockIsDone +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns true if currentTime is greater than or equal to stopTime + in ESMF_DIRECTION_FORWARD, or if currentTime is less than or + equal to startTime in ESMF_DIRECTION_REVERSE. It returns false + otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_ClockIsReverse(clock, rc) +RETURN VALUE: +
logical :: ESMF_ClockIsReverse +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns true if clock is in ESMF_DIRECTION_REVERSE, and false if + in ESMF_DIRECTION_FORWARD. Allows convenient use in "if" and + "do while" constructs. Alternative to + ESMF_ClockGet(...direction=...). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_ClockIsStopTime(clock, rc) +RETURN VALUE: +
logical :: ESMF_ClockIsStopTime +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns true if the clock has reached or exceeded its stop time, + and false otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_ClockIsStopTimeEnabled(clock, rc) +RETURN VALUE: +
logical :: ESMF_ClockIsStopTimeEnabled +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns true if the clock's stop time is set and enabled, + and false otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockPrint(clock, options, preString, unit, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len=*), intent(in), optional :: options + character(*), intent(in), optional :: preString + character(*), intent(out), optional :: unit + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Prints out an ESMF_Clock's properties to stdout, in
+ support of testing and debugging. The options control the type of
+ information and level of detail.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockSet(clock, & + timeStep, startTime, stopTime, & + runDuration, runTimeStepCount, refTime, currTime, advanceCount, & + direction, name, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(inout) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_TimeInterval), intent(in), optional :: timeStep + type(ESMF_Time), intent(in), optional :: startTime + type(ESMF_Time), intent(in), optional :: stopTime + type(ESMF_TimeInterval), intent(in), optional :: runDuration + integer, intent(in), optional :: runTimeStepCount + type(ESMF_Time), intent(in), optional :: refTime + type(ESMF_Time), intent(in), optional :: currTime + integer(ESMF_KIND_I8), intent(in), optional :: advanceCount + type(ESMF_Direction_Flag), intent(in), optional :: direction + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets/resets one or more of the properties of an ESMF_Clock that + was previously initialized via ESMF_ClockCreate(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockStopTimeDisable(clock, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(inout) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Disables a ESMF_Clock's stop time; ESMF_ClockIsStopTime() + will always return false, allowing a clock to run past its stopTime. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockStopTimeEnable(clock, stopTime, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(inout) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Time), intent(in), optional :: stopTime + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Enables a ESMF_Clock's stop time, allowing + ESMF_ClockIsStopTime() to respect the stopTime. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockSyncToRealTime(clock, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(inout) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets a clock's current time to the wall clock time. It is + accurate to the nearest second. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ClockValidate(clock, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Checks whether a clock is valid. + Must have a valid startTime and timeStep. If clock has a + stopTime, its currTime must be within startTime to stopTime, inclusive; + also startTime's and stopTime's calendars must be the same. + +
+The arguments are: +
+ + +
+The Alarm class identifies events that occur at specific Times +or specific TimeIntervals by returning a true value at those times +or subsequent times, and a false value otherwise. + +
+ +
+DESCRIPTION:
+
+Specifies the characteristics of Alarms that populate
+a retrieved Alarm list.
+
+
+The type of this flag is: + +
+type(ESMF_AlarmList_Flag) + +
+The valid values are: +
+
+
+
+
+Alarms are used in conjunction with Clocks (see Section 45.1). +Multiple Alarms can be associated with a Clock. During the +ESMF_ClockAdvance() method, a Clock iterates over its internal Alarms +to determine if any are ringing. Alarms ring when a specified Alarm +time is reached or exceeded, taking into account whether the time step is +positive or negative. In ESMF_DIRECTION_REVERSE +(see Section 45.1), alarms ring in reverse, i.e., they begin +ringing when they originally ended, and end ringing when they originally +began. On completion of the time advance call, the Clock optionally returns +a list of ringing alarms. + +
+Each ringing Alarm can then be processed using Alarm methods for identifying, +turning off, disabling or resetting the Alarm. + +
+Alarm methods are defined for obtaining the ringing state, turning the +ringer on/off, enabling/disabling the Alarm, and getting/setting +associated times. + +
+The following example shows how to set and process Alarms. + +
+ +
+ +
+
+! !PROGRAM: ESMF_AlarmEx - Alarm examples +! +! !DESCRIPTION: +! +! This program shows an example of how to create, initialize, and process +! alarms associated with a clock. +!----------------------------------------------------------------------------- +#include "ESMF.h" + + ! ESMF Framework module + use ESMF + use ESMF_TestMod + implicit none + + ! instantiate time_step, start, stop, and alarm times + type(ESMF_TimeInterval) :: timeStep, alarmInterval + type(ESMF_Time) :: alarmTime, startTime, stopTime + + ! instantiate a clock + type(ESMF_Clock) :: clock + + ! instantiate Alarm lists + integer, parameter :: NUMALARMS = 2 + type(ESMF_Alarm) :: alarm(NUMALARMS) + + ! local variables for Get methods + integer :: ringingAlarmCount ! at any time step (0 to NUMALARMS) + + ! name, loop counter, result code + character (len=ESMF_MAXSTR) :: name + integer :: i, rc, result ++ +
+
+ ! initialize ESMF framework + call ESMF_Initialize(defaultCalKind=ESMF_CALKIND_GREGORIAN, & + defaultlogfilename="AlarmEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+ +
+This example shows how to create and initialize an ESMF_Clock. +
+
+ ! initialize time interval to 1 day + call ESMF_TimeIntervalSet(timeStep, d=1, rc=rc) ++ +
+
+ ! initialize start time to 9/1/2003 + call ESMF_TimeSet(startTime, yy=2003, mm=9, dd=1, rc=rc) ++ +
+
+ ! initialize stop time to 9/30/2003 + call ESMF_TimeSet(stopTime, yy=2003, mm=9, dd=30, rc=rc) ++ +
+
+ ! create & initialize the clock with the above values + clock = ESMF_ClockCreate(timeStep, startTime, stopTime=stopTime, & + name="The Clock", rc=rc) ++ +
+ +
+This example shows how to create and initialize two ESMF_Alarms and + associate them with the clock. +
+
+ ! Initialize first alarm to be a one-shot on 9/15/2003 and associate + ! it with the clock + call ESMF_TimeSet(alarmTime, yy=2003, mm=9, dd=15, rc=rc) ++ +
+
+ alarm(1) = ESMF_AlarmCreate(clock, & + ringTime=alarmTime, name="Example alarm 1", rc=rc) ++ +
+
+ ! Initialize second alarm to ring on a 1 week interval starting 9/1/2003 + ! and associate it with the clock + call ESMF_TimeSet(alarmTime, yy=2003, mm=9, dd=1, rc=rc) ++ +
+
+ call ESMF_TimeIntervalSet(alarmInterval, d=7, rc=rc) ++ +
+
+ ! Alarm gets default name "Alarm002" + alarm(2) = ESMF_AlarmCreate(clock=clock, ringTime=alarmTime, & + ringInterval=alarmInterval, rc=rc) ++ +
+ +
+This example shows how to advance an ESMF_Clock and process any + resulting ringing alarms. +
+
+ ! time step clock from start time to stop time + do while (.not.ESMF_ClockIsStopTime(clock, rc=rc)) ++ +
+
+ ! perform time step and get the number of any ringing alarms + call ESMF_ClockAdvance(clock, ringingAlarmCount=ringingAlarmCount, & + rc=rc) ++ +
+
+ call ESMF_ClockPrint(clock, options="currTime string", rc=rc) ++ +
+
+ ! check if alarms are ringing + if (ringingAlarmCount > 0) then + print *, "number of ringing alarms = ", ringingAlarmCount + + do i = 1, NUMALARMS + if (ESMF_AlarmIsRinging(alarm(i), rc=rc)) then ++ +
+
+ call ESMF_AlarmGet(alarm(i), name=name, rc=rc) + print *, trim(name), " is ringing!" ++ +
+
+ ! after processing alarm, turn it off + call ESMF_AlarmRingerOff(alarm(i), rc=rc) ++ +
+
+ end if ! this alarm is ringing + end do ! each ringing alarm + endif ! ringing alarms + end do ! timestep clock ++ +
+ +
+This example shows how to destroy ESMF_Alarms and ESMF_Clocks. +
+
+ call ESMF_AlarmDestroy(alarm(1), rc=rc) ++ +
+
+ call ESMF_AlarmDestroy(alarm(2), rc=rc) ++ +
+
+ call ESMF_ClockDestroy(clock, rc=rc) ++ +
+
+ ! finalize ESMF framework + call ESMF_Finalize(rc=rc) ++ +
+
+ end program ESMF_AlarmEx ++ +
+ + +
+ +
+
+
+
+ +
+The Alarm class is designed as a deep, dynamically allocatable class, +based on a pointer type. This allows for both indirect and direct +manipulation of alarms. Indirect alarm manipulation is where ESMF_Alarm API +methods, such as ESMF_AlarmRingerOff(), are invoked on alarm references +(pointers) returned from ESMF_Clock queries such as "return ringing alarms." +Since the method is performed on an alarm reference, the actual alarm held +by the clock is affected, not just a user's local copy. Direct alarm +manipulation is the more common case where alarm API methods are invoked on +the original alarm objects created by the user. + +
+For consistency, the ESMF_Clock class is also designed as a deep, dynamically +allocatable class. + +
+An additional benefit from this approach is that Clocks and Alarms can be +created and used from anywhere in a user's code without regard to the scope +in which they were created. In contrast, statically created Alarms and +Clocks would disappear if created within a user's routine that returns, +whereas dynamically allocated Alarms and Clocks will persist until explicitly +destroyed by the user. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + alarm1 = alarm2 +ARGUMENTS: +
type(ESMF_Alarm) :: alarm1 + type(ESMF_Alarm) :: alarm2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign alarm1 as an alias to the same ESMF_Alarm object in + memory as alarm2. If alarm2 is invalid, then alarm1 + will be equally invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (alarm1 == alarm2) then ... endif + OR + result = (alarm1 == alarm2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm1 + type(ESMF_Alarm), intent(in) :: alarm2 ++DESCRIPTION: +
+Overloads the (==) operator for the ESMF_Alarm class. + Compare two alarms for equality; return .true. if equal, + .false. otherwise. Comparison is based on IDs, which are distinct + for newly created alarms and identical for alarms created as copies. + +
+If either side of the equality test is not in the + ESMF_INIT_CREATED status an error will be logged. However, this + does not affect the return value, which is .true. when both + sides are in the same status, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (alarm1 /= alarm2) then ... endif + OR + result = (alarm1 /= alarm2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm1 + type(ESMF_Alarm), intent(in) :: alarm2 ++DESCRIPTION: +
+Overloads the (/=) operator for the ESMF_Alarm class. + Compare two alarms for inequality; return .true. if not equal, + .false. otherwise. Comparison is based on IDs, which are distinct + for newly created alarms and identical for alarms created as copies. + +
+If either side of the equality test is not in the + ESMF_INIT_CREATED status an error will be logged. However, this + does not affect the return value, which is .true. when both sides + are not in the same status, and .false. otherwise. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_AlarmCreate() + function ESMF_AlarmCreateNew(clock, & + ringTime, ringInterval, stopTime, ringDuration, ringTimeStepCount, & + refTime, enabled, sticky, name, rc) +RETURN VALUE: +
type(ESMF_Alarm) :: ESMF_AlarmCreateNew +ARGUMENTS: +
type(ESMF_Clock), intent(in) :: clock + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Time), intent(in), optional :: ringTime + type(ESMF_TimeInterval), intent(in), optional :: ringInterval + type(ESMF_Time), intent(in), optional :: stopTime + type(ESMF_TimeInterval), intent(in), optional :: ringDuration + integer, intent(in), optional :: ringTimeStepCount + type(ESMF_Time), intent(in), optional :: refTime + logical, intent(in), optional :: enabled + logical, intent(in), optional :: sticky + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Creates and sets the initial values in a new ESMF_Alarm. + +
+In ESMF_DIRECTION_REVERSE (see Section 45.1), alarms + ring in reverse, i.e., they begin ringing when they originally ended, + and end ringing when they originally began. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_AlarmCreate() + function ESMF_AlarmCreateCopy(alarm, rc) +RETURN VALUE: +
type(ESMF_Alarm) :: ESMF_AlarmCreateCopy +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Creates a complete (deep) copy of a given ESMF_Alarm. + The returned ESMF_Alarm copy is associated with the same + ESMF_Clock as the original ESMF_Alarm. If desired, use + ESMF_AlarmSet(...clock=...) to re-associate the + ESMF_Alarm copy with a different ESMF_Clock. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AlarmDestroy(alarm, rc) +ARGUMENTS: +
type(ESMF_Alarm), intent(inout) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Releases resources associated with this ESMF_Alarm. Also + removes this ESMF_Alarm from its associated ESMF_Clock's + list of ESMF_Alarms (removes the ESMF_Alarm pointer from + the list). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AlarmDisable(alarm, rc) +ARGUMENTS: +
type(ESMF_Alarm), intent(inout) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Disables an ESMF_Alarm. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AlarmEnable(alarm, rc) +ARGUMENTS: +
type(ESMF_Alarm), intent(inout) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Enables an ESMF_Alarm to function. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AlarmGet(alarm, & + clock, ringTime, prevRingTime, ringInterval, stopTime, ringDuration, & + ringTimeStepCount, timeStepRingingCount, ringBegin, ringEnd, & + refTime, ringing, ringingOnPrevTimeStep, enabled, sticky, name, rc) +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Clock), intent(out), optional :: clock + type(ESMF_Time), intent(out), optional :: ringTime + type(ESMF_Time), intent(out), optional :: prevRingTime + type(ESMF_TimeInterval), intent(out), optional :: ringInterval + type(ESMF_Time), intent(out), optional :: stopTime + type(ESMF_TimeInterval), intent(out), optional :: ringDuration + integer, intent(out), optional :: ringTimeStepCount + integer, intent(out), optional :: timeStepRingingCount + type(ESMF_Time), intent(out), optional :: ringBegin + type(ESMF_Time), intent(out), optional :: ringEnd + type(ESMF_Time), intent(out), optional :: refTime + logical, intent(out), optional :: ringing + logical, intent(out), optional :: ringingOnPrevTimeStep + logical, intent(out), optional :: enabled + logical, intent(out), optional :: sticky + character (len=*), intent(out), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets one or more of an ESMF_Alarm's properties. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_AlarmIsCreated(alarm, rc) +RETURN VALUE: +
logical :: ESMF_AlarmIsCreated +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the alarm has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_AlarmIsEnabled(alarm, rc) +RETURN VALUE: +
logical :: ESMF_AlarmIsEnabled +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Check if ESMF_Alarm is enabled. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_AlarmIsRinging(alarm, rc) +RETURN VALUE: +
logical :: ESMF_AlarmIsRinging +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Check if ESMF_Alarm is ringing. + +
+See also method + ESMF_ClockGetAlarmList(clock, ESMF_ALARMLIST_RINGING, ...) + to get a list of all ringing alarms belonging to an ESMF_Clock. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_AlarmIsSticky(alarm, rc) +RETURN VALUE: +
logical :: ESMF_AlarmIsSticky +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Check if alarm is sticky. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AlarmNotSticky(alarm, & + ringDuration, ringTimeStepCount, rc) +ARGUMENTS: +
type(ESMF_Alarm), intent(inout) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_TimeInterval), intent(in), optional :: ringDuration + integer, intent(in), optional :: ringTimeStepCount + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Unset an ESMF_Alarm's sticky flag; once alarm is ringing, + it turns itself off after ringDuration. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AlarmPrint(alarm, options, rc) +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm + character (len=*), intent(in), optional :: options + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Prints out an ESMF_Alarm's properties to stdout, in support
+ of testing and debugging. The options control the type of information
+ and level of detail.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AlarmRingerOff(alarm, rc) +ARGUMENTS: +
type(ESMF_Alarm), intent(inout) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Turn off an ESMF_Alarm; unsets ringing state. For a sticky + alarm, this method must be called to turn off its ringing state. + This is true for either ESMF_DIRECTION_FORWARD (default) or + ESMF_DIRECTION_REVERSE. See Section 45.1. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AlarmRingerOn(alarm, rc) +ARGUMENTS: +
type(ESMF_Alarm), intent(inout) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Turn on an ESMF_Alarm; sets ringing state. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AlarmSet(alarm, & + clock, ringTime, ringInterval, stopTime, ringDuration, & + ringTimeStepCount, refTime, ringing, enabled, sticky, name, rc) +ARGUMENTS: +
type(ESMF_Alarm), intent(inout) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Clock), intent(in), optional :: clock + type(ESMF_Time), intent(in), optional :: ringTime + type(ESMF_TimeInterval), intent(in), optional :: ringInterval + type(ESMF_Time), intent(in), optional :: stopTime + type(ESMF_TimeInterval), intent(in), optional :: ringDuration + integer, intent(in), optional :: ringTimeStepCount + type(ESMF_Time), intent(in), optional :: refTime + logical, intent(in), optional :: ringing + logical, intent(in), optional :: enabled + logical, intent(in), optional :: sticky + character (len=*), intent(in), optional :: name + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets/resets one or more of the properties of an ESMF_Alarm that + was previously initialized via ESMF_AlarmCreate(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AlarmSticky(alarm, rc) +ARGUMENTS: +
type(ESMF_Alarm), intent(inout) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Set an ESMF_Alarm's sticky flag; once alarm is ringing, + it remains ringing until ESMF_AlarmRingerOff() is called. + There is an implicit limitation that in order to properly reverse + timestep through a ring end time in ESMF_DIRECTION_REVERSE, that + time must have already been traversed in the forward direction. + This is due to the fact that an ESMF_Alarm cannot predict when + user code will call ESMF_AlarmRingerOff(). An error message + will be logged when this limitation is not satisfied. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AlarmValidate(alarm, rc) +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Performs a validation check on an ESMF_Alarm's properties. + Must have a valid ringTime, set either directly or indirectly via + ringInterval. See ESMF_AlarmCreate(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_AlarmWasPrevRinging(alarm, rc) +RETURN VALUE: +
logical :: ESMF_AlarmWasPrevRinging +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Check if ESMF_Alarm was ringing on the previous clock timestep. + +
+See also method + ESMF_ClockGetAlarmList(clock, ESMF_ALARMLIST_PREVRINGING, ...) + get a list of all alarms belonging to a ESMF_Clock that were + ringing on the previous time step. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_AlarmWillRingNext(alarm, timeStep, rc) +RETURN VALUE: +
logical :: ESMF_AlarmWillRingNext +ARGUMENTS: +
type(ESMF_Alarm), intent(in) :: alarm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_TimeInterval), intent(in), optional :: timeStep + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Check if ESMF_Alarm will ring on the next clock timestep, either + the current clock timestep or a passed-in timestep. + +
+See also method + ESMF_ClockGetAlarmList(clock, ESMF_ALARMLIST_NEXTRINGING, ...) + to get a list of all alarms belonging to a ESMF_Clock that will + ring on the next time step. + +
+The arguments are: +
+ESMF Configuration Management is based on NASA DAO's
+Inpak 90 package, a Fortran 90 collection of routines/functions
+for accessing Resource Files in ASCII format.The package
+is optimized for minimizing formatted I/O, performing all of its
+string operations in memory using Fortran intrinsic functions.
+
+
+ +
+The ESMF Configuration Management Package was evolved by +Leonid Zaslavsky and Arlindo da Silva from Ipack90 package +created by Arlindo da Silva at NASA DAO. + +
+Back in the 70's Eli Isaacson wrote IOPACK in Fortran +66. In June of 1987 Arlindo da Silva wrote Inpak77 using +Fortran 77 string functions; Inpak 77 is a vastly +simplified IOPACK, but has its own goodies not found in +IOPACK. Inpak 90 removes some obsolete functionality in +Inpak77, and parses the whole resource file in memory for +performance. + +
+ +
+A Resource File (RF) is a text file consisting of list of + label-value pairs. There is a buffer limit of 256,000 + characters for the entire Resource File. Each label is limited + to 1,000 characters. Each label should be followed by some data, the + value. An example Resource File follows. It is the file used + in the example below. + +
+
+ # This is an example Resource File. + # It contains a list of <label,value> pairs. + # The colon after the label is required. + + # The values after the label can be an list. + # Multiple types are authorized. + + my_file_names: jan87.dat jan88.dat jan89.dat # all strings + constants: 3.1415 25 # float and integer + my_favorite_colors: green blue 022 + + + # Or, the data can be a list of single value pairs. + # It is simplier to retrieve data in this format: + + radius_of_the_earth: 6.37E6 + parameter_1: 89 + parameter_2: 78.2 + input_file_name: dummy_input.nc + + + # Or, the data can be located in a table using the following + # syntax: + + my_table_name:: + 1000 3000 263.0 + 925 3000 263.0 + 850 3000 263.0 + 700 3000 269.0 + 500 3000 287.0 + 400 3000 295.8 + 300 3000 295.8 + :: ++ +
+Note that the colon after the label is required and that the double colon is required + to declare tabular data. + +
+Resource files are intended for random access (except between ::'s in a + table definition). This means that order in which a particular + label-value pair is retrieved is not dependent upon the original order + of the pairs. The only exception to this, however, is when the same label appears + multiple times within the Resource File. + +
+ +
+ +
+ +
+This example/test code performs simple Config/Resource File routines. It does not + include attaching a Config to a component. The important thing to remember there + is that you can have one Config per component. + +
+There are two methodologies for accessing data in a Resource File. This example will + demonstrate both. + +
+Note the API section contains a complete description of arguments in + the methods/functions demonstrated in this example. + +
+ +
+The following are the variable declarations used as arguments in the following code + fragments. They represent the locals names for the variables listed in the Resource + File (RF). Note they do not need to be the same. +
+
+ character(ESMF_MAXPATHLEN) :: fname ! config file name + character(ESMF_MAXPATHLEN) :: fn1, fn2, fn3, input_file ! strings to be read in + integer :: rc ! error return code (0 is OK) + integer :: i_n ! the first constant in the RF + real :: param_1 ! the second constant in the RF + real :: radius ! radius of the earth + real :: table(7,3) ! an array to hold the table in the RF + + type(ESMF_Config) :: cf ! the Config itself + type(ESMF_HConfig) :: hconfig ! HConfig variable ++ +
+ +
+While there are two methodologies for accessing the data within a Resource File, + there is only one way to create the initial Config and load its ASCII text into + memory. This is the first step in the process. + +
+Note that subsequent calls to ESMF_ConfigLoadFile will OVERWRITE the current + Config NOT append to it. There is no means of appending to a Config. + +
+
+ cf = ESMF_ConfigCreate(rc=rc) ! Create the empty Config ++ +
+
+ fname = "myResourceFile.rc" ! Name the Resource File + call ESMF_ConfigLoadFile(cf, fname, rc=rc) ! Load the Resource File + ! into the empty Config ++ +
+ +
+Remember, + that the order in which a particular label/value pair is retrieved + is not dependent upon the order which they exist within the Resource File. +
+
+ call ESMF_ConfigGetAttribute(cf, radius, label='radius_of_the_earth:', & + default=1.0, rc=rc) ++ +
+Note that the colon must be included in the label string when using this + methodology. It is also important to provide a default value in case the label + does not exist in the file + +
+This methodology works for all types. The following is an example of retrieving a + string: +
+
+ call ESMF_ConfigGetAttribute(cf, input_file, label='input_file_name:', & + default="./default.nc", rc=rc) ++ +
+The same code fragment can be used to demonstrate what happens when the label is not + present. Note that "file_name" does not exist in the Resource File. The result of + its absence is the default value provided in the call. +
+
+ call ESMF_ConfigGetAttribute(cf, input_file, label='file_name:', & + default="./default.nc", rc=rc) ++ +
+ +
+A second reminder that the order in which a particular label/value pair is + retrieved is not dependent upon the order which they exist within the + Resource File. The label used in this method allows the user to skip to + any point in the file. +
+
+ call ESMF_ConfigFindLabel(cf, 'constants:', rc=rc) ! Step a) Find the + ! label ++ +
+Two constants, radius and i_n, can now be retrieved without having to specify their + label or use an array. They are also different types. +
+
+ call ESMF_ConfigGetAttribute(cf, param_1, rc=rc) ! Step b) read in the + ! first constant in + ! the sequence + call ESMF_ConfigGetAttribute(cf, i_n, rc=rc) ! Step c) read in the + ! second constant in + ! the sequence ++ +
+This methodology also works with strings. +
+
+ call ESMF_ConfigFindLabel(cf, 'my_file_names:', & + rc=rc) ! Step a) find the label ++ +
+
+ call ESMF_ConfigGetAttribute(cf, fn1, & + rc=rc) ! Step b) retrieve the 1st filename + call ESMF_ConfigGetAttribute(cf, fn2, & + rc=rc) ! Step c) retrieve the 2nd filename + call ESMF_ConfigGetAttribute(cf, fn3, & + rc=rc) ! Step d) retrieve the 3rd filename ++ +
+ +
+To access tabular data, the user must use the multi-value method. +
+
+ call ESMF_ConfigFindLabel(cf, 'my_table_name::', & + rc=rc) ! Step a) Set the label location to the + ! beginning of the table ++ +
+Subsequently, call ESMF_ConfigNextLine() is used to move the location + to the next row of the table. The example table in the Resource File contains + 7 rows and 3 columns (7,3). +
+
+ do i = 1, 7 + call ESMF_ConfigNextLine(cf, rc=rc) ! Step b) Increment the rows + do j = 1, 3 ! Step c) Fill in the table + call ESMF_ConfigGetAttribute(cf, table(i,j), rc=rc) + enddo + enddo ++ +
+ +
+The work with the Config object cf is finalized by callling + ESMF_ConfigDestroy(). +
+
+ call ESMF_ConfigDestroy(cf, rc=rc) ! Destroy the Config object ++ +
+ +
+The Config class supports loading of YAML files. As before, an empty Config + object is created with ESMF_ConfigCreate() and then populated via the + ESMF_ConfigLoadFile() method. +
+
+ cf = ESMF_ConfigCreate(rc=rc) ! Create the empty Config object ++ +
+Files ending in .yaml, .yml, or any combination of upper and lower + case letters that can be mapped to these two options, are interpreted as YAML + files. All other names are interpreted as classic Config RFs as + documented earlier. +
+
+ call ESMF_ConfigLoadFile(cf, "myResourceFile.yaml", & ! Load the YAML File + rc=rc) ! into the empty Config object ++ +
+Here the myResourceFile.yaml contains a YAML version of the previously + used myResourceFile.rc file contents: + +
+
+ # YAML representation of the myResourceFile.rc RF + + # mapping to sequences + + my_file_names: [jan87.dat, jan88.dat, jan89.dat] # all strings + constants: [3.1415, 25] # float and integer + my_favorite_colors: [green, blue, 022] + + # mapping to scalars + + radius_of_the_earth: 6.37E6 + parameter_1: 89 + parameter_2: 78.2 + input_file_name: dummy_input.nc + + # represent table as mapping to sequence of sequences + + my_table_name: + - [1000, 3000, 263.0] + - [ 925, 3000, 263.0] + - [ 850, 3000, 263.0] + - [ 700, 3000, 269.0] + - [ 500, 3000, 287.0] + - [ 400, 3000, 295.8] + - [ 300, 3000, 295.8] ++ +
+Notice that YAML support is limited to a small subset of the full YAML + language specification, allowing access through the classic Config API. + Specifically, the top level in the YAML file is expected to be a mapping + (dictionary) of scalar keys to any of the following three value options: + +
+As an example, access the my_table_name element: +
+
+ call ESMF_ConfigFindLabel(cf, 'my_table_name::', & + rc=rc) ! Step a) Set the label location to the + ! beginning of the table ++ +
+When done, the resources held by the Config object are released by calling + the ESMF_ConfigDestroy() method. +
+
+ call ESMF_ConfigDestroy(cf, rc=rc) ! Destroy the Config object ++ +
+ +
+The Config class supports creating a Config object from a HConfig object. + Here the HConfig object is created from the same YAML file as used before. +
+
+ ! Create HConfig object + hconfig = ESMF_HConfigCreate(filename="myResourceFile.yaml", rc=rc) ++ +
+The myResourceFile.yaml contains the following YAML contents: + +
+
+ # YAML representation of the myResourceFile.rc RF + + # mapping to sequences + + my_file_names: [jan87.dat, jan88.dat, jan89.dat] # all strings + constants: [3.1415, 25] # float and integer + my_favorite_colors: [green, blue, 022] + + # mapping to scalars + + radius_of_the_earth: 6.37E6 + parameter_1: 89 + parameter_2: 78.2 + input_file_name: dummy_input.nc + + # represent table as mapping to sequence of sequences + + my_table_name: + - [1000, 3000, 263.0] + - [ 925, 3000, 263.0] + - [ 850, 3000, 263.0] + - [ 700, 3000, 269.0] + - [ 500, 3000, 287.0] + - [ 400, 3000, 295.8] + - [ 300, 3000, 295.8] ++ +
+A Config object can be created from the HConfig object simply by passing + hconfig into ESMF_CreateConfig() as argument. +
+
+ ! Create Config object from HConfig + cf = ESMF_ConfigCreate(hconfig=hconfig, rc=rc) ++ +
+Notice that cf uses the specified hconfig object via reference. + It remains the callers responsibility to destroy the hconfig object + when finished. Care must be taken to not destroy until access via + cf is complete. + +
+Here, as an example, access the my_table_name element: +
+
+ call ESMF_ConfigFindLabel(cf, 'my_table_name::', & + rc=rc) ! Step a) Set the label location to the + ! beginning of the table ++ +
+
+ call ESMF_ConfigDestroy(cf, rc=rc) ! Destroy the Config object ++ +
+As discussed above, the hconfig object requires its own destroy call + for a complete release. +
+
+ call ESMF_HConfigDestroy(hconfig, rc=rc) ! Destroy the HConfig object ++ +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + config1 = config2 +ARGUMENTS: +
type(ESMF_Config) :: config1 + type(ESMF_Config) :: config2 ++DESCRIPTION: +
+Assign config1 as an alias to the same ESMF_Config object in memory + as config2. If config2 is invalid, then config1 will be + equally invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (config1 == config2) then ... endif + OR + result = (config1 == config2) +RETURN VALUE: +
configical :: result +ARGUMENTS: +
type(ESMF_Config), intent(in) :: config1 + type(ESMF_Config), intent(in) :: config2 ++DESCRIPTION: +
+Overloads the (==) operator for the ESMF_Config class. + Compare two configs for equality; return .true. if equal, + .false. otherwise. Comparison is based on whether the objects + are distinct, as with two newly created objects, or are simply aliases + to the same object as would be the case when assignment was involved. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (config1 /= config2) then ... endif + OR + result = (config1 /= config2) +RETURN VALUE: +
configical :: result +ARGUMENTS: +
type(ESMF_Config), intent(in) :: config1 + type(ESMF_Config), intent(in) :: config2 ++DESCRIPTION: +
+Overloads the (/=) operator for the ESMF_Config class. + Compare two configs for equality; return .true. if not equivalent, + .false. otherwise. Comparison is based on whether the Config objects + are distinct, as with two newly created objects, or are simply aliases + to the same object as would be the case when assignment was involved. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ConfigCreate() + type(ESMF_Config) function ESMF_ConfigCreateDefault(hconfig, rc) +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_HConfig), intent(in), optional :: hconfig + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Instantiates an ESMF_Config object. Optionally create from HConfig. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_ConfigCreate() + type(ESMF_Config) function ESMF_ConfigCreateFromSection(config, & + openlabel, closelabel, rc) +ARGUMENTS: +
type(ESMF_Config) :: config + character(len=*), intent(in) :: openlabel, closelabel + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer,intent(out), optional :: rc ++DESCRIPTION: +
+Instantiates an ESMF_Config object from a section of an existing + ESMF_Config object delimited by openlabel and closelabel. + An error is returned if neither of the input labels is found in input + config. + +
+Note that a section is intended as the content of a given ESMF_Config + object delimited by two distinct labels. Such content, as well as each of the + surrounding labels, are still within the scope of the parent ESMF_Config + object. Therefore, including in a section labels used outside that + section should be done carefully to prevent parsing conflicts. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigDestroy(config, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroys the config object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigFindLabel(config, label, isPresent, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + character(len=*), intent(in) :: label + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(out), optional :: isPresent + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Finds the label (key) string in the config object + starting from the beginning of its content. + +
+Since the search is done by looking for a string, possibly multi-worded, + in the whole Config object, it is important to use special + conventions to distinguish labels from other words. This is done + in the Resource File by using the NASA/DAO convention to finish + line labels with a colon (:) and table labels with a double colon (::). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigFindNextLabel(config, label, isPresent, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + character(len=*), intent(in) :: label + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(out), optional :: isPresent + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Finds the label (key) string in the config object, + starting from the current position pointer. + +
+This method is equivalent to ESMF_ConfigFindLabel, but the search + is performed starting from the current position pointer. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigGet(config, hconfig, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_HConfig), intent(out), optional :: hconfig + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access Config internals. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigGetAttribute(config, <value>, & + label, default, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + <value argument>, see below for supported values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: label + character(len=*), intent(in), optional :: default + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets a value from the config object. When the + value is a sequence of characters + it will be terminated by the first white space. + +
+Supported values for <value argument> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigGetAttribute(config, <value list argument>, & + count, label, default, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + <value list argument>, see below for values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in) optional :: count + character(len=*), intent(in), optional :: label + character(len=*), intent(in), optional :: default + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets a list of values from the config object. + +
+Supported values for <value list argument> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigGetChar(config, value, & + label, default, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + character, intent(out) :: value + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: label + character, intent(in), optional :: default + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets a character value from the config object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigGetDim(config, lineCount, columnCount, & + label, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + integer, intent(out) :: lineCount + integer, intent(out) :: columnCount + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: label + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Returns the number of lines in the table in lineCount and + the maximum number of words in a table line in columnCount. + +
+After the call, the line pointer is positioned to the end of the table. + To reset it to the beginning of the table, use ESMF_ConfigFindLabel. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
integer function ESMF_ConfigGetLen(config, label, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: label + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Gets the length of the line in words by counting words + disregarding types. Returns the word count as an integer. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_ConfigIsCreated(config, rc) +RETURN VALUE: +
logical :: ESMF_ConfigIsCreated +ARGUMENTS: +
type(ESMF_Config), intent(in) :: config + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the config has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigLoadFile(config, filename, & + delayout, & ! DEPRECATED ARGUMENT + unique, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + character(len=*), intent(in) :: filename + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_DELayout), intent(in), optional :: delayout ! DEPRECATED ARGUMENT + logical, intent(in), optional :: unique + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+The resource file named filename is loaded into memory. Both the + classic Config file format, described in this document, and the YAML file + format are supported. YAML support is limited to a small subset of the full + YAML language specification, allowing access through the classic Config API. + Specifically, in YAML mode, the top level is expected to be a mapping + (dictionary) of scalar keys to the following value options: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigLog(config, raw, prefix, logMsgFlag, & + log, rc) +ARGUMENTS: +
type(ESMF_Config), intent(in) :: config + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: raw + character (len=*), intent(in), optional :: prefix + type(ESMF_LogMsg_Flag), intent(in), optional :: logMsgFlag + type(ESMF_Log), intent(inout), optional :: log + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write content of ESMF_Config object to ESMF log. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigNextLine(config, tableEnd, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(out), optional :: tableEnd + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Selects the next line (for tables). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigPrint(config, unit, rc) +ARGUMENTS: +
type(ESMF_Config), intent(in) :: config + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, optional, intent(in) :: unit + integer, optional, intent(out) :: rc ++DESCRIPTION: +
+Write content of input ESMF_Config object to unit unit. + If unit not provided, writes to standard output. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigSetAttribute(config, <value argument>, & + label, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + <value argument>, see below for supported values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: label + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Sets a value in the config object. + +
+Supported values for <value argument> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_ConfigValidate(config, & + options, rc) +ARGUMENTS: +
type(ESMF_Config), intent(inout) :: config + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len=*), intent(in), optional :: options + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Checks whether a config object is valid. + +
+The arguments are: +
+ + +
+The ESMF HConfig class implements a hierarchical configuration facility that is +compatible with YAML Ain't Markup Language (YAMLTM). ESMF HConfig +can be understood as a Fortran interface to YAML. However, no claim is made that +all YAML language features are supported in their entirety. + +
+The purpose of the HConfig class under ESMF is to provide a migration path +toward more standard configuration management for ESMF applications. To this end +ESMF_HConfig integrates with the traditional ESMF_Config class. Through this +integration the traditional Config class API offers basic access to YAML +configuration files, in addition to providing backward compatible support of the +traditional config file format. This is discussed in more detail in the Config +class section. For more complete YAML support, applications are encouraged to +migrate to the HConfig API discussed in this section. + +
+ +
+DESCRIPTION:
+
+Indicates the level to which two HConfig variables match.
+
+
+The type of this flag is: + +
+type(ESMF_HConfigMatch_Flag) + +
+The valid values in ascending order are: +
+The following examples demonstrate how a user typically interacts with the +HConfig API. The HConfig class introduces two derived types: + +
+ESMF_HConfig objects can be created explicitly by the user, or they +can be accessed from an existing ESMF_Config object, e.g. queried from +a Component. They can play a number of roles when interacting with +a HConfig hierarchy: + +
+ +
+ESMF_HConfigIter objects are iterators, referencing a specific +node within the hierarchy. They are created from ESMF_HConfig objects. +The iterator approach allows convenient sequential traversal of a particular +location in the HConfig hierarchy. There are two flavors of iterators in +HConfig: sequence and map iterators. +Both are represented by the same ESMF_HConfigIter derived type, and the +distinction is made at run-time. + +
+Notice that there are redundancies built into the HConfig API, where different +ways are available to achieve the same goal. This is mostly done for +convenience, allowing the user to pick the approach most suitable to their +needs. + +
+For instance, while it can be convenient to use iterators in some cases, in +others, it might be more appropriate to access elements directly by index +(for sequences) or key (for maps). Both options are available. + +
+ +
+ +
+ +
+ +
+By default, ESMF_HConfigCreate() creates an empty HConfig object. +
+
+ ! type(ESMF_HConfig) :: hconfig + hconfig = ESMF_HConfigCreate(rc=rc) ++ +
+ +
+An empty HConfig object can be set directly from a string using YAML + syntax. +
+
+ call ESMF_HConfigSet(hconfig, content="[1, 2, 3, abc, b, TRUE]", rc=rc) ++ +
+This sets hconfig as a sequence of six scalar members. + +
+ +
+One way to parse the elements contained in hconfig is to use the + iterator pattern known from laguages such as C++ or Python. HConfig + iterators are implemented as type(ESMF_HConfigIter) objects that + are initialized using one of the HConfigIter*() methods. An iterator + can then be used to traverse the elements in a sequence or map + by calling the ESMF_HConfigIterNext() method, taking one step forward + each time the method is called. + +
+Being a HConfig object, an iterator can be passed into any of the usual + HConfig methods. The operation is applied to the element that the iterator is + currently referencing. + +
+Notice that iterators are merely references, not associated with their own + deep allocation. This is reflected in the fact that iterators are + not created by an assignment that has a Create() call on the right + hand side. As such, HConfig iterators need not be destroyed + explicitly when done. + +
+Two special HConfig iterators are defined, referencing the beginning and + the end of a HConfig sequence or map object. +
+
+ ! type(ESMF_HConfigIter) :: hconfigIterBegin, hconfigIterEnd + hconfigIterBegin = ESMF_HConfigIterBegin(hconfig, rc=rc) ++ +
+
+ hconfigIterEnd = ESMF_HConfigIterEnd(hconfig, rc=rc) ++ +
+In analogy to the C++ iterator pattern, hconfigIterBegin points to the + first element in hconfig, while hconfigIterEnd points one step + beyond the last element. Using these elements together, an iterator loop + can be written in the following intuitive way, using hconfigIter as the + loop variable. +
+
+ ! type(ESMF_HConfigIter) :: hconfigIter + hconfigIter = hconfigIterBegin + do while (hconfigIter /= hconfigIterEnd) + + ! Code here that uses hconfigIter + ! to access the currently referenced + ! element in hconfig. ....... + + call ESMF_HConfigIterNext(hconfigIter, rc=rc) ++ +
+
+ enddo ++ +
+One major concern with the above iterator loop implementation is when + Fortran cycle statements are introduced. In orde to make the above loop + cycle-safe, each such cycle statement needs to be matched with + its own call to ESMF_HConfigIterNext(). This needs to be done to + prevent endless-loop conditions, where the exit condition of the + do while is never reached. + +
+The cycle-safe alternative implementation of the iterator loop + leverages the ESMF_HConfigIterLoop() function instead of + ESMF_HConfigIterNext(). This approach is more akin to the + C++ +
+ for (element : container){ + ... + } ++ or the Python +
+ for element in container: + ... ++ approach. It is the preferable way to write HConfig iterator loops due to its + simplicity and inherent cycle-safety. + +
+The ESMF_HConfigIterLoop() function takes three required arguments. + The first is the loop iterator, followed by the begin and end iterators. The + loop iterator must enter equal to the begin iterator at the start of the loop. + Each time the ESMF_HConfigIterLoop() function is called, the loop + iterator is stepped forward as appropriate, and the exit condition of having + reached the end iterator is checked. Having both the stepping and exit logic + in one place provided by the HConfig API simplifies the usage. In addition, + the approach is cycle-safe: no matter where a cycle statement is + inserted in the loop body, it always brings the execution back to the top of + the while loop, which in turn calls the ESMF_HConfigIterLoop() + function. +
+
+ ! type(ESMF_HConfigIter) :: hconfigIter + hconfigIter = hconfigIterBegin + do while (ESMF_HConfigIterLoop(hconfigIter, hconfigIterBegin, hconfigIterEnd, rc=rc)) ++ +
+
+ ! Check whether the current element is a scalar. + ! logical :: isScalar + isScalar = ESMF_HConfigIsScalar(hconfigIter, rc=rc) ++ +
+
+ if (isScalar) then + + ! Any scalar can be accessed as a string. + ! character(len=:), allocatable :: string + string = ESMF_HConfigAsString(hconfigIter, rc=rc) ++ +
+
+ ! The attempt can be made to interpret the scalar as any of the other + ! supported data types. By default, if the scalar cannot be interpreted + ! as the requested data type, rc /= ESMF_SUCCESS is returned. To prevent + ! such error condition, the optional, intent(out) argument "asOkay" can + ! be provided. If asOkay == .true. is returned, the interpretation was + ! successful. Otherwise asOkay == .false. is returned. + + ! logical :: asOkay + + ! integer(ESMF_KIND_I4) :: valueI4 + valueI4 = ESMF_HConfigAsI4(hconfigIter, asOkay=asOkay, rc=rc) ++ +
+
+ ! integer(ESMF_KIND_I8) :: valueI8 + valueI8 = ESMF_HConfigAsI8(hconfigIter, asOkay=asOkay, rc=rc) ++ +
+
+ ! real(ESMF_KIND_R4) :: valueR4 + valueR4 = ESMF_HConfigAsR4(hconfigIter, asOkay=asOkay, rc=rc) ++ +
+
+ ! real(ESMF_KIND_R8) :: valueR8 + valueR8 = ESMF_HConfigAsR8(hconfigIter, asOkay=asOkay, rc=rc) ++ +
+
+ ! logical :: valueL + valueL = ESMF_HConfigAsLogical(hconfigIter, asOkay=asOkay, rc=rc) ++ +
+
+ else + ! Possible recursive iteration over the current hconfigIter element. + endif + + enddo ++ +
+ +
+An alternative way to loop over the elements contained in hconfig, + and parsing them, is to use an index variable. For this approach the + size of hconfig is queried. +
+
+ ! integer :: size + size = ESMF_HConfigGetSize(hconfig, rc=rc) ++ +
+Then looping over the elements is done with a simple do loop. Index based + access allows random order of access, versus the iterator approach that + only supports begin to end iteration. This is demonstrated here by writing + the do loop in reverse order. +
+
+ ! integer :: i + do i=size, 1, -1 + + ! Check whether the current element is a scalar. + ! logical :: isScalar + isScalar = ESMF_HConfigIsScalar(hconfig, index=i, rc=rc) ++ +
+
+ if (isScalar) then + + ! Any scalar can be accessed as a string. + ! character(len=:), allocatable :: string + string = ESMF_HConfigAsString(hconfig, index=i, rc=rc) ++ +
+
+ ! The attempt can be made to interpret the scalar as any of the other + ! supported data types. By default, if the scalar cannot be interpreted + ! as the requested data type, rc /= ESMF_SUCCESS is returned. To prevent + ! such error condition, the optional, intent(out) argument "asOkay" can + ! be provided. If asOkay == .true. is returned, the interpretation was + ! successful. Otherwise asOkay == .false. is returned. + ! logical :: asOkay + + ! integer(ESMF_KIND_I4) :: valueI4 + valueI4 = ESMF_HConfigAsI4(hconfig, index=i, asOkay=asOkay, rc=rc) ++ +
+
+ ! integer(ESMF_KIND_I8) :: valueI8 + valueI8 = ESMF_HConfigAsI8(hconfig, index=i, asOkay=asOkay, rc=rc) ++ +
+
+ ! real(ESMF_KIND_R4) :: valueR4 + valueR4 = ESMF_HConfigAsR4(hconfig, index=i, asOkay=asOkay, rc=rc) ++ +
+
+ ! real(ESMF_KIND_R8) :: valueR8 + valueR8 = ESMF_HConfigAsR8(hconfig, index=i, asOkay=asOkay, rc=rc) ++ +
+
+ ! logical :: valueL + valueL = ESMF_HConfigAsLogical(hconfig, index=i, asOkay=asOkay, rc=rc) ++ +
+
+ else + ! Possible recursive iteration over the current index=i element. + endif + enddo ++ +
+The above loop is safe with respect to index potentially being specified + with an out-of-range value. This is because ESMF_HConfigIsScalar() + returns .false. in this case. There are only four valid options of what + type a valid HConfig element can be. Each has an associated Is + method: + +
+
+ ! logical :: isDefined + isDefined = ESMF_HConfigIsDefined(hconfig, index=10, rc=rc) ++ +
+This returns isDefined == .false. because for hconfig a value of + index=10 is out of range. + +
+ +
+When done with hconfig, it should be destroyed in the usual manner. +
+
+ call ESMF_HConfigDestroy(hconfig, rc=rc) ++ +
+ +
+The ESMF_HConfigCreate() method supports loading contents from + string using YAML syntax directly via the optional content argument. +
+
+ ! type(ESMF_HConfig) :: hconfig + hconfig = ESMF_HConfigCreate(content="{car: red, bike: 22, plane: TRUE}", rc=rc) ++ +
+Here a map is created. In this case, all of the keys are scalars (car, + bike, plane), as are all of the associated values (red, 22, TRUE). + +
+ +
+The elements of the map contained in hconfig can be iterated over + analogous to the sequence case demonstrated earlier. Again the begin + and end iterator variables are defined. +
+
+ ! type(ESMF_HConfigIter) :: hconfigIterBegin, hconfigIterEnd + hconfigIterBegin = ESMF_HConfigIterBegin(hconfig, rc=rc) ++ +
+
+ hconfigIterEnd = ESMF_HConfigIterEnd(hconfig, rc=rc) ++ +
+Then iterate over the elements in hconfig using an iterator loop + variable as before. + +
+The difference of the code below, compared to the sequence case, is + that all the As access methods here are either of the form + As*MapKey or As*MapVal. This is necessary to selectively access + the map key or map value, respectively. +
+
+ ! type(ESMF_HConfigIter) :: hconfigIter + hconfigIter = hconfigIterBegin + do while (ESMF_HConfigIterLoop(hconfigIter, hconfigIterBegin, hconfigIterEnd, rc=rc)) ++ +
+
+ ! Check whether the current element is a scalar both for the map key + ! and the map value. + ! logical :: isScalar + isScalar = ESMF_HConfigIsScalarMapKey(hconfigIter, rc=rc) ++ +
+
+ isScalar = isScalar .and. ESMF_HConfigIsScalarMapVal(hconfigIter, rc=rc) ++ +
+
+ if (isScalar) then + + ! Any scalar can be accessed as a string. Use this for the map key. + ! character(len=:), allocatable :: stringKey + stringKey = ESMF_HConfigAsStringMapKey(hconfigIter, rc=rc) ++ +
+
+ ! Now access the map value. Again first access as a string, which + ! always works. + ! character(len=:), allocatable :: string + string = ESMF_HConfigAsStringMapVal(hconfigIter, rc=rc) ++ +
+
+ ! The attempt can be made to interpret the scalar as any of the other + ! supported data types. By default, if the scalar cannot be interpreted + ! as the requested data type, rc /= ESMF_SUCCESS is returned. To prevent + ! such error condition, the optional, intent(out) argument "asOkay" can + ! be provided. If asOkay == .true. is returned, the interpretation was + ! successful. Otherwise asOkay == .false. is returned. + ! logical :: asOkay + + ! integer(ESMF_KIND_I4) :: valueI4 + valueI4 = ESMF_HConfigAsI4MapVal(hconfigIter, asOkay=asOkay, rc=rc) ++ +
+
+ ! integer(ESMF_KIND_I8) :: valueI8 + valueI8 = ESMF_HConfigAsI8MapVal(hconfigIter, asOkay=asOkay, rc=rc) ++ +
+
+ ! real(ESMF_KIND_R4) :: valueR4 + valueR4 = ESMF_HConfigAsR4MapVal(hconfigIter, asOkay=asOkay, rc=rc) ++ +
+
+ ! real(ESMF_KIND_R8) :: valueR8 + valueR8 = ESMF_HConfigAsR8MapVal(hconfigIter, asOkay=asOkay, rc=rc) ++ +
+
+ ! logical :: valueL + valueL = ESMF_HConfigAsLogicalMapVal(hconfigIter, asOkay=asOkay, rc=rc) ++ +
+
+ else + ! Deal with case where either key or value are not scalars themselves. + endif + + enddo ++ +
+ +
+The map values stored in hconfig can be accessed + in random order providing the map key. + +
+To demonstrate this, a temporary array holding keys in random order is defined. +
+
+ ! character(5) :: keyList(3) + keyList = ["bike ", "plane", "car "] ++ +
+Then loop over the elements of keyList and use them as map key + to access the map values in hconfig. +
+
+ ! integer :: i + do i=1,3 + + ! Ensure that all white space padding is removed. + ! character :: stringKey + stringKey = trim(keyList(i)) + + ! Check whether the accessed map value is a scalar. + ! logical :: isScalar + isScalar = ESMF_HConfigIsScalar(hconfig, keyString=stringKey, rc=rc) ++ +
+
+ if (isScalar) then + + ! Access as a string always works. + ! character(len=:), allocatable :: string + string = ESMF_HConfigAsString(hconfig, keyString=stringKey, rc=rc) ++ +
+
+ ! The attempt can be made to interpret the scalar as any of the other + ! supported data types. By default, if the scalar cannot be interpreted + ! as the requested data type, rc /= ESMF_SUCCESS is returned. To prevent + ! such error condition, the optional, intent(out) argument "asOkay" can + ! be provided. If asOkay == .true. is returned, the interpretation was + ! successful. Otherwise asOkay == .false. is returned. + ! logical :: asOkay + + ! integer(ESMF_KIND_I4) :: valueI4 + valueI4 = ESMF_HConfigAsI4(hconfig, keyString=stringKey, asOkay=asOkay, rc=rc) ++ +
+
+ ! integer(ESMF_KIND_I8) :: valueI8 + valueI8 = ESMF_HConfigAsI8(hconfig, keyString=stringKey, asOkay=asOkay, rc=rc) ++ +
+
+ ! real(ESMF_KIND_R4) :: valueR4 + valueR4 = ESMF_HConfigAsR4(hconfig, keyString=stringKey, asOkay=asOkay, rc=rc) ++ +
+
+ ! real(ESMF_KIND_R8) :: valueR8 + valueR8 = ESMF_HConfigAsR8(hconfig, keyString=stringKey, asOkay=asOkay, rc=rc) ++ +
+
+ ! logical :: valueL + valueL = ESMF_HConfigAsLogical(hconfig, keyString=stringKey, asOkay=asOkay, rc=rc) ++ +
+
+ else + ! Deal with case where either key or value are not scalars themselves. + endif + + enddo ++ +
+The above loop is safe with respect to stringKey potentially + specifying a value that is not a valid map key. This is because + ESMF_HConfigIsScalar() returns .false. in this case. + +
+The general check to see whether a map key refers to a valid element + is provided by ESMF_HConfigIsDefined(). +
+
+ ! logical :: isDefined + isDefined = ESMF_HConfigIsDefined(hconfig, keyString="bad-key", rc=rc) ++ +
+This returns isDefined == .false. because hconfig does not + contain "bad-key" as one of its valid map keys. + +
+Finally destroy hconfig when done. +
+
+ call ESMF_HConfigDestroy(hconfig, rc=rc) ++ +
+ +
+The ESMF_Config class can be queried for a HConfig object. This allows + the use of the HConfig API to access information contained in a Config object. +
+
+ ! type(ESMF_Config) :: config + ! type(ESMF_HConfig) :: hconfig + call ESMF_ConfigGet(config, hconfig=hconfig, rc=rc) ++ +
+The hconfig obtained this way is indistinguishable from an explicitly + created HConfig instance. E.g. it can be queried for its type using the + Is methods: +
+
+ ! logical :: isDefined + isDefined = ESMF_HConfigIsDefined(hconfig, rc=rc) ++ +
+
+ ! logical :: isNull + isNull = ESMF_HConfigIsNull(hconfig, rc=rc) ++ +
+
+ ! logical :: isSequence + isSequence = ESMF_HConfigIsSequence(hconfig, rc=rc) ++ +
+
+ ! logical :: isMap + isMap = ESMF_HConfigIsMap(hconfig, rc=rc) ++ +
+Once done with hconfig it must not be destroyed explicitly by + the user. The hconfig is still owned by the config object, and + will be destroyed automatically when the config object is destroyed. + This follows the simple rule that a user only owns those objects created + explicitly by calling a Create() method. + +
+ +
+One option to load a YAML file is to first create an empty HConfig object, + followed by calling ESMF_HConfigFileLoad(). +
+
+ ! type(ESMF_HConfig) :: hconfig + hconfig = ESMF_HConfigCreate(rc=rc) ++ +
+
+ call ESMF_HConfigFileLoad(hconfig, filename="example.yaml", rc=rc) ++ +
+
+ ! When done destroy as usual. + call ESMF_HConfigDestroy(hconfig, rc=rc) ++ +
+The alternative option is to create and load the HConfig object in a single + call to ESMF_HConfigCreate() using the optional filename + argument to specify the YAML file. +
+
+ ! type(ESMF_HConfig) :: hconfig + hconfig = ESMF_HConfigCreate(filename="example.yaml", rc=rc) ++ +
+
+ ! And again destroy hconfig when done with it. + call ESMF_HConfigDestroy(hconfig, rc=rc) ++ +
+ +
+A HConfig object can be saved to a YAML file by calling the + ESMF_HConfigFileSave() method. To demonstrate this, a YAML file + containing: +
+ # An example of YAML configuration file + + simple_list: [1, 2, 3, abc, b, TRUE] + simple_map: + car: red + [bike, {p1: 10, p2: 20}]: [bmx, mountain, street] + plane: [TRUE, FALSE] ++ +
+is loaded to create the hconfig object: +
+
+ hconfig = ESMF_HConfigCreate(filename="example.yaml", rc=rc) ++ +
+Now the hconfig object can be saved to file using the + ESMF_HConfigFileSave() method. +
+
+ call ESMF_HConfigFileSave(hconfig, filename="saveMe.yml", rc=rc) ++ +
+Notice that the resulting contents of file saveMe.yml does not + contain the comments of the original file. The YAML structure is saved. +
+ simple_list: [1, 2, 3, abc, b, TRUE] + simple_map: + car: red + [bike, {p1: 10, p2: 20}]: [bmx, mountain, street] + plane: [TRUE, FALSE] ++ +
+The object specified in ESMF_HConfigFileSave() can be a regular node + (of any type) or a sequence iterator. In either case the file written + represents the YAML hierarchy with the specified object as the root node. + +
+In the case of a map iterator, it is necessary to first create an + appropriate root node utilizing the appropriate CreateAt method. This + allows saving either the map key or map value node at the + current iterator. This is demonstrated below. + +
+In the current example, where hconfig is a map with two elements, a + map iterator can be set to the beginning using the following call. +
+
+ ! type(ESMF_HConfigIter) :: hconfigIter + hconfigIter = ESMF_HConfigIterBegin(hconfig, rc=rc) ++ +
+Here hconfigIter cannot be saved to file directly. To write the + key node, first create a HConfig object for it using method + ESMF_HConfigCreateAtMapKey(). +
+
+ ! type(ESMF_HConfig) :: hconfigTemp + hconfigTemp = ESMF_HConfigCreateAtMapKey(hconfigIter, rc=rc) ++ +
+Then save it. +
+
+ call ESMF_HConfigFileSave(hconfigTemp, filename="mapKeyBegin.yaml", rc=rc) ++ +
+And finally destroy hconfigTemp again. +
+
+ call ESMF_HConfigDestroy(hconfigTemp, rc=rc) ++ +
+Similarly, to write the value node to file, first create a HConfig + object for it using method ESMF_HConfigCreateAtMapVal(). +
+
+ ! type(ESMF_HConfig) :: hconfigTemp + hconfigTemp = ESMF_HConfigCreateAtMapVal(hconfigIter, rc=rc) ++ +
+Then save it. +
+
+ call ESMF_HConfigFileSave(hconfigTemp, filename="mapValBegin.yaml", rc=rc) ++ +
+And destroy it. +
+
+ call ESMF_HConfigDestroy(hconfigTemp, rc=rc) ++ +
+Since hconfig is a map node, it is also possible to directly + create a value node by calling ESMF_HConfigCreateAt() + on it, using the desired key. +
+
+ ! type(ESMF_HConfig) :: hconfigTemp + hconfigTemp = ESMF_HConfigCreateAt(hconfig, keyString="simple_map", rc=rc) ++ +
+Now hconfigTemp points to the value node, that is + associated with the "simple_map" key, which is in turn a map: +
+ car: red + [bike, {p1: 10, p2: 20}]: [bmx, mountain, street] + plane: [TRUE, FALSE] ++ It can be saved to file as usual. +
+
+ call ESMF_HConfigFileSave(hconfigTemp, filename="mapValAtKey.yaml", rc=rc) ++ +
+Any of the value nodes of hconfigTemp can be accessed through + recursive usage of the ESMF_HConfigCreateAt() method. + For example, the following call accesses the value node that is + associated with keyString="[bike, p1: 10, p2: 20]". Here the + keyString is interpreted as YAML syntax, for which an internal HConfig + representation is created, and finally the map held by hconfigTemp is + searched for a matching key. +
+
+ ! type(ESMF_HConfig) :: hconfigTemp2 + hconfigTemp2 = ESMF_HConfigCreateAt(hconfigTemp, & + keyString="[bike, {p1: 10, p2: 20}]", rc=rc) ++ +
+Now hconfigTemp2 points to the sequence node with contents + [bmx, mountain, street]. It, too, can be saved to file. +
+
+ call ESMF_HConfigFileSave(hconfigTemp2, filename="mapValRecursive.yaml", rc=rc) ++ +
+Finally hconfigTemp2, hconfigTemp and hconfig should be destroyed. +
+
+ call ESMF_HConfigDestroy(hconfigTemp2, rc=rc) ++ +
+
+ call ESMF_HConfigDestroy(hconfigTemp, rc=rc) ++ +
+
+ call ESMF_HConfigDestroy(hconfig, rc=rc) ++ +
+ +
+The HConfig class implements tags to identify a node's data type according to + the YAML standard. The combination of a set of defined tags and a mechanism + to resolve non-specific tags is called a schema under YAML. The HConfig class + implements the YAML Core schema, which is an extension of the JSON schema. + +
+This example starts with an empty HConfig object. +
+
+ ! type(ESMF_HConfig) :: hconfig + hconfig = ESMF_HConfigCreate(rc=rc) ++ +
+Method ESMF_HConfigGetTag() is used to query the tag. +
+
+ ! character(len=:), allocatable :: tag + tag = ESMF_HConfigGetTag(hconfig, rc=rc) ++ +
+ +
+Next, file exampleWithTags.yaml is loaded. +
+
+ call ESMF_HConfigFileLoad(hconfig, filename="exampleWithTags.yaml", rc=rc) ++ +
+The file contains the following YAML: +
+ value_one: {word1: this, word2: is, word3: a, word4: map} + value_two: [this, is, a, list] + value_three: 123 + value_four: !!float 123 + value_five: 2.5 + value_six: !!str 2.5 + value_seven: False + value_eight: !!str true + value_nine: 0x234 + value_ten: Null + value_eleven: + value_twelve: !myStuff xyz + value_thirteen: NO + value_fourteen: "NO" ++ +
+The value associated with map key "value_ten" is explicitly set to + Null. The associated tag for this node can be obtained + directly by supplying the keyString argument. +
+
+ tag = ESMF_HConfigGetTag(hconfig, keyString="value_ten", rc=rc) ++ +
+The resolved Core schema tag is again tag:yaml.org,2002:null. There + are four special values that resolve to this tag: null, Null, + NULL, and . In addition to those special values, an empty + value, as demonstrated by key "value_eleven", also automatically + resolves to tag:yaml.org,2002:null. +
+
+ tag = ESMF_HConfigGetTag(hconfig, keyString="value_eleven", rc=rc) ++ +
+ +
+
+ tag = ESMF_HConfigGetTag(hconfig, rc=rc) ++ +
+results in the Core schema tag of tag:yaml.org,2002:map. + +
+ +
+
+ tag = ESMF_HConfigGetTag(hconfig, keyString="value_two", rc=rc) ++ +
+The resolved Core schema tag for a sequence is tag:yaml.org,2002:seq. + +
+ +
+
+ ! type(ESMF_HConfigIter) :: hconfigIter + hconfigIter = ESMF_HConfigIterBegin(hconfig, rc=rc) ++ +
+Now the ESMF_HConfigGetTagMapKey() method can be used to obtain + the tag for the first key node. +
+
+ tag = ESMF_HConfigGetTagMapKey(hconfigIter, rc=rc) ++ +
+Here the Core schema tag resolves to tag:yaml.org,2002:str. + +
+ +
+
+ tag = ESMF_HConfigGetTag(hconfig, keyString="value_three", rc=rc) ++ +
+The Core schema tag resolves to tag:yaml.org,2002:int. + +
+The value associated with map key "value_nine" in the current + hconfig object is an integer number in hex. The tag for this node can be + obtained as before by directly supplying the keyString argument. +
+
+ tag = ESMF_HConfigGetTag(hconfig, keyString="value_nine", rc=rc) ++ +
+The Core schema tag resolves to tag:yaml.org,2002:int. + +
+ +
+
+ tag = ESMF_HConfigGetTag(hconfig, keyString="value_five", rc=rc) ++ +
+The Core schema tag resolves to tag:yaml.org,2002:float. + +
+ +
+
+ tag = ESMF_HConfigGetTag(hconfig, keyString="value_seven", rc=rc) ++ +
+The Core schema tag resolves to tag:yaml.org,2002:bool. The + supported boolean values are: +
+ true | false + True | False + TRUE | FALSE ++ +
+ +
+ yes | no + Yes | No + YES | NO + y | n + Y | N + on | off + On | Off + ON | OFF ++ The interpretation of value NO as a boolean, instead of a literal + string, can be problematic. It leads to the so-called "Norway problem", + because the same string is often used as country code instead. The underlying + problem is the misinterpretation of values by YAML. + +
+Strictly speaking this is not a YAML problem, but instead a schema specific + issue. Fortunately there are two simple solutions to ensure the correct and + intended interpretation of values by ESMF_HConfig: + +
+ +
+
+ +
+
+ tag = ESMF_HConfigGetTag(hconfig, keyString="value_four", rc=rc) ++ +
+
+ tag = ESMF_HConfigGetTag(hconfig, keyString="value_six", rc=rc) ++ +
+
+ tag = ESMF_HConfigGetTag(hconfig, keyString="value_eight", rc=rc) ++ +
+The default resolution of these three keys would be + tag:yaml.org,2002:int, tag:yaml.org,2002:float, and + tag:yaml.org,2002:bool, respectively. However, with the explict tags + in place, they are resolved to tag:yaml.org,2002:float, + tag:yaml.org,2002:str, tag:yaml.org,2002:str, instead. + +
+ +
+The value associated with map key "value_twelve" in the current + hconfig object has a custom tag. The tag for this node can be + obtained as before by directly supplying the keyString argument. +
+
+ tag = ESMF_HConfigGetTag(hconfig, keyString="value_twelve", rc=rc) ++ +
+The returned tag is !myStuff. + +
+Finally clean up hconfig. +
+
+ ! Destroy hconfig when done with it. + call ESMF_HConfigDestroy(hconfig, rc=rc) ++ +
+ +
+The HConfig class follows the standard behavior of ESMF deep classes as + described in section 8.4. To demonstrate + the operations of assignment, equality, and comparison based on content, we + start by creating a simple HConfig object. +
+
+ ! type(ESMF_HConfig) :: hconfig + hconfig = ESMF_HConfigCreate(content="{car: red, bike: 22, plane: TRUE}", rc=rc) ++ +
+A simple assignment results in an alias to the same deep HConfig object. +
+
+ ! type(ESMF_HConfig) :: hconfigTemp + hconfigTemp = hconfig ++ +
+The equality (==) and inequality (/=) operators are + overloaded to check for the alias condition when used between two + HConfig objects. +
+
+ ! logical :: isAlias + isAlias = (hconfigTemp == hconfig) ++ +
+
+ ! logical :: isNotAlias + isNotAlias = (hconfigTemp /= hconfig) ++ +
+Alias equality can also be tested by using the ESMF_HConfigMatch() + function. The return value of this function is of type + ESMF_HConfigMatch_Flag, which allows for a wider range of possible + comparison results. See section 48.2.1 for all the + implemented return values. +
+
+ ! type(ESMF_HConfigMatch_Flag) :: match + match = ESMF_HConfigMatch(hconfig, hconfigTemp, rc=rc) ++ +
+For the case of an alias match, the value of ESMF_HCONFIGMATCH_ALIAS + is returned. +
+
+ isAlias = (match == ESMF_HCONFIGMATCH_ALIAS) ++ +
+To demonstrate content matching for HConfig objects that are not aliases, we + create a separate object with the same content as hconfig. +
+
+ ! type(ESMF_HConfig) :: hconfigTemp + hconfigTemp = ESMF_HConfigCreate(content="{car: red, bike: 22, plane: TRUE}", rc=rc) ++ +
+The simple alias check now returns .false.. +
+
+ ! logical :: isAlias + isAlias = (hconfigTemp == hconfig) ++ +
+However, for two separate HConfig objects that have exactly matching + content, as is the case for hconfig and hconfigTemp, function + ESMF_HConfigMatch() returns value ESMF_HCONFIGMATCH_EXACT. +
+
+ ! type(ESMF_HConfigMatch_Flag) :: match + match = ESMF_HConfigMatch(hconfig, hconfigTemp, rc=rc) ++ +
+
+ ! logical :: isExact + isExact = (match == ESMF_HCONFIGMATCH_EXACT) ++ +
+The values returned by ESMF_HConfigMatch() are constructed in + a monotonically increasing manner to simplify general comparisons that + ensure two objects are either aliases of each other or their content + matches exactly. This common case is demonstrated in the following code that + sets isMatch to .true. for the alias or exact match condition, + and .false. otherwise, using (>=) logic. +
+
+ ! logical :: isMatch + isMatch = (match >= ESMF_HCONFIGMATCH_EXACT) ++ +
+While there is an exact match of the content of hconfig and + hconfigTemp, they are distinct objects in memory, which can be modified + independent of each other. E.g. another key-value pair can be added to + hconfigTemp without affecting the content of hconfig. +
+
+ call ESMF_HConfigAdd(hconfigTemp, addKeyString="kNew", content=7, rc=rc) ++ +
+Now that the content of hconfig and hconfigTemp differs, function + ESMF_HConfigMatch() returns value ESMF_HCONFIGMATCH_NONE. +
+
+ ! type(ESMF_HConfigMatch_Flag) :: match + match = ESMF_HConfigMatch(hconfig, hconfigTemp, rc=rc) ++ +
+
+ ! logical :: isNone + isNone = (match == ESMF_HCONFIGMATCH_NONE) ++ +
+Finally clean up both HConfig objects. +
+
+ ! Destroy hconfig when done with it. + call ESMF_HConfigDestroy(hconfig, rc=rc) ++ +
+
+ ! Destroy hconfigTemp when done with it. + call ESMF_HConfigDestroy(hconfigTemp, rc=rc) ++ +
+ +
+After creating a HConfig object without specifying content or + filename, it is empty. +
+
+ ! type(ESMF_HConfig) :: hconfig + hconfig = ESMF_HConfigCreate(rc=rc) ++ +
+Now the ESMF_HConfigAdd() method can be used to add new elements to + an existing HConfig object. The Add() interfaces are heavily overloaded, + each specific entry point featuring a number of optional arguments. The two + fundamentally different ways of using Add() are: (1) adding an element + at the end of a sequence or (2) adding an element to a map. + Here, where hconfig is empty, either option is possible. The way the + first element is added determines whether hconfig is a sequence or + a map. + +
+The following call adds an element to hconfig without specifying the + addKey or addKeyString argument. This indicates that a sequence + element is added to the end, and as a consequence rendering hconfig + a sequence. +
+
+ call ESMF_HConfigAdd(hconfig, "first added item", rc=rc) ++ +
+Additional elements can be added at the end of hconfig. +
+
+ call ESMF_HConfigAdd(hconfig, 12.57_ESMF_KIND_R8, rc=rc) ++ +
+At this point, the content of hconfig is a sequence with two elements. +
+ - first added item + - 12.5700000000 ++ +
+It is also possible to add an entire HConfig structure as an item to the + existing sequence. One way to do this is to use standar YAML syntax when + adding the element. Here a map is added to the end of hconfig. +
+
+ call ESMF_HConfigAdd(hconfig, "{k1: 7, k2: 25}", rc=rc) ++ +
+This results in the following content, where the third element of the sequence + is the map that was just added. +
+ - first added item + - 12.5700000000 + - {k1: 7, k2: 25} ++ +
+A HConfig structure can even be loaded from file and added to the end of + hconfig. This requires a temporary HConfig object. +
+
+ ! type(ESMF_HConfig) :: hconfigTemp + hconfigTemp = ESMF_HConfigCreate(filename="example.yaml", rc=rc) ++ +
+
+ call ESMF_HConfigAdd(hconfig, hconfigTemp, rc=rc) ++ +
+
+ call ESMF_HConfigDestroy(hconfigTemp, rc=rc) ++ +
+The result is the following content for hconfig. +
+ - first added item + - 12.5700000000 + - {k1: 7, k2: 25} + - simple_list: [1, 2, 3, abc, b, TRUE] + simple_map: + car: red + [bike, {p1: 10, p2: 20}]: [bmx, mountain, street] + plane: [TRUE, FALSE] ++ +
+Using the CreateAt() method, it is easy to gain access to any specific + element in hconfig. Since hconfig is a sequence, the proper + access is by index. +
+
+ ! type(ESMF_HConfig) :: hconfigTemp + hconfigTemp = ESMF_HConfigCreateAt(hconfig, index=3, rc=rc) ++ +
+This creates a temporary HConfig object that references the 3rd element + of the sequence stored by hconfig. If hconfigTemp were to be + saved to file, it would have the following content. +
+ {k1: 7, k2: 25} ++ +
+Using the Set() methods, contents in hconfigTemp, and thus in + the 3rd element of hconfig can be modified. The content of + hconfigTemp is a map, and the proper access is by map key. + Here key "k2" is being modified. +
+
+ call ESMF_HConfigSet(hconfigTemp, 12.5, keyString="k2", rc=rc) ++ +
+The hconfigTemp is a reference to a map, and new elements can be + added using the addKeyString argument. +
+
+ call ESMF_HConfigAdd(hconfigTemp, .true., addKeyString="k3", rc=rc) ++ +
+
+ call ESMF_HConfigDestroy(hconfigTemp, rc=rc) ++ +
+After these operations, the content of hconfig has changed to +
+ - first added item + - 12.5700000000 + - {k1: 7, k2: 12.5000000000, k3: True} + - simple_list: [1, 2, 3, abc, b, TRUE] + simple_map: + car: red + [bike, {p1: 10, p2: 20}]: [bmx, mountain, street] + plane: [TRUE, FALSE] ++ Notice that while hconfigTemp should be destroyed explicitly, as in the + example above, doing so does not affect the referenced node inside the + hconfig object. In other words, hconfigTemp was a reference, and + not a deep copy of the node! There is some allocated memory associated + with the hconfigTemp reference that gets cleaned up with the + Destroy() call, but it does not affect the reference itself. + +
+The Set() method can also be used to edit the element referenced + itself. Here the 4th element in the hconfig sequence is set to be a + simple scalar string value using this approach. +
+
+ ! type(ESMF_HConfig) :: hconfigTemp + hconfigTemp = ESMF_HConfigCreateAt(hconfig, index=4, rc=rc) ++ +
+
+ call ESMF_HConfigSet(hconfigTemp, "Simple scalar string value", rc=rc) ++ +
+
+ call ESMF_HConfigDestroy(hconfigTemp, rc=rc) ++ +
+The content of hconfig has been updated as below. +
+ - first added item + - 12.5700000000 + - {k1: 7, k2: 12.5000000000, k3: True} + - Simple scalar string value ++ +
+There is a simpler alternative for direct element editing in an + HConfig object via the Set() method. Using the index or + keyString argument, a sequence or map element, respectively, can + be edited directly. For instance, +
+
+ call ESMF_HConfigSet(hconfig, "[a, b, c]", index=4, rc=rc) ++ +
+sets the 4th element of hconfig directly, without the need of a + temporary HConfig variable. This updates the content to: +
+ - first added item + - 12.5700000000 + - {k1: 7, k2: 12.5000000000, k3: True} + - [a, b, c] ++ +
+Elements can be deleted from a HConfig object holding a sequence or map + using the Remove() method, specifying the index or + map key, respectively. Here the 2nd element of the sequence held by + hconfig is removed. +
+
+ call ESMF_HConfigRemove(hconfig, index=2, rc=rc) ++ +
+The result is a sequence with only three remaining elements. +
+ - first added item + - {k1: 7, k2: 12.5000000000, k3: True} + - [a, b, c] ++ +
+To demonstrate removal of an element from a map, the second + hconfig element is referenced by a temporary HConfig object. The element + with key "k2" is then removed using the respective Remove() method. +
+
+ ! type(ESMF_HConfig) :: hconfigTemp + hconfigTemp = ESMF_HConfigCreateAt(hconfig, index=2, rc=rc) ++ +
+
+ call ESMF_HConfigRemove(hconfigTemp, keyString="k2", rc=rc) ++ +
+
+ call ESMF_HConfigDestroy(hconfigTemp, rc=rc) ++ +
+The resulting hconfig content is as expected. +
+ - first added item + - {k1: 7, k3: True} + - [a, b, c] ++ +
+Finally the entire contents of hconfig can be deleted by setting the + node itself to one of the special NULL values. +
+
+ call ESMF_HConfigSet(hconfig, "NULL", rc=rc) ++ +
+If saved to file, the contents of hconfig shows up as a simple tilde + character, indicating its NULL value. +
+ ~ ++ +
+At this point hconfig is neither a sequence nor a map. It is + NULL. Adding a map element, i.e. an element with a key, turns + hconfig into a map. +
+
+ call ESMF_HConfigAdd(hconfig, "first added item", addKeyString="item1", rc=rc) ++ +
+The contents of hconfig now is a map with a single entry: + character, indicating its NULL value. +
+ item1: first added item ++ +
+As in other contexts before, the content as well as the specified + addKeyString can be of any legal YAML syntax. This is demonstrated + in the following Add() calls. +
+
+ ! Add YAML sequence content with simple scalar key. + call ESMF_HConfigAdd(hconfig, "[2, added, item]", addKeyString="item2", rc=rc) ++ +
+
+ ! Add simple scalar content with a YAML map as key. + call ESMF_HConfigAdd(hconfig, "third added item", addKeyString="{item: 3}", & + rc=rc) ++ +
+
+ ! Add complex YAML content with YAML sequence as key. + call ESMF_HConfigAdd(hconfig, "{4th: item, 5th: [true, false]}", & + addKeyString="[1, 2, 3, 4]", rc=rc) ++ +
+Resulting in the final contents of hconfig: +
+ item1: first added item + item2: [2, added, item] + {item: 3}: third added item + [1, 2, 3, 4]: {4th: item, 5th: [true, false]} ++ Finally clean up hconfig. +
+
+ ! Destroy hconfig when done with it. + call ESMF_HConfigDestroy(hconfig, rc=rc) ++ +
+ +
+The YAML standard supports multiple documents in a single file by separating + each document with a line containing three dashes (--). Optionally the + end of each document may be indicated by three periods (...). For example, + the following YAML file contains three documents (notice the optional usage + of the document end marker): +
+ --- + - This + - is + - the + - first document. + ... + --- + - And + - a second document. + --- + - And + - finally a + - third document. ++ All of the documents contained in a YAML file can be loaded into a single + HConfig object all at once. +
+
+ ! type(ESMF_HConfig) :: hconfig + hconfig = ESMF_HConfigCreate(filename="multiDoc.yaml", rc=rc) ++ +
+The number of documents held by hconfig can be queried. +
+
+ ! integer :: docCount + docCount = ESMF_HConfigGetDocCount(hconfig, rc=rc) ++ +
+When saving hconfig, a multi-document YAML file will be written. +
+
+ call ESMF_HConfigFileSave(hconfig, filename="multi_00.yaml", rc=rc) ++ +
+The ESMF_HConfigFileSave() method implements strict usage of both + document markers when saving a multi-document HConfig object. +
+ --- + - This + - is + - the + - first document. + ... + --- + - And + - a second document. + ... + --- + - And + - finally a + - third document. + ... ++ +
+The content of the hconfig object can be written to the ESMF log file + as usual. +
+
+ call ESMF_HConfigLog(hconfig, prefix="my-multi-doc: ", rc=rc) ++ +
+The optional doc argument can be specified to save or log a specific + document of the multi-document hconfig object. +
+
+ call ESMF_HConfigFileSave(hconfig, filename="multi_01.yaml", doc=2, rc=rc) ++ +
+This operation results in a single document file: +
+ - And + - a second document. ++ The ESMF_HConfigFileLoad() method also accepts the optional doc + argument. When specified, the result is a single-document hconfig + object, holding the content of the indicated document within the loaded file. +
+
+ call ESMF_HConfigFileLoad(hconfig, filename="multiDoc.yaml", doc=3, rc=rc) ++ +
+Saving hconfig to file shows the expected situation. +
+
+ call ESMF_HConfigFileSave(hconfig, filename="multi_02.yaml", rc=rc) ++ +
+Resulting in: +
+ - And + - finally a + - third document. ++ +
+Most HConfig methods provide the optional doc argument. If present, + the method applies to the specified document. The default for when the + doc argument is not present, for most methods is to use the first + document in the object. The exceptions to this rule are the + ESMF_HConfigFileSave() and ESMF_HConfigFileLoad() methods. + Here the default is to apply the operation to all documents. + +
+When done, clean up hconfig as usual. +
+
+ ! Destroy hconfig when done with it. + call ESMF_HConfigDestroy(hconfig, rc=rc) ++ +
+ +
+The HConfig class offers shortcut methods for the sake of convenience when + working with sequences where all elements are of the same typekind. In these + cases a sequence can be represented as a one-dimensional Fortran array. The + interfaces are overloaded for one-dimensional string, logical, I4, I8, R4, + and R8 typekinds. + +
+Using a Fortran array constructor for the actual argument, a sequence of I4 + data is created. +
+
+ ! type(ESMF_HConfig) :: hconfig + hconfig = ESMF_HConfigCreate([1,2,3], rc=rc) ++ +
+The content of hconfig can be accessed in the usual manner, via + iterators or indexed access. Alternatively, the sequence of I4 elements + can be retrieved in a single call using a one-dimensional allocatable + Fortran array of the appropriate typekind. +
+
+ ! integer(ESMF_KIND_I4), allocatable :: valueI4Seq(:) + valueI4Seq = ESMF_HConfigAsI4Seq(hconfig, rc=rc) ++ +
+The optional, intent(out) argument asOkay is available as in the scalar + access methods. If specified, errors triggered by unsupported typekind + conversion exceptions are suppressed, and instead asOkay == .false. is + returned by the call. + +
+Here an attempt is made to access the content of hconfig as a sequence + of logicals. This is not supported, and will be flagged in the return value + of asOkay. +
+
+ ! logical, allocatable :: valueLSeq(:) + valueLSeq = ESMF_HConfigAsLogicalSeq(hconfig, asOkay=asOkay, rc=rc) ++ +
+Finally the content of hconfig is accessed as a sequence of strings. + This is always supported since every typekind can be represented in string + form. +
+
+ ! character(len=:), allocatable :: valueSSeq(:) + valueSSeq = ESMF_HConfigAsStringSeq(hconfig, stringLen=10, asOkay=asOkay, rc=rc) ++ +
+Next hconfig is cleaned up before re-creating it as an empty HConfig + object. +
+
+ ! Clean up hconfig. + call ESMF_HConfigDestroy(hconfig, rc=rc) ++ +
+
+ ! type(ESMF_HConfig) :: hconfig + hconfig = ESMF_HConfigCreate(rc=rc) ++ +
+Sequences can be added to hconfig conveniently using the overloaded + Add() interfaces that accept one-dimensional Fortran arrays. Here a + sequence of strings is added as the value of a map entry with key string "k1". +
+
+ call ESMF_HConfigAdd(hconfig, ["aaa","bbb","ccc"], addKeyString="k1", rc=rc) ++ +
+Next a sequence of R4 values is added to the map held by hconfig, + under key string "k2". +
+
+ call ESMF_HConfigAdd(hconfig, [1.0,1.25,1.5], addKeyString="k2", rc=rc) ++ +
+At this point hconfig contains the following information: +
+ k1: + - aaa + - bbb + - ccc + k2: + - 1 + - 1.25 + - 1.5 ++ +
+The Set() interfaces are also overloaded to accept one-dimensional + Fortran arrays as input. This makes it easy to set any node to a sequence + that is available as Fortran array. Here the value associated with key "k1" + is changed to a list of two logicals. +
+
+ call ESMF_HConfigSet(hconfig, [.true.,.false.], keyString="k1", rc=rc) ++ +
+This changes the content of hconfig as expected. +
+ k1: + - True + - False + k2: + - 1 + - 1.25 + - 1.5 ++ +
+Finally clean up hconfig as usual. +
+
+ ! Destroy hconfig when done with it. + call ESMF_HConfigDestroy(hconfig, rc=rc) ++ +
+ + +
+ +
+The ESMF HConfig class is implemented on top of YAML-CPP (https://github.com/jbeder/yaml-cpp). +A copy of YAML-CPP is included in the ESMF source tree under ./src/prologue/yaml-cpp. It is +used by a number of ESMF/NUOPC functions, including HConfig. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + hconfig1 = hconfig2 +ARGUMENTS: +
type(ESMF_HConfig) :: hconfig1 + type(ESMF_HConfig) :: hconfig2 ++DESCRIPTION: +
+Assign hconfig1 as an alias to the same ESMF HConfig object in memory + as hconfig2. If hconfig2 is invalid, then hconfig1 will be equally + invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (hconfig1 == hconfig2) then ... endif + OR + result = (hconfig1 == hconfig2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_HConfig), intent(in) :: hconfig1 + type(ESMF_HConfig), intent(in) :: hconfig2 ++DESCRIPTION: +
+Test whether hconfig1 and hconfig2 are valid aliases to the same ESMF + HConfig object in memory. For a more general comparison of two + ESMF HConfigs, going beyond the simple alias test, the + ESMF_HConfigMatch() function (48.6.44) must + be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (hconfig1 /= hconfig2) then ... endif + OR + result = (hconfig1 /= hconfig2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_HConfig), intent(in) :: hconfig1 + type(ESMF_HConfig), intent(in) :: hconfig2 ++DESCRIPTION: +
+Test whether hconfig1 and hconfig2 are not valid aliases to the + same ESMF HConfig object in memory. For a more general comparison of two + ESMF HConfigs, going beyond the simple alias test, the + ESMF_HConfigMatch() function (48.6.44) must + be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigAdd(hconfig, content, & + addKey, addKeyString, index, keyString, doc, rc) +ARGUMENTS: +
type(ESMF_HConfig[Iter]), intent(in) :: hconfig + <Type>, intent(in) :: content[(:)] + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_HConfig), intent(in), optional :: addKey + character(*), intent(in), optional :: addKeyString + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add the content of type <Type> to the hconfig, + at the current location, or as specified by index or keyString + (mutually exclusive!). + Most <Type> options support the sequence array variant (:) in + addition to the scalar variant. + +
+If either addKey or addKeyString (mutually exclusive!) is + specified, then add a new map element with the respective key. + Otherwise add a new list element at the end of the list. Error checking + is implemented to ensure respective conditions are met. + +
+The supported <Type> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigAddMapKey(hconfig, content, & + addKey, addKeyString, index, keyString, doc, rc) +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + <Type>, intent(in) :: content[(:)] + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_HConfig), intent(in), optional :: addKey + character(*), intent(in), optional :: addKeyString + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add the content of type <Type> to the hconfig map key, + at the current location, or as specified by index or keyString + (mutually exclusive!). + Most <Type> options support the sequence array variant (:) in + addition to the scalar variant. + +
+If either addKey or addKeyString (mutually exclusive!) is + specified, then add a new map element with the respective key. + Otherwise add a new list element at the end of the list. Error checking + is implemented to ensure respective conditions are met. + +
+The supported <Type> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigAddMapVal(hconfig, content, & + addKey, addKeyString, index, keyString, doc, rc) +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + <Type>, intent(in) :: content[(:)] + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_HConfig), intent(in), optional :: addKey + character(*), intent(in), optional :: addKeyString + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add the content of type <Type> to the hconfig map value, + at the current location, or as specified by index or keyString + (mutually exclusive!). + Most <Type> options support the sequence array variant (:) in + addition to the scalar variant. + +
+If either addKey or addKeyString (mutually exclusive!) is + specified, then add a new map element with the respective key. + Otherwise add a new list element at the end of the list. Error checking + is implemented to ensure respective conditions are met. + +
+The supported <Type> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigAs<TypeSpec>(hconfig, index, keyString, & + doc, asOkay, rc) +RETURN VALUE: +
<Type> :: ESMF_HConfigAs<TypeSpec> +ARGUMENTS: +
type(ESMF_HConfig[Iter]) , intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + logical, intent(out), optional :: asOkay + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the value of item hconfig interpreted as <Type>. + The returned value is only valid if rc == ESMF_SUCCESS, and, if + provided, asOkay == .true.. + +
+The supported <Type> / <TypeSpec> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigAs<TypeSpec>MapKey(hconfig, index, keyString, & + doc, asOkay, rc) +RETURN VALUE: +
<Type> :: ESMF_HConfigAs<TypeSpec>MapKey +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + logical, intent(out), optional :: asOkay + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the map key of item hconfig interpreted as <Type>. + The returned value is only valid if rc == ESMF_SUCCESS, and, if + provided, asOkay == .true.. + +
+The supported <Type> / <TypeSpec> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigAs<TypeSpec>MapVal(hconfig, index, keyString, & + doc, asOkay, rc) +RETURN VALUE: +
<Type> :: ESMF_HConfigAs<TypeSpec>MapVal +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + logical, intent(out), optional :: asOkay + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the map value of item hconfig interpreted as <Type>. + The returned value is only valid if rc == ESMF_SUCCESS, and, if + provided, asOkay == .true.. + +
+The supported <Type> / <TypeSpec> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigAs<TypeSpec>Seq(hconfig, index, keyString, & + doc, asOkay, rc) +RETURN VALUE: +
<Type>, allocatable :: ESMF_HConfigAs<TypeSpec>Seq(:) +ARGUMENTS: +
type(ESMF_HConfig[Iter]), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + logical, intent(out), optional :: asOkay + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the value of item hconfig interpreted as sequence of <Type>. + The returned value is only valid if rc == ESMF_SUCCESS, and, if + provided, asOkay == .true.. + +
+The supported <Type> / <TypeSpec> options are: + +
+An extra non-optional argument stringLen must be provided for the + String option. This argument specifies the number of characters in + each of the output strings. Longer actual string values are tuncated, while + shorter actual string values are padded with white space. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigAs<TypeSpec>SeqMapKey(hconfig, index, keyString, & + doc, asOkay, rc) +RETURN VALUE: +
<Type>, allocatable :: ESMF_HConfigAs<TypeSpec>SeqMapKey(:) +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + logical, intent(out), optional :: asOkay + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the map key of item hconfig interpreted as sequence of <Type>. + The returned value is only valid if rc == ESMF_SUCCESS, and, if + provided, asOkay == .true.. + +
+The supported <Type> / <TypeSpec> options are: + +
+An extra non-optional argument stringLen must be provided for the + String option. This argument specifies the number of characters in + each of the output strings. Longer actual string values are tuncated, while + shorter actual string values are padded with white space. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigAs<TypeSpec>SeqMapVal(hconfig, index, keyString, & + doc, asOkay, rc) +RETURN VALUE: +
<Type>, allocatable :: ESMF_HConfigAs<TypeSpec>SeqMapVal(:) +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + logical, intent(out), optional :: asOkay + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the map value of item hconfig interpreted as sequence of <Type>. + The returned value is only valid if rc == ESMF_SUCCESS, and, if + provided, asOkay == .true.. + +
+The supported <Type> / <TypeSpec> options are: + +
+An extra non-optional argument stringLen must be provided for the + String option. This argument specifies the number of characters in + each of the output strings. Longer actual string values are tuncated, while + shorter actual string values are padded with white space. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_HConfigCreate() + function ESMF_HConfigCreateDefault(content, filename, rc) +RETURN VALUE: +
type(ESMF_HConfig) :: ESMF_HConfigCreateDefault +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: content + character(len=*), intent(in), optional :: filename + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a new HConfig object. The object is empty unless either the + content or filename argument is specified. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_HConfigCreate() + function ESMF_HConfigCreateHConfig(content, rc) +RETURN VALUE: +
type(ESMF_HConfig) :: ESMF_HConfigCreateHConfig +ARGUMENTS: +
type(ESMF_HConfig), intent(in) :: content + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a new HConfig object from existing HConfig object as a deep copy. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigCreate(content, rc) +RETURN VALUE: +
type(ESMF_HConfig) :: ESMF_HConfigCreate +ARGUMENTS: +
<Type>, intent(in) :: content[(:)] + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a new HConfig object from content of type <Type>. All <Type> options + support the sequence array variant (:) in addition to the scalar + variant. + +
+The supported <Type> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_HConfigCreate() + function ESMF_HConfigCreateStringSeq(content, rc) +RETURN VALUE: +
type(ESMF_HConfig) :: ESMF_HConfigCreateStringSeq +ARGUMENTS: +
character(len=*), intent(in) :: content(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a new HConfig object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigCreateAt(hconfig, index, key, & + keyString, doc, rc) +RETURN VALUE: +
type(ESMF_HConfig) :: ESMF_HConfigCreateAt +ARGUMENTS: +
type(ESMF_HConfig[Iter]), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + type(ESMF_HConfig), intent(in), optional :: key + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a new HConfig object at the current iteration, or + as specified by index, key or keyString. + The hconfig must not be a map iterator. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigCreateAtMapKey(hconfig, index, key, & + keyString, doc, rc) +RETURN VALUE: +
type(ESMF_HConfig) :: ESMF_HConfigCreateAtMapKey +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + type(ESMF_HConfig), intent(in), optional :: key + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a new HConfig object for a map key at the current iteration, or + as specified by index, key or keyString. + The hconfig must be a map iterator. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigCreateAtMapVal(hconfig, index, key, & + keyString, doc, rc) +RETURN VALUE: +
type(ESMF_HConfig) :: ESMF_HConfigCreateAtMapVal +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + type(ESMF_HConfig), intent(in), optional :: key + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a new HConfig object for a map value at the current iteration, or + as specified by index, key or keyString. + The hconfig must be a map iterator. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigDestroy(hconfig, rc) +ARGUMENTS: +
type(ESMF_HConfig), intent(inout) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Destroys an ESMF_HConfig, releasing the resources associated + with the object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigFileLoad(hconfig, filename, doc, rc) +ARGUMENTS: +
type(ESMF_HConfig), intent(in) :: hconfig + character(len=*), intent(in) :: filename + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Load YAML file into hconfig. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigFileSave(hconfig, filename, doc, rc) +ARGUMENTS: +
type(ESMF_HConfig), intent(in) :: hconfig + character(len=*), intent(in) :: filename + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Save HConfig into YAML file. Only localPet == 0 does the writing. + The hconfig must not be a map iterator. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigGetDocCount(hconfig, rc) +RETURN VALUE: +
integer :: ESMF_HConfigGetDocCount +ARGUMENTS: +
type(ESMF_HConfig), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the number of documents held by hconfig. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigGetSize(hconfig, index, keyString, doc, rc) +RETURN VALUE: +
integer :: ESMF_HConfigGetSize +ARGUMENTS: +
type(ESMF_HConfig[Iter]), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the number of elements in collection hconfig. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigGetSizeMapKey(hconfig, index, keyString, & + doc, rc) +RETURN VALUE: +
integer :: ESMF_HConfigGetSizeMapKey +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return size of the hconfig node. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigGetSizeMapVal(hconfig, index, keyString, & + doc, rc) +RETURN VALUE: +
integer :: ESMF_HConfigGetSizeMapVal +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return size of the hconfig node. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigGetTag(hconfig, index, keyString, doc, rc) +RETURN VALUE: +
character(len=:), allocatable :: ESMF_HConfigGetTag +ARGUMENTS: +
type(ESMF_HConfig[Iter]), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return tag string of the hconfig node. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigGetTagMapKey(hconfig, index, keyString, & + doc, rc) +RETURN VALUE: +
character(len=:), allocatable :: ESMF_HConfigGetTagMapKey +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return tag string of map key of the hconfig node. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigGetTagMapVal(hconfig, index, keyString, & + doc, rc) +RETURN VALUE: +
character(len=:), allocatable :: ESMF_HConfigGetTagMapVal +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return tag string of map key of the hconfig node. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIs<NodeType>(hconfig, index, keyString, & + doc, rc) +RETURN VALUE: +
logical :: ESMF_HConfigIs<NodeType> +ARGUMENTS: +
type(ESMF_HConfig[Iter]), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the hconfig node is of node type + <NodeType>. Otherwise return .false.. If an error occurs, i.e. + rc /= ESMF_SUCCESS is returned, the return value of the function + will be .false.. + +
+The supported <NodeType> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIs<NodeType>MapKey(hconfig, index, keyString, & + doc, rc) +RETURN VALUE: +
logical :: ESMF_HConfigIs<NodeType>MapKey +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the hconfig MapKey node is of node type + <NodeType>. Otherwise return .false.. If an error occurs, i.e. + rc /= ESMF_SUCCESS is returned, the return value of the function + will be .false.. + +
+The supported <NodeType> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIs<NodeType>MapVal(hconfig, index, keyString, & + doc, rc) +RETURN VALUE: +
logical :: ESMF_HConfigIs<NodeType>MapVal +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the hconfig MapVal node is of node type + <NodeType>. Otherwise return .false.. If an error occurs, i.e. + rc /= ESMF_SUCCESS is returned, the return value of the function + will be .false.. + +
+The supported <NodeType> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIterBegin(hconfig, rc) +RETURN VALUE: +
type(ESMF_HConfigIter) :: ESMF_HConfigIterBegin +ARGUMENTS: +
type(ESMF_HConfig[Iter]), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return an iterator that points to the first item in hconfig. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIterBeginMapKey(hconfig, rc) +RETURN VALUE: +
type(ESMF_HConfigIter) :: ESMF_HConfigIterBeginMapKey +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return an iterator that points to the first item in hconfig. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIterBeginMapVal(hconfig, rc) +RETURN VALUE: +
type(ESMF_HConfigIter) :: ESMF_HConfigIterBeginMapVal +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return an iterator that points to the first item in hconfig. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIterEnd(hconfig, rc) +RETURN VALUE: +
type(ESMF_HConfigIter) :: ESMF_HConfigIterEnd +ARGUMENTS: +
type(ESMF_HConfig[Iter]), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return an iterator that points to one past the last item in hconfig. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIterEndMapKey(hconfig, rc) +RETURN VALUE: +
type(ESMF_HConfigIter) :: ESMF_HConfigIterEndMapKey +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return an iterator that points to one past the last item in hconfig. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIterEndMapVal(hconfig, rc) +RETURN VALUE: +
type(ESMF_HConfigIter) :: ESMF_HConfigIterEndMapVal +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return an iterator that points to one past the last item in hconfig. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIterIsMap(hconfig, rc) +RETURN VALUE: +
logical :: ESMF_HConfigIterIsMap +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the hconfig node is Null. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIterIsSequence(hconfig, rc) +RETURN VALUE: +
logical :: ESMF_HConfigIterIsSequence +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the hconfig node is Null. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigIterLoop(hconfig, hconfigBegin, hconfigEnd, rc) +RETURN VALUE: +
logical :: ESMF_HConfigIterLoop +ARGUMENTS: +
type(ESMF_HConfigIter), intent(inout) :: hconfig + type(ESMF_HConfigIter), intent(in) :: hconfigBegin + type(ESMF_HConfigIter), intent(in) :: hconfigEnd + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Step the iterator hconfig forward. starting at hconfigBegin + until hconfigEnd is reached. Returns .true. as long as + hconfig has not reached hconfigEnd. Once this condition has + been reached, returns .false.. + +
+The intended usage of ESMF_HConfigIterLoop() is as the conditional + in a do while loop, iterating over the elements of a HConfig object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigIterNext(hconfig, rc) +ARGUMENTS: +
type(ESMF_HConfigIter), intent(inout) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Step the iterator hconfig one step forward. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigLog(hconfig, prefix, logMsgFlag, doc, rc) +ARGUMENTS: +
type(ESMF_HConfig), intent(in) :: hconfig + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: prefix + type(ESMF_LogMsg_Flag), intent(in), optional :: logMsgFlag + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write the contents of hconfig to the ESMF default Log. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigMatch(hconfig1, hconfig2, rc) +RETURN VALUE: +
type(ESMF_HConfigMatch_Flag) :: ESMF_HConfigMatch +ARGUMENTS: +
type(ESMF_HConfig), intent(in) :: hconfig1 + type(ESMF_HConfig), intent(in) :: hconfig2 + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Determine the level to which hconfig1 and hconfig2 match. + +
+Returns a value of type ESMF_HConfigMatch_Flag, + indicating how closely the two HConfig objects match. For a description of + the possible return values, see 48.2.1. + Note that this call only performs PET local matching. Different match values + may be returned on different PETs for the same HConfig pair. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigRemove(hconfig, index, keyString, rc) +ARGUMENTS: +
type(ESMF_HConfig[Iter]), intent(in) :: hconfigIter + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Remove an element from a squence or map HConfig object. Either index + (for sequence) or keyString (for map) must be provided. An error is + flagged if neither optional argument is specified. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigSet(hconfig, content, & + index, keyString, doc, rc) +ARGUMENTS: +
type(ESMF_HConfig[Iter]), intent(in) :: hconfig + <Type>, intent(in) :: content[(:)] + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the content of type <Type> to hconfig, + at the current location, or as specified by index or keyString + (mutually exclusive!). + Most <Type> options support the sequence array variant (:) in + addition to the scalar variant. + +
+The supported <Type> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigSet(hconfig, content, & + index, keyString, doc, rc) +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + <Type>, intent(in) :: content[(:)] + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the content of type <Type> to the hconfig map key, + at the current location, or as specified by index or keyString + (mutually exclusive!). + Most <Type> options support the sequence array variant (:) in + addition to the scalar variant. + +
+The supported <Type> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_HConfigSet(hconfig, content, & + index, keyString, doc, rc) +ARGUMENTS: +
type(ESMF_HConfigIter), intent(in) :: hconfig + <Type>, intent(in) :: content[(:)] + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: index + character(*), intent(in), optional :: keyString + integer, intent(in), optional :: doc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the content of type <Type> to the hconfig map value, + at the current location, or as specified by index or keyString + (mutually exclusive!). + Most <Type> options support the sequence array variant (:) in + addition to the scalar variant. + +
+The supported <Type> options are: + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_HConfigValidateMapKeys(hconfig, vocabulary, & + badKey, rc) +RETURN VALUE: +
logical :: ESMF_HConfigValidateMapKeys +ARGUMENTS: +
type(ESMF_HConfig), intent(in) :: hconfig + character(len=*), intent(in) :: vocabulary(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(:), allocatable, intent(out), optional :: badKey + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Validate that the map held in hconfig only uses keys that + are listed in vocabulary. + +
+The arguments are: +
+ + +
+The Log class consists of a variety of methods for writing error, warning, and +informational messages to files. A default Log is created at ESMF +initialization. Other Logs can be created later in the code by the user. Most +Log methods take a Log as an optional argument and apply to the default Log +when another Log is not specified. A set of standard return codes and +associated messages are provided for error handling. + +
+Log provides capabilities to store message entries in a buffer, which is +flushed to a file, either when the buffer is full, or when the user calls an +ESMF_LogFlush() method. Currently, the default is for the Log to flush +after every ten entries. This can easily be changed by using the +ESMF_LogSet() method and setting the maxElements property to +another value. The ESMF_LogFlush() method is automatically called when +the program exits by any means (program completion, halt on error, or when the +Log is closed). + +
+The user has the capability to abort the program on conditions such as +an error or on a warning by using the ESMF_LogSet() method with +the logmsgAbort argument. For example if the logmsgAbort array +is set to (ESMF_LOGMSG_ERROR,ESMF_LOGMSG_WARNING), the program will +stop on any and all warning or errors. When the logmsgAbort argument +is set to ESMF_LOGMSG_ERROR, the program will only abort on +errors. Lastly, the user can choose to never abort by using +ESMF_LOGMSG_NONE; this is the default. + +
+Log will automatically put the PET number into the Log. Also, the user can +either specify ESMF_LOGKIND_SINGLE which writes all the entries to a single +Log or ESMF_LOGKIND_MULTI which writes entries to multiple Logs according to +the PET number. To distinguish Logs from each other when using +ESMF_LOGKIND_MULTI, the PET number (in the format PETx.) will be +prepended to the file name where x is the PET number. + +
+Opening multiple log files and writing log messages from all the processors +may affect the application performance while running on a large number of +processors. For that reason, ESMF_LOGKIND_NONE is provided to +switch off the Log capability. All the Log methods have no effect +in the ESMF_LOGKIND_NONE mode. + +
+A tracing capability may be enabled by setting the trace flag by +using the ESMF_LogSet() method. When tracing is enabled, calls to +methods such as ESMF_LogFoundError, ESMF_LogFoundAllocError, +and ESMF_LogFoundDeallocError are logged in the default log file. +This can result in voluminous output. It is typically used only around areas +of code which are being debugged. + +
+Other options that are planned for Log are to adjust the verbosity of output, and to optionally write to stdout instead of file(s). + +
+ +
+ +
+The valid values are: +
+ +
+DESCRIPTION:
+
+Specifies a single log file, multiple log files (one per PET), or no log files.
+
+
+The type of this flag is: + +
+type(ESMF_LogKind_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+
+Specifies a message level
+
+
+The type of this flag is: + +
+type(ESMF_LogMsg_Flag) + +
+The valid values are: +
+Valid predefined named array constant values are: + +
+
+ +
+By default ESMF_Initialize() opens a default Log in +ESMF_LOGKIND_MULTI mode. ESMF handles the initialization and finalization +of the default Log so the user can immediately start using it. If additional Log +objects are desired, they must be explicitly created or opened using +ESMF_LogOpen(). + +
+ESMF_LogOpen() requires a Log object and filename argument. Additionally, +the user can specify single or multi Logs by setting the logkindflag property +to ESMF_LOGKIND_SINGLE or ESMF_LOGKIND_MULTI. +This is useful as the PET numbers are automatically added to the Log entries. +A single Log will put all entries, regardless of PET number, into a single +log while a multi Log will create multiple Logs with the PET number prepended +to the filename and all entries will be written to their corresponding Log +by their PET number. + +
+By default, the Log file is not truncated at the start of a new run; it just +gets appended each time. Future functionality may include an option to +either truncate or append to the Log file. + +
+In all cases where a Log is opened, a Fortran unit number is assigned to a specific +Log. A Log is assigned an unused unit number using the algorithm described in +the ESMF_IOUnitGet() method. + +
+The user can then set or get options on how the Log should be used +with the ESMF_LogSet() and ESMF_LogGet() methods. These are +partially implemented at this time. + +
+Depending on how the options are set, ESMF_LogWrite() either writes user +messages directly to a Log file or writes to a buffer that can be flushed when +full or by using the ESMF_LogFlush() method. The default is to flush +after every ten entries because maxElements is initialized to ten +(which means the buffer reaches its full state after every ten writes and then +flushes). + +
+A message filtering option may be set with ESMF_LogSet() so +that only selected message types are actually written to the log. One key +use of this feature is to allow placing informational log write requests +into the code for debugging or tracing. Then, when the informational entries +are not needed, the messages at that level may be turned off -- leaving only +warning and error messages in the logs. + +
+For every ESMF_LogWrite(), a time and date stamp is prepended to the +Log entry. The time is given in microsecond precision. The user can call +other methods to write to the Log. In every case, all methods eventually make +a call implicitly to ESMF_LogWrite() even though the user may never +explicitly call it. + +
+When calling ESMF_LogWrite(), the user can supply an optional line, +file and method. These arguments can be passed in explicitly or with the help +of cpp macros. In the latter case, a define for an ESMF_FILENAME must +be placed at the beginning of a file and a define for ESMF_METHOD must +be placed at the beginning of each method. The user can then use the +ESMF_CONTEXT cpp macro in place of line, file and method to insert the +parameters into the method. The user does not have to specify line number as +it is a value supplied by cpp. + +
+An example of Log output is given below running with logkindflag +property set to ESMF_LOGKIND_MULTI (default) using the default Log: + +
+(Log file PET0.ESMF_LogFile) +
+20041105 163418.472210 INFO PET0 Running with ESMF Version 2.2.1 ++ +
+(Log file PET1.ESMF_LogFile) +
+20041105 163419.186153 ERROR PET1 ESMF_Field.F90 812 +ESMF_FieldGet No Grid or Bad Grid attached to Field ++ +
+The first entry shows date and time stamp. The time is given in microsecond +precision. The next item shown is the type of message (INFO in this case). +Next, the PET number is added. Lastly, the content is written. + +
+The second entry shows something slightly different. In this case, we have +an ERROR. The method name (ESMF_Field.F90) is automatically provided from +the cpp macros as well as the line number (812). Then the content of the +message is written. + +
+When done writing messages, the default Log is closed by calling +ESMF_LogFinalize() or ESMF_LogClose() for user created Logs. +Both methods will release the assigned unit number. + +
+ +
+ +
+
+! !PROGRAM: ESMF_LogErrEx - Log Error examples +! +! !DESCRIPTION: +! +! This program shows examples of Log Error writing +!----------------------------------------------------------------------------- ++ +
+
+! Macros for cpp usage +! File define +#define ESMF_FILENAME "ESMF_LogErrEx.F90" +! Method define +#define ESMF_METHOD "program ESMF_LogErrEx" +#include "ESMF_LogMacros.inc" + + ! ESMF Framework module + use ESMF + use ESMF_TestMod + implicit none + + ! return variables + integer :: rc1, rc2, rc3, rcToTest, allocRcToTest, result + type(ESMF_LOG) :: alog ! a log object that is not the default log + type(ESMF_LogKind_Flag) :: logkindflag + type(ESMF_Time) :: time + type(ESMF_VM) :: vm + integer, pointer :: intptr(:) ++ +
+ +
+This example shows how to use the default Log. This example does not use cpp + macros but does use multi Logs. A separate Log will be created for each PET. +
+
+ ! Initialize ESMF to initialize the default Log + call ESMF_Initialize(vm=vm, defaultlogfilename="LogErrEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc1) ++ +
+
+ ! LogWrite + call ESMF_LogWrite("Log Write 2", ESMF_LOGMSG_INFO, rc=rc2) ++ +
+
+ ! LogMsgSetError + call ESMF_LogSetError(ESMF_RC_OBJ_BAD, msg="Convergence failure", & + rcToReturn=rc2) ++ +
+
+ ! LogMsgFoundError + call ESMF_TimeSet(time, calkindflag=ESMF_CALKIND_NOCALENDAR) + call ESMF_TimeSyncToRealTime(time, rc=rcToTest) + if (ESMF_LogFoundError(rcToTest, msg="getting wall clock time", & + rcToReturn=rc2)) then + ! Error getting time. The previous call will have printed the error + ! already into the log file. Add any additional error handling here. + ! (This call is expected to provoke an error from the Time Manager.) + endif + + ! LogMsgFoundAllocError + allocate(intptr(10), stat=allocRcToTest) + if (ESMF_LogFoundAllocError(allocRcToTest, msg="integer array", & + rcToReturn=rc2)) then + ! Error during allocation. The previous call will have logged already + ! an error message into the log. + endif + deallocate(intptr) ++ +
+ +
+
+ ! Open a Log named "Testlog.txt" associated with alog. + call ESMF_LogOpen(alog, "TestLog.txt", rc=rc1) ++ +
+
+%///////////////////////////////////////////////////////////// + + \begin{verbatim} + ! LogWrite + call ESMF_LogWrite("Log Write 2", ESMF_LOGMSG_INFO, & + line=__LINE__, file=ESMF_FILENAME, & + method=ESMF_METHOD, log=alog, rc=rc2) ++ +
+
+ ! LogMsgSetError + call ESMF_LogSetError(ESMF_RC_OBJ_BAD, msg="Interpolation Failure", & + line=__LINE__, file=ESMF_FILENAME, & + method=ESMF_METHOD, rcToReturn=rc2, log=alog) ++ +
+ +
+
+ ! This is an example showing a query of the default Log. Please note that + ! no Log is passed in the argument list, so the default Log will be used. + call ESMF_LogGet(logkindflag=logkindflag, rc=rc3) ++ +
+
+ ! This is an example setting a property of a Log that is not the default. + ! It was opened in a previous example, and the handle for it must be + ! passed in the argument list. + call ESMF_LogSet(log=alog, logmsgAbort=(/ESMF_LOGMSG_ERROR/), rc=rc2) ++ +
+
+ ! Close the user log. + call ESMF_LogClose(alog, rc=rc3) ++ +
+
+ ! Finalize ESMF to close the default log + call ESMF_Finalize(rc=rc1) ++ +
+ + +
+ +
+
+
+
+
+
+The properties for a Log are set with the ESMF_LogSet() method and +retrieved with the ESMF_LogGet() method. + +
+Additionally, buffering is enabled. Buffering allows ESMF to manage +output data streams in a desired way. Writing to the buffer is transparent +to the user because all the Log entries are handled automatically by the +ESMF_LogWrite() method. All the user has to do is specify the buffer +size (the default is ten) by setting the maxElements property. Every +time the ESMF_LogWrite() method is called, a LogEntry element is +populated with the ESMF_LogWrite() information. When the buffer is +full (i.e., when all the LogEntry elements are populated), the buffer will be +flushed and all the contents will be written to file. If buffering is not +needed, that is maxElements=1 or flushImmediately=ESMF_TRUE, +the ESMF_LogWrite() method will immediately write to the Log file(s). +
+The following is a simplified UML diagram showing the structure of the +Log class. See Appendix A, A Brief Introduction to UML, +for a translation table that lists the symbols in the diagram and their +meaning. + +
+
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + log1 = log2 +ARGUMENTS: +
type(ESMF_Log) :: log1 + type(ESMF_Log) :: log2 ++DESCRIPTION: +
+Assign log1 as an alias to the same ESMF_Log object in memory + as log2. If log2 is invalid, then log1 will be + equally invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (log1 == log2) then ... endif + OR + result = (log1 == log2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Log), intent(in) :: log1 + type(ESMF_Log), intent(in) :: log2 ++DESCRIPTION: +
+Overloads the (==) operator for the ESMF_Log class. + Compare two logs for equality; return .true. if equal, + .false. otherwise. Comparison is based on whether the objects + are distinct, as with two newly created logs, or are simply aliases + to the same log as would be the case when assignment was involved. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (log1 /= log2) then ... endif + OR + result = (log1 /= log2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_Log), intent(in) :: log1 + type(ESMF_Log), intent(in) :: log2 ++DESCRIPTION: +
+Overloads the (/=) operator for the ESMF_Log class. + Compare two logs for inequality; return .true. if equal, + .false. otherwise. Comparison is based on whether the objects + are distinct, as with two newly created logs, or are simply aliases + to the same log as would be the case when assignment was involved. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LogClose(log, rc) +ARGUMENTS: +
type(ESMF_Log), intent(inout), optional :: log + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This routine closes the log file(s) associated with log. + If the log is not explicitly closed, it will be closed by + ESMF_Finalize. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LogFlush(log, rc) +ARGUMENTS: +
type(ESMF_Log), intent(inout), optional :: log + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This subroutine flushes the file buffer associated with log. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_LogFoundAllocError(statusToCheck, & + msg,line,file, & + method,rcToReturn,log) +RETURN VALUE: +
logical :: ESMF_LogFoundAllocError +ARGUMENTS: +
integer, intent(in) :: statusToCheck + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: msg + integer, intent(in), optional :: line + character(len=*), intent(in), optional :: file + character(len=*), intent(in), optional :: method + integer, intent(inout), optional :: rcToReturn + type(ESMF_Log), intent(inout), optional :: log ++STATUS: + +
+DESCRIPTION:
+
+
+
+This function returns .true. when statusToCheck indicates + an allocation error, otherwise it returns .false.. The status + value is typically returned from a Fortran ALLOCATE statement. + If an error is indicated, a ESMF memory allocation error message + will be written to the ESMF_Log along with a user added msg, + line, file and method. + +
+The arguments are: +
+
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_LogFoundDeallocError(statusToCheck, & + msg,line,file, & + method,rcToReturn,log) +RETURN VALUE: +
logical ::ESMF_LogFoundDeallocError +ARGUMENTS: +
integer, intent(in) :: statusToCheck + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: msg + integer, intent(in), optional :: line + character(len=*), intent(in), optional :: file + character(len=*), intent(in), optional :: method + integer, intent(inout), optional :: rcToReturn + type(ESMF_Log), intent(inout), optional :: log ++STATUS: + +
+DESCRIPTION:
+
+
+
+This function returns .true. when statusToCheck indicates + a deallocation error, otherwise it returns .false.. The status + value is typically returned from a Fortran DEALLOCATE statement. + If an error is indicated, a ESMF memory allocation error message + will be written to the ESMF_Log along with a user added msg, + line, file and method. + +
+The arguments are: +
+
+ +
+ +
+ +
+
+INTERFACE:
+
recursive function ESMF_LogFoundError(rcToCheck, & + msg, line, file, method, & + rcToReturn, log) result (LogFoundError) +RETURN VALUE: +
logical :: LogFoundError +ARGUMENTS: +
integer, intent(in), optional :: rcToCheck + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: msg + integer, intent(in), optional :: line + character(len=*), intent(in), optional :: file + character(len=*), intent(in), optional :: method + integer, intent(inout), optional :: rcToReturn + type(ESMF_Log), intent(inout), optional :: log ++STATUS: + +
+DESCRIPTION:
+
+
+
+This function returns .true. when rcToCheck indicates + an return code other than ESMF_SUCCESS, otherwise it returns + .false.. + If an error is indicated, a ESMF predefined error message + will be written to the ESMF_Log along with a user added msg, + line, file and method. + +
+The arguments are: +
+
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_LogFoundNetCDFError(ncerrToCheck, msg, line, & + file, method, rcToReturn, log) + + #if defined ESMF_NETCDF + use netcdf + #elif defined ESMF_PNETCDF + use pnetcdf + #endif +RETURN VALUE: +
logical :: ESMF_LogFoundNetCDFError +ARGUMENTS: +
integer, intent(in) :: ncerrToCheck + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: msg + integer, intent(in), optional :: line + character(len=*), intent(in), optional :: file + character(len=*), intent(in), optional :: method + integer, intent(inout), optional :: rcToReturn + type(ESMF_Log), intent(inout), optional :: log ++DESCRIPTION: +
+This function returns .true. when ncerrToCheck indicates + an return code other than 0 (the success code from NetCDF Fortran) + or NF_NOERR (the success code for PNetCDF). Otherwise it returns + .false.. + If an error is indicated, a predefined ESMF error message + will be written to the ESMF_Log along with a user added msg, + line, file and method. The NetCDF string error + representation will also be logged. + +
+The arguments are: +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LogGet(log, & + flush, & + logmsgAbort, logkindflag, & + maxElements, trace, fileName, & + highResTimestampFlag, indentCount, & + noPrefix, rc) +ARGUMENTS: +
type(ESMF_Log), intent(in), optional :: log + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(out), optional :: flush + type(ESMF_LogMsg_Flag), pointer, optional :: logmsgAbort(:) + type(ESMF_LogKind_Flag), intent(out), optional :: logkindflag + integer, intent(out), optional :: maxElements + logical, intent(out), optional :: trace + character(*), intent(out), optional :: fileName + logical, intent(out), optional :: highResTimestampFlag + integer, intent(out), optional :: indentCount + logical, intent(out), optional :: noPrefix + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This subroutine returns properties about a Log object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LogOpen(log, filename, & + appendflag, logkindflag, noPrefix, rc) +ARGUMENTS: +
type(ESMF_Log), intent(inout) :: log + character(len=*), intent(in) :: filename + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: appendFlag + type(ESMF_LogKind_Flag), intent(in), optional :: logkindFlag + logical, intent(in), optional :: noPrefix + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This routine opens a file named filename and associates + it with the ESMF_Log. When logkindflag is set to + ESMF_LOGKIND_MULTI or ESMF_LOGKIND_MULTI_ON_ERROR + the file name is prepended with PET number identification. If the + incoming log is already open, an error is returned. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_LogOpen () + subroutine ESMF_LogOpenDefault (filename, & + appendflag, logkindflag, rc) +ARGUMENTS: +
character(len=*), intent(in) :: filename + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: appendflag + type(ESMF_LogKind_Flag), intent(in), optional :: logkindflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This routine opens a file named filename and associates + it with the default log. When logkindflag is set to + ESMF_LOGKIND_MULTI the file name is prepended with PET + number identification. If the incoming default log is already open, + an error is returned. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LogSet(log, & + flush, & + logmsgAbort, maxElements, logmsgList, & + errorMask, trace, highResTimestampFlag, indentCount, & + noPrefix, rc) +ARGUMENTS: +
type(ESMF_Log), intent(inout), optional :: log + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: flush + type(ESMF_LogMsg_Flag), intent(in), optional :: logmsgAbort(:) + integer, intent(in), optional :: maxElements + type(ESMF_LogMsg_Flag), intent(in), optional :: logmsgList(:) + integer, intent(in), optional :: errorMask(:) + logical, intent(in), optional :: trace + logical, intent(in), optional :: highResTimestampFlag + integer, intent(in), optional :: indentCount + logical, intent(in), optional :: noPrefix + integer, intent(out), optional :: rc ++DESCRIPTION: +
+This subroutine sets the properties for the Log object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_LogSetError(rcToCheck, & + msg, line, file, method, & + rcToReturn, log) +ARGUMENTS: +
integer, intent(in) :: rcToCheck + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: msg + integer, intent(in), optional :: line + character(len=*), intent(in), optional :: file + character(len=*), intent(in), optional :: method + integer, intent(out), optional :: rcToReturn + type(ESMF_Log), intent(inout), optional :: log ++STATUS: + +
+DESCRIPTION:
+
+
+
+This subroutine sets the rcToReturn value to rcToCheck if + rcToReturn is present and writes this error code to the ESMF_Log + if an error is generated. A predefined error message will added to the + ESMF_Log along with a user added msg, line, file + and method. + +
+The arguments are: +
+
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_LogWrite(msg, logmsgFlag, & + logmsgList, & ! DEPRECATED ARGUMENT + line, file, method, log, rc) +ARGUMENTS: +
character(len=*), intent(in) :: msg + type(ESMF_LogMsg_Flag),intent(in),optional :: logmsgFlag + type(ESMF_LogMsg_Flag),intent(in),optional::logmsgList ! DEPRECATED ARG + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: line + character(len=*), intent(in), optional :: file + character(len=*), intent(in), optional :: method + type(ESMF_Log), intent(inout),optional :: log + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This subroutine writes to the file associated with an ESMF_Log. + A message is passed in along with the logmsgFlag, line, + file and method. If the write to the ESMF_Log + is successful, the function will return a logical true. This + function is the base function used by all the other ESMF_Log + writing methods. + +
+The arguments are: +
+ + +
+The DELayout class provides an additional layer of abstraction on top of the Virtual Machine (VM) layer. DELayout does this by introducing DEs (Decomposition Elements) as logical resource units. The DELayout object keeps track of the relationship between its DEs and the resources of the associated VM object. + +
+The relationship between DEs and VM resources (PETs (Persistent Execution Threads) and VASs (Virtual Address Spaces)) contained in a DELayout object is defined during its creation and cannot be changed thereafter. There are, however, a number of hint and specification arguments that can be used to shape the DELayout during its creation. + +
+Contrary to the number of PETs and VASs contained in a VM object, which are fixed by the available resources, the number of DEs contained in a DELayout can be chosen freely to best match the computational problem or other design criteria. Creating a DELayout with less DEs than there are PETs in the associated VM object can be used to share resources between decomposed objects within an ESMF component. Creating a DELayout with more DEs than there are PETs in the associated VM object can be used to evenly partition the computation over the available resources. + +
+The simplest case, however, is where the DELayout contains the same number of DEs as there are PETs in the associated VM context. In this case the DELayout may be used to re-label the hardware and operating system resources held by the VM. For instance, it is possible to order the resources so that specific DEs have best available communication paths. The DELayout will map the DEs to the PETs of the VM according to the resource details provided by the VM instance. + +
+Furthermore, general DE to PET mapping can be used to offer computational resources with finer granularity than the VM does. The DELayout can be queried for computational and communication capacities of DEs and DE pairs, respectively. This information can be used to best utilize the DE resources when partitioning the computational problem. In combination with other ESMF classes, general DE to PET mapping can be used to realize cache blocking, communication hiding and dynamic load balancing. + +
+Finally, the DELayout layer offers primitives that allow a work queue style dynamic load balancing between DEs. + +
+ +
+DESCRIPTION:
+
+Specifies which VM resource DEs are pinned to (PETs, VASs, SSIs).
+
+
+The type of this flag is: + +
+type(ESMF_Pin_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+Reply when a PET offers to service a DE.
+
+
+The type of this flag is: + +
+type(ESMF_ServiceReply_Flag) + +
+The valid values are: +
+The following examples demonstrate how to create, use and destroy DELayout objects. + +
+ +
+ +
+ +
+Without specifying any of the optional parameters the created + ESMF_DELayout + defaults into having as many DEs as there are PETs in the associated VM + object. Consequently the resulting DELayout describes a simple 1-to-1 DE to + PET mapping. +
+
+ delayout = ESMF_DELayoutCreate(rc=rc) ++ +
+The default DE to PET mapping is simply: +
+ DE 0 -> PET 0 + DE 1 -> PET 1 + ... ++ +
+DELayout objects that are not used any longer should be destroyed. +
+
+ call ESMF_DELayoutDestroy(delayout, rc=rc) ++ +
+The optional vm argument can be provided to DELayoutCreate() to lower + the method's overhead by the amount it takes to determine the current VM. +
+
+ delayout = ESMF_DELayoutCreate(vm=vm, rc=rc) ++ +
+By default all PETs of the associated VM will be considered. However, if the + optional argument petList is present DEs will only be mapped against + the PETs contained in the list. When the following example is executed on + four PETs it creates a DELayout with four DEs by default that are mapped + to the provided PETs in their given order. It is erroneous to specify PETs + that are not part of the VM context on which the DELayout is defined. +
+
+ delayout = ESMF_DELayoutCreate(petList=(/(i,i=petCount-1,1,-1)/), rc=rc) ++ +
+Once the end of the petList has been reached the DE to PET mapping + continues from the beginning of the list. For a 4 PET VM the above created + DELayout will end up with the following DE to PET mapping: + +
+
+ DE 0 -> PET 3 + DE 1 -> PET 2 + DE 2 -> PET 1 + DE 2 -> PET 3 ++ +
+ +
+The deCount argument can be used to specify the number of DEs. In this + example a DELayout is created that contains four times as many DEs as there + are PETs in the VM. +
+
+ delayout = ESMF_DELayoutCreate(deCount=4*petCount, rc=rc) ++ +
+Cyclic DE to PET mapping is the default. For 4 PETs this means: +
+ DE 0, 4, 8, 12 -> PET 0 + DE 1, 5, 9, 13 -> PET 1 + DE 2, 6, 10, 14 -> PET 2 + DE 3, 7, 11, 15 -> PET 3 ++ The default DE to PET mapping can be overridden by providing the + deGrouping argument. This argument provides a positive integer group + number for each DE in the DELayout. All of the DEs of a group will be mapped + against the same PET. The actual group index is arbitrary (but must be + positive) and its value is of no consequence. +
+
+ delayout = ESMF_DELayoutCreate(deCount=4*petCount, & + deGrouping=(/(i/4,i=0,4*petCount-1)/), rc=rc) ++ +
+This will achieve blocked DE to PET mapping. For 4 PETs this means: +
+ DE 0, 1, 2, 3 -> PET 0 + DE 4, 5, 6, 7 -> PET 1 + DE 8, 9, 10, 11 -> PET 2 + DE 12, 13, 14, 15 -> PET 3 ++ +
+ +
+The quality of the partitioning expressed by the DE to PET mapping depends + on the amount and quality of information provided during DELayout creation. + In the following example the compWeights argument is used to specify + relative computational weights for all DEs and communication weights for + DE pairs are provided by the commWeights argument. The example assumes + four DEs. +
+
+ allocate(compWeights(4)) + allocate(commWeights(4, 4)) + ! setup compWeights and commWeights according to computational problem + delayout = ESMF_DELayoutCreate(deCount=4, compWeights=compWeights, & + commWeights=commWeights, rc=rc) + deallocate(compWeights, commWeights) ++ +
+The resulting DE to PET mapping depends on the specifics of the VM object and + the provided compWeights and commWeights arrays. + +
+ +
+Full control over the DE to PET mapping is provided via the petMap + argument. This example maps the DEs to PETs in reverse order. In the 4-PET + case this will result in the following mapping: +
+ DE 0 -> PET 3 + DE 1 -> PET 2 + DE 2 -> PET 1 + DE 3 -> PET 0 ++
+
+ delayout = ESMF_DELayoutCreate(petMap=(/(i,i=petCount-1,0,-1)/), rc=rc) ++ +
+ +
+The petMap argument gives full control over DE to PET mapping. The + following example run on 4 or more PETs maps DEs to PETs according to the + following table: +
+ DE 0 -> PET 3 + DE 1 -> PET 3 + DE 2 -> PET 1 + DE 3 -> PET 0 + DE 4 -> PET 2 + DE 5 -> PET 1 + DE 6 -> PET 3 + DE 7 -> PET 1 ++
+
+ delayout = ESMF_DELayoutCreate(petMap=(/3, 3, 1, 0, 2, 1, 3, 1/), rc=rc) ++ +
+ +
+The simplest case is a DELayout where there is exactly one DE for every PET. + Of course this implies that the number of DEs equals the number of PETs. + This special 1-to-1 DE-to-PET mapping is very common and many applications + assume it. The following example shows how a DELayout can be queried about + its mapping. + +
+First a default DELayout is created where the number of DEs equals the number + of PETs, and are associated 1-to-1. +
+
+ delayout = ESMF_DELayoutCreate(rc=rc) ++ +
+Next the DELayout is queried for the oneToOneFlag, and the user code + makes a decision based on its value. +
+
+ call ESMF_DELayoutGet(delayout, oneToOneFlag=oneToOneFlag, rc=rc) + if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + if (.not. oneToOneFlag) then + ! handle the unexpected case of not dealing with a 1-to-1 mapping + else ++ +
+1-to-1 mapping is guaranteed in this branch and the following code can + work under the simplifying assumption that every PET holds exactly one DE: +
+
+ allocate(localDeToDeMap(1)) + call ESMF_DELayoutGet(delayout, localDeToDeMap=localDeToDeMap, rc=rc) + if (rc /= ESMF_SUCCESS) finalrc=rc + myDe = localDeToDeMap(1) + deallocate(localDeToDeMap) + if (finalrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) + endif ++ +
+ +
+In general a DELayout may map any number (including zero) of DEs against + a single PET. The exact situation can be detected by querying the DELayout + for the oneToOneFlag. If this flag comes back as .true. then the + DELayout maps exactly one DE against each PET, but if it comes back as + .false. the DELayout describes a more general DE-to-PET layout. The + following example shows how code can be be written to work for a general + DELayout. + +
+First a DELayout is created with two more DEs than there are PETs. The + DELayout will consequently map some DEs to the same PET. +
+
+ delayout = ESMF_DELayoutCreate(deCount=petCount+2, rc=rc) ++ +
+The first piece of information needed on each PET is the localDeCount. + This number may be different on each PET and indicates how many DEs are + mapped against the local PET. +
+
+ call ESMF_DELayoutGet(delayout, localDeCount=localDeCount, rc=rc) ++ +
+The DELayout can further be queried for a list of DEs that are held by + the local PET. This information is provided by the localDeToDeMap + argument. In ESMF a localDe is an index that enumerates the DEs that + are associated with the local PET. In many cases the exact bounds of the + localDe index range, e.g. +, or + + does not matter, since it only affects how user code indexes into variables + the user allocated, and therefore set the specific bounds. However, there are + a few Array and Field level calls that take localDe input arguments. In + all those cases where the localDe index variable is passed into an ESMF + call as an input argument, it must be defined with a range starting at + zero, i.e. +. + +
+For consistency with Array and Field, the following code uses a + + range for the localDe index variable, + although it is not strictly necessary here: +
+
+ allocate(localDeToDeMap(0:localDeCount-1)) + call ESMF_DELayoutGet(delayout, localDeToDeMap=localDeToDeMap, rc=rc) + if (rc /= ESMF_SUCCESS) finalrc=rc + do localDe=0, localDeCount-1 + workDe = localDeToDeMap(localDe) +! print *, "I am PET", localPET, " and I am working on DE ", workDe + enddo + deallocate(localDeToDeMap) + if (finalrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ +
+The DELayout API includes two calls that can be used to easily implement + work queue dynamic load balancing. The workload is broken up into DEs + (more than there are PETs) and processed by the PETs. Load balancing is + only possible for ESMF multi-threaded VMs and requires that DEs are pinned + to VASs instead of the PETs (default). The following example will + run for any VM and DELayout, however, load balancing will only occur under the + mentioned conditions. +
+
+ delayout = ESMF_DELayoutCreate(deCount=petCount+2, & + pinflag=ESMF_PIN_DE_TO_VAS, rc=rc) ++ +
+
+ call ESMF_DELayoutGet(delayout, vasLocalDeCount=localDeCount, rc=rc) + if (rc /= ESMF_SUCCESS) finalrc=rc + allocate(localDeToDeMap(localDeCount)) + call ESMF_DELayoutGet(delayout, vasLocalDeToDeMap=localDeToDeMap, rc=rc) + if (rc /= ESMF_SUCCESS) finalrc=rc + do i=1, localDeCount + workDe = localDeToDeMap(i) + print *, "I am PET", localPET, & + " and I am offering service for DE ", workDe + reply = ESMF_DELayoutServiceOffer(delayout, de=workDe, rc=rc) + if (rc /= ESMF_SUCCESS) finalrc=rc + if (reply == ESMF_SERVICEREPLY_ACCEPT) then + ! process work associated with workDe + print *, "I am PET", localPET, ", service offer for DE ", workDe, & + " was accepted." + call ESMF_DELayoutServiceComplete(delayout, de=workDe, rc=rc) + if (rc /= ESMF_SUCCESS) finalrc=rc + endif + enddo + deallocate(localDeToDeMap) + if (finalrc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) ++ +
+ + +
+ +
+The DELayout class is a light weight object. It stores the DE to PET and VAS mapping for all DEs within all PET instances and a list of local DEs for each PET instance. The DELayout does not store the computational and communication weights optionally provided as arguments to the create method. These hints are only used during create while they are available in user owned arrays. + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + delayout1 = delayout2 +ARGUMENTS: +
type(ESMF_DELayout) :: delayout1 + type(ESMF_DELayout) :: delayout2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign delayout1 as an alias to the same ESMF DELayout object in memory + as delayout2. If delayout2 is invalid, then delayout1 will be equally + invalid after the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (delayout1 == delayout2) then ... endif + OR + result = (delayout1 == delayout2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_DELayout), intent(in) :: delayout1 + type(ESMF_DELayout), intent(in) :: delayout2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether delayout1 and delayout2 are valid aliases to the same ESMF + DELayout object in memory. For a more general comparison of two + ESMF DELayouts, going beyond the simple alias test, the + ESMF_DELayoutMatch() function (not yet implemented) must + be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (delayout1 /= delayout2) then ... endif + OR + result = (delayout1 /= delayout2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_DELayout), intent(in) :: delayout1 + type(ESMF_DELayout), intent(in) :: delayout2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether delayout1 and delayout2 are not valid aliases to the + same ESMF DELayout object in memory. For a more general comparison of two + ESMF DELayouts, going beyond the simple alias test, the + ESMF_DELayoutMatch() function (not yet implemented) must + be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DELayoutCreate() + recursive function ESMF_DELayoutCreateDefault(deCount, & + deGrouping, pinflag, petList, vm, rc) +RETURN VALUE: +
type(ESMF_DELayout) :: ESMF_DELayoutCreateDefault +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: deCount + integer, target, intent(in), optional :: deGrouping(:) + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + integer, target, intent(in), optional :: petList(:) + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_DELayout object on the basis of optionally provided + restrictions. By default a DELayout with deCount equal to petCount will + be created, each DE mapped to a single PET. However, the number of DEs + as well grouping of DEs and PETs can be specified via the optional + arguments. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_DELayoutCreate() + recursive function ESMF_DELayoutCreateFromPetMap(petMap, & + pinflag, vm, rc) +RETURN VALUE: +
type(ESMF_DELayout) :: ESMF_DELayoutCreateFromPetMap +ARGUMENTS: +
integer, intent(in) :: petMap(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Pin_Flag), intent(in), optional :: pinflag + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Create an ESMF_DELayout with exactly specified DE to PET mapping. + +
+This ESMF method must be called in unison by all PETs of the VM. Calling + this method from a PET not part of the VM or not calling it from a PET + that is part of the VM will result in undefined behavior. ESMF does not + guard against violation of the unison requirement. The call is not + collective, there is no communication between PETs. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_DELayoutDestroy(delayout, noGarbage, rc) +ARGUMENTS: +
type(ESMF_DELayout), intent(inout) :: delayout + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: noGarbage + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Destroy an ESMF_DELayout object, releasing the resources associated + with the object. + +
+By default a small remnant of the object is kept in memory in order to + prevent problems with dangling aliases. The default garbage collection + mechanism can be overridden with the noGarbage argument. + +
+The arguments are: +
+It is generally recommended to leave the noGarbage argument + set to .FALSE. (the default), and to take advantage of the ESMF + garbage collection system which will prevent problems with dangling + aliases or incorrect sequences of destroy calls. However this level of + support requires that a small remnant of the object is kept in memory + past the destroy call. This can lead to an unexpected increase in memory + consumption over the course of execution in applications that use + temporary ESMF objects. For situations where the repeated creation and + destruction of temporary objects leads to memory issues, it is + recommended to call with noGarbage set to .TRUE., fully + removing the entire temporary object from memory. + +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_DELayoutGet(delayout, vm, deCount,& + petMap, vasMap, oneToOneFlag, pinflag, localDeCount, localDeToDeMap, & + localDeList, & ! DEPRECATED ARGUMENT + vasLocalDeCount, vasLocalDeToDeMap, & + vasLocalDeList, & ! DEPRECATED ARGUMENT + rc) +ARGUMENTS: +
type(ESMF_DELayout), intent(in) :: delayout + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_VM), intent(out), optional :: vm + integer, intent(out), optional :: deCount + integer, target, intent(out), optional :: petMap(:) + integer, target, intent(out), optional :: vasMap(:) + logical, intent(out), optional :: oneToOneFlag + type(ESMF_Pin_Flag), intent(out), optional :: pinflag + integer, intent(out), optional :: localDeCount + integer, target, intent(out), optional :: localDeToDeMap(:) + integer, target, intent(out), optional :: localDeList(:) !DEPRECATED ARG + integer, intent(out), optional :: vasLocalDeCount + integer, target, intent(out), optional :: vasLocalDeToDeMap(:) + integer, target, intent(out), optional :: vasLocalDeList(:) !DEPRECATED ARG + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Access to DELayout information. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_DELayoutIsCreated(delayout, rc) +RETURN VALUE: +
logical :: ESMF_DELayoutIsCreated +ARGUMENTS: +
type(ESMF_DELayout), intent(in) :: delayout + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the delayout has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DELayoutPrint(delayout, rc) +ARGUMENTS: +
type(ESMF_DELayout), intent(in) :: delayout + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Prints internal information about the specified ESMF_DELayout
+ object to stdout.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_DELayoutServiceComplete(delayout, de, rc) +ARGUMENTS: +
type(ESMF_DELayout), intent(in) :: delayout + integer, intent(in) :: de + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+The PET who's service offer was accepted for de must use + ESMF_DELayoutServiceComplete to close the service window. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive function ESMF_DELayoutServiceOffer(delayout, de, rc) +RETURN VALUE: +
type(ESMF_ServiceReply_Flag) :: ESMF_DELayoutServiceOffer +ARGUMENTS: +
type(ESMF_DELayout), intent(in) :: delayout + integer, intent(in) :: de + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Offer service for a DE in the ESMF_DELayout object. This call + together with ESMF_DELayoutServiceComplete() provides the + synchronization primitives between the PETs of an ESMF multi-threaded VM + necessary for dynamic load balancing via a work queue approach. + +
+The calling PET will either receive ESMF_SERVICEREPLY_ACCEPT if + the service offer has been accepted by DELayout or + ESMF_SERVICEREPLY_DENY if the service offer was denied. The + service offer paradigm is different from a simple mutex approach in that + the DELayout keeps track of the number of service offers issued for each + DE by each PET and accepts only one PET's offer for each offer increment. + This requires that all PETs use ESMF_DELayoutServiceOffer() in + unison. See section 50.2.2 for the potential return + values. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_DELayoutValidate(delayout, rc) +ARGUMENTS: +
type(ESMF_DELayout), intent(in) :: delayout + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Validates that the delayout is internally consistent. + The method returns an error code if problems are found. + +
+The arguments are: +
+ + +
+The ESMF VM (Virtual Machine) class is a generic representation of hardware and system software resources. There is exactly one VM object per ESMF Component, providing the execution environment for the Component code. The VM class handles all resource management tasks for the Component class and provides a description of the underlying configuration of the compute resources used by a Component. + +
+In addition to resource description and management, the VM class offers the lowest level of ESMF communication methods. The VM communication calls are very similar to MPI. Data references in VM communication calls must be provided as raw, language-specific, one-dimensional, contiguous data arrays. The similarity between VM and MPI communication calls is striking and there are many equivalent point-to-point and collective communication calls. However, unlike MPI, the VM communication calls support communication between threaded PETs in a completely transparent fashion. + +
+Many ESMF applications do not interact with the VM class directly very much. The resource management aspect is wrapped completely transparent into the ESMF Component concept. Often the only reason that user code queries a Component +object for the associated VM object is to inquire about resource information, such as the localPet or the petCount. Further, for most applications the use of higher level communication APIs, such as provided by Array and Field, are much more convenient than using the low level VM communication calls. + +
+The basic elements of a VM are called PETs, which stands for Persistent Execution Threads. These are equivalent to OS threads with a lifetime of at least that of the associated component. All VM functionality is expressed in terms of PETs. In the simplest, and most common case, a PET is equivalent to an MPI process. However, ESMF also supports multi-threading, where multiple PETs run as Pthreads inside the same virtual address space (VAS). + +
+The resource management functions of the VM class become visible when a component, or the driver code, creates sub-components. Section 16.4.8 discusses this aspect from the Superstructure +perspective and provides links to the relevant Component examples in the documentation. + +
+There are two parts to resource management, the parent and the child. When the parent component creates a child component, the parent VM object provides the resources on which the child is created with ESMF_GridCompCreate() or ESMF_CplCompCreate(). The optional petList argument to these calls limits the resources that the parent gives to a specific child. The child component, may specify - during its optional +ESMF_<Grid/Cpl>CompSetVM() method - how it wants to arrange the inherited resources in its own VM. After this, all standard ESMF methods of the Component, including ESMF_<Grid/Cpl>CompSetServices(), will execute in the child VM. Notice that the ESMF_<Grid/Cpl>CompSetVM() routine, although part of the child Component, must execute before the child VM has been started up. It runs in the parent VM context. The child VM is created and started up just before the user-written set services routine, specified as an argument to ESMF_<Grid/Cpl>CompSetServices(), is entered. + +
+ +
+DESCRIPTION:
+
+Specifies the kind of VM Epoch being entered.
+
+
+The type of this flag is: + +
+type(ESMF_VMEpoch_Flag) + +
+The valid values are: +
+The concept of the ESMF Virtual Machine (VM) is so fundamental to the framework that every ESMF application uses it. However, for many user applications the VM class is transparently hidden behind the ESMF Component concept and higher data classes (e.g. Array, Field). The interaction between user code and VM is often only indirect. The following examples provide an overview of where the VM class can come into play in user code. + +
+ +
+ +
+ +
+This complete example program demonstrates the simplest ESMF application, + consisting of only a main program without any Components. The global + VM, which is automatically created during the ESMF_Initialize() call, + is obtained using two different methods. First the global VM will be returned + by ESMF_Initialize() if the optional vm argument is specified. + The example uses the VM object obtained this way to call the VM print method. + Second, the global VM can be obtained anywhere in the user application using + the ESMF_VMGetGlobal() call. The identical VM is returned and several + VM query methods are called to inquire about the associated resources. + +
+
+program ESMF_VMDefaultBasicsEx +#include "ESMF.h" + + use ESMF + use ESMF_TestMod + + implicit none + + ! local variables + integer:: rc + type(ESMF_VM):: vm + integer:: localPet, petCount, peCount, ssiId, vas ++ +
+
+ call ESMF_Initialize(vm=vm, defaultlogfilename="VMDefaultBasicsEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) + ! Providing the optional vm argument to ESMF_Initialize() is one way of + ! obtaining the global VM. ++ +
+
+ call ESMF_VMPrint(vm, rc=rc) ++ +
+
+ call ESMF_VMGetGlobal(vm=vm, rc=rc) + ! Calling ESMF_VMGetGlobal() anywhere in the user application is the other + ! way to obtain the global VM object. ++ +
+
+ call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, peCount=peCount, & + rc=rc) + ! The VM object contains information about the associated resources. If the + ! user code requires this information it must query the VM object. ++ +
+
+ print *, "This PET is localPet: ", localPet + print *, "of a total of ",petCount," PETs in this VM." + print *, "There are ", peCount," PEs referenced by this VM" + + call ESMF_VMGet(vm, localPet, peCount=peCount, ssiId=ssiId, vas=vas, rc=rc) ++ +
+
+ print *, "This PET is executing in virtual address space (VAS) ", vas + print *, "located on single system image (SSI) ", ssiId + print *, "and is associated with ", peCount, " PEs." ++ +
+
+end program ++ +
+ + +
+ +
+ +
+ +
+The following example shows the role that the VM plays in connection with ESMF + Components. A single Component is created in the main program. Through the + optional petList argument the driver code specifies that only resources + associated with PET 0 are given to the gcomp object. + +
+When the Component code is invoked through the standard ESMF Component methods + Initialize, Run, or Finalize the Component's VM is automatically entered. + Inside of the user-written Component code the Component VM can be obtained + by querying the Component object. The VM object will indicate that only a + single PET is executing the Component code. + +
+
+module ESMF_VMComponentEx_gcomp_mod ++ +
+
+ recursive subroutine mygcomp_init(gcomp, istate, estate, clock, rc) + type(ESMF_GridComp) :: gcomp + type(ESMF_State) :: istate, estate + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + ! local variables + type(ESMF_VM):: vm + + ! get this Component's vm + call ESMF_GridCompGet(gcomp, vm=vm) + + ! the VM object contains information about the execution environment of + ! the Component + + call ESMF_VMPrint(vm, rc=rc) + + rc = 0 + end subroutine !-------------------------------------------------------------- + + + recursive subroutine mygcomp_run(gcomp, istate, estate, clock, rc) + type(ESMF_GridComp) :: gcomp + type(ESMF_State) :: istate, estate + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + ! local variables + type(ESMF_VM):: vm + + ! get this Component's vm + call ESMF_GridCompGet(gcomp, vm=vm) + + ! the VM object contains information about the execution environment of + ! the Component + + call ESMF_VMPrint(vm, rc=rc) + + rc = 0 + end subroutine !-------------------------------------------------------------- + + recursive subroutine mygcomp_final(gcomp, istate, estate, clock, rc) + type(ESMF_GridComp) :: gcomp + type(ESMF_State) :: istate, estate + type(ESMF_Clock) :: clock + integer, intent(out) :: rc + + ! local variables + type(ESMF_VM):: vm + + ! get this Component's vm + call ESMF_GridCompGet(gcomp, vm=vm) + + ! the VM object contains information about the execution environment of + ! the Component + + call ESMF_VMPrint(vm, rc=rc) + + rc = 0 + end subroutine !-------------------------------------------------------------- + +end module ++ +
+
+program ESMF_VMComponentEx +#include "ESMF.h" + use ESMF + use ESMF_TestMod + use ESMF_VMComponentEx_gcomp_mod + implicit none + + ! local variables ++ +
+
+ gcomp = ESMF_GridCompCreate(petList=(/0/), rc=rc) ++ +
+
+ call ESMF_GridCompSetServices(gcomp, userRoutine=mygcomp_register, rc=rc) ++ +
+
+ call ESMF_GridCompInitialize(gcomp, rc=rc) ++ +
+
+ call ESMF_GridCompRun(gcomp, rc=rc) ++ +
+
+ call ESMF_GridCompFinalize(gcomp, rc=rc) ++ +
+
+ call ESMF_GridCompDestroy(gcomp, rc=rc) ++ +
+
+ call ESMF_Finalize(rc=rc) ++ +
+
+end program ++ +
+ + +
+ +
+ +
+ +
+Sometimes user code requires access to the MPI communicator, e.g. to support + legacy code that contains explict MPI communication calls. The correct way of + wrapping such code into ESMF is to obtain the MPI intra-communicator out of + the VM object. In order not to interfere with ESMF communications it is + advisable to duplicate the communicator before using it in user-level MPI + calls. In this example the duplicated communicator is used for a user + controlled MPI_Barrier(). + +
+
+ integer:: mpic ++ +
+
+ integer:: mpic2 ++ +
+
+ call ESMF_VMGet(vm, mpiCommunicator=mpic, rc=rc) + ! The returned MPI communicator spans the same MPI processes that the VM + ! is defined on. ++ +
+
+ call MPI_Comm_dup(mpic, mpic2, ierr) + ! Duplicate the MPI communicator not to interfere with ESMF communications. + ! The duplicate MPI communicator can be used in any MPI call in the user + ! code. Here the MPI_Barrier() routine is called. + call MPI_Barrier(mpic2, ierr) ++ +
+ + +
+ +
+ +
+ +
+The Fortran 2008 MPI language binding defines type MPI_Comm to + represent the MPI communicator. The following example demonstrates + how the MPI communicator queried from the VM object can be used with the + Fortran 2008 MPI binding. + +
+
+ use mpi_f08 ++ +
+
+ integer :: int_mpic + type(MPI_Comm):: mpic ++ +
+
+ type(MPI_Comm):: mpic2 ++ +
+
+ call ESMF_VMGet(vm, mpiCommunicator=int_mpic, rc=rc) + ! The returned MPI communicator spans the same MPI processes that the VM + ! is defined on. ++ +
+
+ mpic%mpi_val = int_mpic ! integer version of communicator -> type(MPI_Comm) + + ! Now mpic can be used in the Fortran 2008 MPI binding interfaces + + call MPI_Comm_dup(mpic, mpic2, ierr) + ! Duplicate the MPI communicator not to interfere with ESMF communications. + ! The duplicate MPI communicator can be used in any MPI call in the user + ! code. Here the MPI_Barrier() routine is called. + call MPI_Barrier(mpic2, ierr) ++ +
+ + +
+ +
+ +
+ +
+It is possible to nest an ESMF application inside a user application that + explicitly calls MPI_Init() and MPI_Finalize(). The + ESMF_Initialize() call automatically checks whether MPI has already + been initialized, and if so does not call MPI_Init() internally. + On the finalize side, ESMF_Finalize() can be instructed to not + call MPI_Finalize(), making it the responsibility of the outer code + to finalize MPI. + + +
+
+ ! For cases where ESMF resource management is desired (e.g. for threading), + ! ESMF_InitializePreMPI() must be called before MPI_Init(). + call ESMF_InitializePreMPI(rc=rc) ++ +
+
+ ! User code initializes MPI. + call MPI_Init(ierr) ++ +
+
+ ! ESMF_Initialize() does not call MPI_Init() if it finds MPI initialized. + call ESMF_Initialize(defaultlogfilename="VMUserMpiEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+
+ ! Use ESMF here... ++ +
+
+ ! Calling ESMF_Finalize() with endflag=ESMF_END_KEEPMPI instructs ESMF + ! to keep MPI active. + call ESMF_Finalize(endflag=ESMF_END_KEEPMPI, rc=rc) ++ +
+
+ ! It is the responsibility of the outer user code to finalize MPI. + call MPI_Finalize(ierr) ++ +
+ + +
+ +
+ +
+ +
+The previous example demonstrated that it is possible to nest an ESMF + application, i.e. ESMF_Initialize()...ESMF_Finalize() inside + MPI_Init()...MPI_Finalize(). It is not necessary that all + MPI ranks enter the ESMF application. The following example shows how the + user code can pass an MPI communicator to ESMF_Initialize(), and + enter the ESMF application on a subset of MPI ranks. + + +
+
+ ! User code initializes MPI. + call MPI_Init(ierr) ++ +
+
+ ! User code determines the local rank. + call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr) ++ +
+
+ ! User code prepares MPI communicator "esmfComm", that allows rank 0 and 1 + ! to be grouped together. + if (rank < 2) then + ! first communicator split with color=0 + call MPI_Comm_split(MPI_COMM_WORLD, 0, 0, esmfComm, ierr) + else + ! second communicator split with color=1 + call MPI_Comm_split(MPI_COMM_WORLD, 1, 0, esmfComm, ierr) + endif ++ +
+
+ if (rank < 2) then + ! Only call ESMF_Initialize() on rank 0 and 1, passing the prepared MPI + ! communicator that spans these ranks. + call ESMF_Initialize(mpiCommunicator=esmfComm, & + defaultlogfilename="VMUserMpiCommEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+
+ ! Use ESMF here... ++ +
+
+ ! Calling ESMF_Finalize() with endflag=ESMF_END_KEEPMPI instructs ESMF + ! to keep MPI active. + call ESMF_Finalize(endflag=ESMF_END_KEEPMPI, rc=rc) ++ +
+
+ else + ! Ranks 2 and above do non-ESMF work... ++ +
+
+ endif ++ +
+
+ ! Free the MPI communicator before finalizing MPI. + call MPI_Comm_free(esmfComm, ierr) + + ! It is the responsibility of the outer user code to finalize MPI. + call MPI_Finalize(ierr) ++ +
+ + +
+ +
+ +
+ +
+Multiple instances of ESMF can run concurrently under the same user main + program on separate MPI communicators. The user program first splits + MPI_COMM_WORLD into separate MPI communicators. Each communicator is + then used to run a separate ESMF instance by passing it into + ESMF_Initialize() on the appropriate MPI ranks. + +
+Care must be taken to set the defaultlogfilename to be unique on each + ESMF instances. This prevents concurrent ESMF instances from writing to the + same log file. + Further, each ESMF instances must call + ESMF_Finalize() with the endflag=ESMF_END_KEEPMPI option in + order to hand MPI control back to the user program. The outer user program is + ultimately responsible for destroying the MPI communicators and to cleanly + shut down MPI. + + +
+
+ ! User code initializes MPI. + call MPI_Init(ierr) ++ +
+
+ ! User code determines the local rank and overall size of MPI_COMM_WORLD + call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr) + call MPI_Comm_size(MPI_COMM_WORLD, size, ierr) ++ +
+
+ ! User code prepares different MPI communicators. + ! Here a single MPI_Comm_split() call is used to split MPI_COMM_WORLD + ! into two non-overlapping communicators: + ! One communicator for ranks 0 and 1, and the other for ranks 2 and above. + if (rank < 2) then + ! first communicator split with color=0 + call MPI_Comm_split(MPI_COMM_WORLD, 0, 0, esmfComm, ierr) + else + ! second communicator split with color=1 + call MPI_Comm_split(MPI_COMM_WORLD, 1, 0, esmfComm, ierr) + endif ++ +
+
+ if (rank < 2) then + ! Ranks 0 and 1 enter ESMF_Initialize() with the prepared communicator. + ! Care is taken to set a unique log file name. + call ESMF_Initialize(mpiCommunicator=esmfComm, & + defaultlogfilename="VMUserMpiCommMultiEx1.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+
+ ! Use ESMF here... ++ +
+
+ ! Finalize ESMF without finalizing MPI. The user application will call + ! MPI_Finalize() on all ranks. + call ESMF_Finalize(endflag=ESMF_END_KEEPMPI, rc=rc) ++ +
+
+ else + ! Ranks 2 and above enter ESMF_Initialize() with the prepared communicator. + ! Care is taken to set a unique log file name. + call ESMF_Initialize(mpiCommunicator=esmfComm, & + defaultlogfilename="VMUserMpiCommMultiEx2.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+
+ ! Use ESMF here... ++ +
+
+ ! Finalize ESMF without finalizing MPI. The user application will call + ! MPI_Finalize() on all ranks. + call ESMF_Finalize(endflag=ESMF_END_KEEPMPI, rc=rc) ++ +
+
+ endif ++ +
+
+ ! Free the MPI communicator(s) before finalizing MPI. + call MPI_Comm_free(esmfComm, ierr) + + ! It is the responsibility of the outer user code to finalize MPI. + call MPI_Finalize(ierr) ++ +
+ + +
+ +
+ +
+ +
+The VM layer provides MPI-like point-to-point communication. Use + ESMF_VMSend() and ESMF_VMRecv() to pass data between two PETs. + The following code sends data from PET 'src' and receives it on PET 'dst'. + Both PETs must be part of the same VM. + +
+Set up the localData array. +
+
+ count = 10 + allocate(localData(count)) + do i=1, count + localData(i) = localPet*100 + i + enddo ++ +
+Carry out the data transfer between src PET and dst PET. +
+
+ if (localPet==src) then + call ESMF_VMSend(vm, sendData=localData, count=count, dstPet=dst, rc=rc) + endif ++ +
+
+ if (localPet==dst) then + call ESMF_VMRecv(vm, recvData=localData, count=count, srcPet=src, rc=rc) + endif ++ +
+Finally, on dst PET, test the received data for correctness. +
+
+ if (localPet==dst) then + do i=1, count + if (localData(i) /= src*100 + i) then + finalrc = ESMF_RC_VAL_WRONG + endif + enddo + endif ++ +
+ + +
+ +
+ +
+ +
+The VM layer provides MPI-like collective communication. ESMF_VMScatter() + scatters data located on root PET across all the PETs of the VM. + ESMF_VMGather() provides the opposite operation, gathering data from + all the PETs of the VM onto root PET. + +
+
+ integer, allocatable:: array1(:), array2(:) ++ +
+
+ ! allocate data arrays + nsize = 2 + nlen = nsize * petCount + allocate(array1(nlen)) + allocate(array2(nsize)) + + ! prepare data array1 + do i=1, nlen + array1(i) = localPet * 100 + i + enddo ++ +
+
+ call ESMF_VMScatter(vm, sendData=array1, recvData=array2, count=nsize, & + rootPet=scatterRoot, rc=rc) ++ +
+
+ call ESMF_VMGather(vm, sendData=array2, recvData=array1, count=nsize, & + rootPet=gatherRoot, rc=rc) ++ +
+ + +
+ +
+ +
+ +
+Use ESMF_VMAllReduce() to reduce data distributed across the PETs of a + VM into a result vector, returned on all the PETs. Further, use + ESMF_VMAllFullReduce() to reduce the data into a single scalar returned + on all PETs. + +
+
+ integer, allocatable:: array1(:), array2(:) ++ +
+
+ ! allocate data arrays + nsize = 2 + allocate(array1(nsize)) + allocate(array2(nsize)) + + ! prepare data array1 + do i=1, nsize + array1(i) = localPet * 100 + i + enddo ++ +
+
+ call ESMF_VMAllReduce(vm, sendData=array1, recvData=array2, count=nsize, & + reduceflag=ESMF_REDUCE_SUM, rc=rc) + ! Reduce distributed sendData, element by element into recvData and + ! return it on all the PETs. ++ +
+
+ call ESMF_VMAllFullReduce(vm, sendData=array1, recvData=result, & + count=nsize, reduceflag=ESMF_REDUCE_SUM, rc=rc) + ! Fully reduce the distributed sendData into a single scalar and + ! return it in recvData on all PETs. ++ +
+ + +
+ +
+ +
+ +
+The separation of initiation and completion of the data transfer provides + the opportunity for the underlying communication system to progress + concurrently with other operations on the same PET. This can be leveraged to + have profound impact on the performance of an algorithm that requires both + computation and communication. + +
+Another critical application of the non-blocking communication mode is the + prevention of deadlocks. In the default blocking mode, a receiving method + will not return until the data transfer has completed. Sending methods may + also not return, especially if the message being sent is above the + implementation dependent internal buffer size. This behavior makes it often + hard, if not impossible, to write safe algorithms that guarantee to not + deadlock when communicating between a group of PETs. + Using the communication calls in non-blocking mode simplifies this problem + immensely. + +
+The following code shows how ESMF_VMSend() and ESMF_VMRecv() + are used in non-blocking mode by passing in the ESMF_SYNC_NONBLOCKING + argument. + +
+Set up the localData array. +
+
+ do i=1, count + localData(i) = localPet*100 + i + enddo ++ +
+Initiate the data transfer between src PET and dst PET. +
+
+ if (localPet==src) then + call ESMF_VMSend(vm, sendData=localData, count=count, dstPet=dst, & + syncflag=ESMF_SYNC_NONBLOCKING, rc=rc) + endif ++ +
+
+ if (localPet==dst) then + call ESMF_VMRecv(vm, recvData=localData, count=count, srcPet=src, & + syncflag=ESMF_SYNC_NONBLOCKING, rc=rc) + endif ++ +
+There is no garantee at this point that the data transfer has actually + started, let along completed. For this reason it is unsafe to overwrite + the data in the localData array on src PET, or to access + the localData array on dst PET. However both PETs are free + to engage in other work while the data transfer may proceed concurrently. +
+
+ ! local computational work here, or other communications ++ +
+Wait for the completion of all outstanding non-blocking communication calls + by issuing the ESMF_VMCommWaitAll() call. +
+
+ call ESMF_VMCommWaitAll(vm, rc=rc) ++ +
+Finally, on dst PET, test the received data for correctness. +
+
+ if (localPet==dst) then + do i=1, count + if (localData(i) /= src*100 + i) then + finalrc = ESMF_RC_VAL_WRONG + endif + enddo + endif ++ +
+Sometimes it is necessary to wait for individual outstanding communications + specifically. This can be accomplished by using ESMF_CommHandle + objects. To demonstrate this, first re-initialize the localData array. +
+
+ do i=1, count + localData(i) = localPet*100 + i + localData2(i) = localPet*1000 + i + enddo ++ +
+Initiate the data transfer between src PET and dst PET, but this + time also pass the commhandle variable of type ESMF_CommHandle. + Here send two message between src and dst in order to have + different outstanding messages to wait for. +
+
+ if (localPet==src) then + call ESMF_VMSend(vm, sendData=localData, count=count, dstPet=dst, & + syncflag=ESMF_SYNC_NONBLOCKING, commhandle=commhandle(1), rc=rc) + call ESMF_VMSend(vm, sendData=localData2, count=count, dstPet=dst, & + syncflag=ESMF_SYNC_NONBLOCKING, commhandle=commhandle(2), rc=rc) + endif ++ +
+
+ if (localPet==dst) then + call ESMF_VMRecv(vm, recvData=localData, count=count, srcPet=src, & + syncflag=ESMF_SYNC_NONBLOCKING, commhandle=commhandle(1), rc=rc) + call ESMF_VMRecv(vm, recvData=localData2, count=count, srcPet=src, & + syncflag=ESMF_SYNC_NONBLOCKING, commhandle=commhandle(2), rc=rc) + endif ++ +
+Now it is possible to specifically wait for the first data transfer, e.g. on + the dst PET. +
+
+ if (localPet==dst) then + call ESMF_VMCommWait(vm, commhandle=commhandle(1), rc=rc) + endif ++ +
+At this point there are still 2 outstanding communications on the src + PET, and one outstanding communication on the dst PET. However, having + returned from the specific ESMF_VMCommWait() call guarantees that the + first communication on the dst PET has completed, i.e. the data has + been received from the src PET, and can now be accessed in the + localData array. +
+
+ if (localPet==dst) then + do i=1, count + if (localData(i) /= src*100 + i) then + finalrc = ESMF_RC_VAL_WRONG + endif + enddo + endif ++ +
+Before accessing data from the second transfer, it is necessary to wait on + the associated commhandle for completion. +
+
+ if (localPet==dst) then + call ESMF_VMCommWait(vm, commhandle=commhandle(2), rc=rc) + endif ++ +
+
+ if (localPet==dst) then + do i=1, count + if (localData2(i) /= src*1000 + i) then + finalrc = ESMF_RC_VAL_WRONG + endif + enddo + endif ++ +
+Finally the commhandle elements on the src side need to be + cleared by waiting for them. This could be done using specific + ESMF_VMCommWait() calls, similar to the dst side, or simply + by waiting for all/any outstanding communications using + ESMF_VMCommWaitAll() as in the previous example. This call can be + issued without commhandle on all of the PETs. +
+
+ call ESMF_VMCommWaitAll(vm, rc=rc) ++ +
+For cases where multiple messages are being sent between the same + src-dst pairs using non-blocking communications, performance + can often be improved by aggregating individual messages. An extra buffer + is needed to hold the collected messages. The result is a single data + transfer for each PET pair. In many cases this can significantly reduce the + time spent in communications. The ESMF VM class provides access to such a + buffering technique through the ESMF_VMEpoch API. + +
+The ESMF_VMEpoch API consists of two interfaces: + ESMF_VMEpochEnter() and ESMF_VMEpochExit(). When entering an + epoch, the user specifies the type of epoch that is to be entered. Currently + only ESMF_VMEPOCH_BUFFER is available. Inside this epoch, + non-blocking communication calls are aggregated and data transfers on the + src side are not issued until the epoch is exited. On the dst side + a single data transfer is received, and then divided over the actual + non-blocking receive calls. + +
+The following code repeates the previous example with two messages between + src and dst. It is important that every PET only must act either + as sender or receiver. A sending PET can send to many different PETs, and a + receiving PET can receive from many PETs, but no PET must send and + receive within the same epoch! + +
+First re-initialize the localData array. +
+
+ do i=1, count + localData(i) = localPet*100 + i + localData2(i) = localPet*1000 + i + enddo ++ +
+Enter the ESMF_VMEPOCH_BUFFER. +
+
+ call ESMF_VMEpochEnter(epoch=ESMF_VMEPOCH_BUFFER, rc=rc) ++ +
+Now issue non-blocking send and receive calls as usual. +
+
+ if (localPet==src) then + call ESMF_VMSend(vm, sendData=localData, count=count, dstPet=dst, & + syncflag=ESMF_SYNC_NONBLOCKING, commhandle=commhandle(1), rc=rc) ++ +
+
+ call ESMF_VMSend(vm, sendData=localData2, count=count, dstPet=dst, & + syncflag=ESMF_SYNC_NONBLOCKING, commhandle=commhandle(2), rc=rc) ++ +
+
+ endif + if (localPet==dst) then + call ESMF_VMRecv(vm, recvData=localData, count=count, srcPet=src, & + syncflag=ESMF_SYNC_NONBLOCKING, commhandle=commhandle(1), rc=rc) ++ +
+
+ call ESMF_VMRecv(vm, recvData=localData2, count=count, srcPet=src, & + syncflag=ESMF_SYNC_NONBLOCKING, commhandle=commhandle(2), rc=rc) ++ +
+
+ endif ++ +
+No data transfer has been initiated at this point due to the fact that this + code is inside the ESMF_VMEPOCH_BUFFER. On the dst side the + same methods are used to wait for the data transfer. However, it is not until + the exit of the epoch on the src side that data is transferred to the + dst side. +
+
+ if (localPet==dst) then + call ESMF_VMCommWait(vm, commhandle=commhandle(1), rc=rc) ++ +
+
+ endif ++ +
+
+ if (localPet==dst) then + do i=1, count + if (localData(i) /= src*100 + i) then + finalrc = ESMF_RC_VAL_WRONG + endif + enddo + endif ++ +
+
+ if (localPet==dst) then + call ESMF_VMCommWait(vm, commhandle=commhandle(2), rc=rc) ++ +
+
+ endif ++ +
+
+ if (localPet==dst) then + do i=1, count + if (localData2(i) /= src*1000 + i) then + finalrc = ESMF_RC_VAL_WRONG + endif + enddo + endif ++ +
+Now exit the epoch, to trigger the data transfer on the src side. +
+
+ call ESMF_VMEpochExit(rc=rc) ++ +
+Finally clear the outstanding communication handles on the src side. + This needs to happen first inside the next ESMF_VMEPOCH_BUFFER. + As before, waits could be issued either for the specific commhandle + elements not yet explicitly cleared, or a general call to + ESMF_VMCommWaitAll() can be used for simplicity. +
+
+ call ESMF_VMEpochEnter(epoch=ESMF_VMEPOCH_BUFFER, rc=rc) ++ +
+
+ call ESMF_VMCommWaitAll(vm, rc=rc) ++ +
+
+ call ESMF_VMEpochExit(rc=rc) ++ +
+ + +
+ +
+ +
+ +
+In the current implementation of the VM communication methods all the data + array arguments are declared as assumed shape dummy arrays of rank one. + The assumed shape flavor was chosen in order to minimize the chance of + copy in/out problems, associated with the other options for declaring the + dummy data arguments. + However, currently the interfaces are not overloaded for higher ranks. This + restriction requires that users that need to communicate data arrays with + rank greater than one, must only pass the first dimension of the data array + into the VM communication calls. Specifying the full size of the data arrays + (considering all dimensions) ensure that the complete data is + transferred in or out of the contiguous array memory. +
+
+ integer, allocatable:: sendData(:,:) + integer, allocatable:: recvData(:,:,:,:) ++ +
+
+ count1 = 5 + count2 = 8 + allocate(sendData(count1,count2)) ! 5 x 8 = 40 elements + do j=1, count2 + do i=1, count1 + sendData(i,j) = localPet*100 + i + (j-1)*count1 + enddo + enddo + + count1 = 2 + count2 = 5 + count3 = 1 + count4 = 4 + allocate(recvData(count1,count2,count3,count4)) ! 2 x 5 x 1 x 4 = 40 elements + do l=1, count4 + do k=1, count3 + do j=1, count2 + do i=1, count1 + recvData(i,j,k,l) = 0 + enddo + enddo + enddo + enddo ++ +
+
+ if (localPet==src) then + call ESMF_VMSend(vm, & + sendData=sendData(:,1), & ! 1st dimension as contiguous array section + count=count1*count2, & ! total count of elements + dstPet=dst, rc=rc) + endif ++ +
+
+ if (localPet==dst) then + call ESMF_VMRecv(vm, & + recvData=recvData(:,1,1,1), & ! 1st dimension as contiguous array section + count=count1*count2*count3*count4, & ! total count of elements + srcPet=src, rc=rc) + endif ++ +
+ + +
+ +
+
+
+
+
+
+
+ +
+The VM class provides an additional layer of abstraction on top of the POSIX machine model, making it suitable for HPC applications. There are four key aspects the VM class deals with. + +
+ +
+
+
+
+
+
+Definition of terms used in the diagram + +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The POSIX machine abstraction, while a very powerful concept, needs augmentation when applied to HPC applications. Key elements of the POSIX abstraction are processes, which provide virtually unlimited resources (memory, I/O, sockets, ...) to possibly multiple threads of execution. Similarly POSIX threads create the illusion that there is virtually unlimited processing power available to each POSIX process. While the POSIX abstraction is very suitable for many multi-user/multi-tasking applications that need to share limited physical resources, it does not directly fit the HPC workload where over-subscription of resources is one of the most expensive modes of operation. + +
+ESMF's virtual machine abstraction is based on the POSIX machine model but holds additional information about the available physical processing units in terms of Processing Elements (PEs). A PE is the smallest physical processing unit and encapsulates the hardware details (Cores, CPUs and SSIs). + +
+There is exactly one physical machine layout for each application, and all VM instances have access to this information. The PE is the smallest processing unit which, in today's microprocessor technology, corresponds to a single Core. Cores are arranged in CPUs which in turn are arranged in SSIs. The setup of the physical machine layout is part of the ESMF initialization process. + +
+On top of the PE concept the key abstraction provided by the VM is the PET. All user code is executed by PETs while OS and hardware details are hidden. The VM class contains a number of methods which allow the user to prescribe how the PETs of a desired virtual machine should be instantiated on the OS level and how they should map onto the hardware. This prescription is kept in a private virtual machine plan object which is created at the same time the associated component is being created. Each time component code is entered through one of the component's registered top-level methods (Initialize/Run/Finalize), the virtual machine plan along with a pointer to the respective user function is used to instantiate the user code on the PETs of the associated VM in form of single- or multi-threaded POSIX processes. + +
+The process of starting, entering, exiting and shutting down a VM is very transparent, all spawning and joining of threads is handled by VM methods "behind the scenes". Furthermore, fundamental synchronization and communication primitives are provided on the PET level through a uniform API, hiding details related to the actual instantiation of the participating PETs. + +
+Within a VM object each PE of the physical machine maps to 0 or 1 PETs. Allowing unassigned PEs provides a means to prevent over-subscription between multiple concurrently running virtual machines. Similarly a maximum of one PET per PE prevents over-subscription within a single VM instance. However, over-subscription is possible by subscribing PETs from different virtual machines to the same PE. This type of over-subscription can be desirable for PETs associated with I/O workloads expected to be used infrequently and to block often on I/O requests. + +
+On the OS level each PET of a VM object is represented by a POSIX thread (Pthread) either belonging to a single- or multi-threaded process and maps to at least 1 PE of the physical machine, ensuring its execution. Mapping a single PET to multiple PEs provides resources for user-level multi-threading, in which case the user code inquires how many PEs are associated with its PET and if there are multiple PEs available the user code can spawn an equal number of threads (e.g. OpenMP) without risking over-subscription. Typically these user spawned threads are short-lived and used for fine-grained parallelization in form of TETs. All PEs mapped against a single PET must be part of a unique SSI in order to allow user-level multi-threading! + +
+In addition to discovering the physical machine the ESMF initialization process sets up the default global virtual machine. This VM object, which is the ultimate parent of all VMs created during the course of execution, contains as many PETs as there are PEs in the physical machine. All of its PETs are instantiated in form of single-threaded MPI processes and a 1:1 mapping of PETs to PEs is used for the default global VM. + +
+The VM design and implementation is based on the POSIX process and thread model as well as the MPI-1.2 standard. As a consequence of the latter standard the number of processes is static during the course of execution and is determined at start-up. The VM implementation further requires that the user starts up the ESMF application with as many MPI processes as there are PEs in the available physical machine using the platform dependent mechanism to ensure proper process placement. + +
+All MPI processes participating in a VM are grouped together by means of an MPI_Group object and their context is defined via an MPI_Comm object (MPI intra-communicator). The PET local process id within each virtual machine is equal to the MPI_Comm_rank in the local MPI_Comm context whereas the PET process id is equal to the MPI_Comm_rank in MPI_COMM_WORLD. The PET process id is used within the VM methods to determine the virtual memory space a PET is operating in. + +
+In order to provide a migration path for legacy MPI-applications the VM offers accessor functions to its MPI_Comm object. Once obtained this object may be used in explicit user-code MPI calls within the same context. + +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
interface assignment(=) + vm1 = vm2 +ARGUMENTS: +
type(ESMF_VM) :: vm1 + type(ESMF_VM) :: vm2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Assign vm1 as an alias to the same ESMF VM object in memory + as vm2. If vm2 is invalid, then vm1 will be equally invalid after + the assignment. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(==) + if (vm1 == vm2) then ... endif + OR + result = (vm1 == vm2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm1 + type(ESMF_VM), intent(in) :: vm2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether vm1 and vm2 are valid aliases to the same ESMF + VM object in memory. For a more general comparison of two ESMF VMs, + going beyond the simple alias test, the ESMF_VMMatch() function (not yet + implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
interface operator(/=) + if (vm1 /= vm2) then ... endif + OR + result = (vm1 /= vm2) +RETURN VALUE: +
logical :: result +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm1 + type(ESMF_VM), intent(in) :: vm2 ++STATUS: + +
+DESCRIPTION:
+
+
+
+Test whether vm1 and vm2 are not valid aliases to the + same ESMF VM object in memory. For a more general comparison of two ESMF + VMs, going beyond the simple alias test, the ESMF_VMMatch() function + (not yet implemented) must be used. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMAllFullReduce(vm, sendData, recvData, & + count, reduceflag, syncflag, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + <type>(ESMF_KIND_<kind>), intent(out) :: recvData + integer, intent(in) :: count + type(ESMF_Reduce_Flag), intent(in) :: reduceflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that reduces a contiguous data + array of <type><kind> across the ESMF_VM object + into a single value of the same <type><kind>. The result is + returned on all PETs. Different reduction operations can be specified. + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8. + +
+TODO: The current version of this method does not provide an + implementation of the non-blocking feature. When calling this + method with syncflag = ESMF_SYNC_NONBLOCKING, error code + ESMF_RC_NOT_IMPL will be returned and an error will be + logged. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMAllGather(vm, sendData, recvData, count, & + syncflag, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: count + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that gathers contiguous data + of <type><kind> from all PETs of an ESMF_VM object into an array on + each PET. The data received in recvData is identical across all PETs. + The count elements sent from the sendData array on PET i + are stored contiguously in the recvData array starting at position + i count 1. + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8, + ESMF_TYPEKIND_LOGICAL. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMAllGatherV(vm, sendData, sendCount, & + recvData, recvCounts, recvOffsets, syncflag, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + integer, intent(in) :: sendCount + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: recvCounts(:) + integer, intent(in) :: recvOffsets(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that gathers contiguous data + of <type><kind> from all PETs of an ESMF_VM object into an array on + each PET. The data received in recvData is identical across all PETs. + The sendCount elements sent from the sendData array on PET + i are stored contiguously in the recvData array starting at + position recvOffsets(i). + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8. + +
+TODO: The current version of this method does not provide an + implementation of the non-blocking feature. When calling this + method with syncflag = ESMF_SYNC_NONBLOCKING, error code + ESMF_RC_NOT_IMPL will be returned and an error will be + logged. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMAllReduce(vm, sendData, recvData, count, & + reduceflag, syncflag, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: count + type(ESMF_Reduce_Flag), intent(in) :: reduceflag + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that reduces a contiguous data + array across the ESMF_VM object into a contiguous data array of the + same <type><kind>. The result array is returned on all PETs. + Different reduction operations can be specified. + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8. + +
+TODO: The current version of this method does not provide an + implementation of the non-blocking feature. When calling this + method with syncflag = ESMF_SYNC_NONBLOCKING, error code + ESMF_RC_NOT_IMPL will be returned and an error will be + logged. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMAllToAll(vm, sendData, sendCount, & + recvData, recvCount, syncflag, & + commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + integer, intent(in) :: sendCount + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: recvCount + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that performs a total exchange + operation on the contiguous data of <type><kind>. PET i sends + contiguous sendCount elements of its sendData array to every + PET, including itself. The sendCount elements sent to PET j are + those starting at position j sendCount 1, and are + stored in recvData on PET in position i + recvCount 1. + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8. + +
+TODO: The current version of this method does not provide an + implementation of the non-blocking feature. When calling this + method with syncflag = ESMF_SYNC_NONBLOCKING, error code + ESMF_RC_NOT_IMPL will be returned and an error will be + logged. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMAllToAllV(vm, sendData, sendCounts, & + sendOffsets, recvData, recvCounts, recvOffsets, syncflag, & + commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + integer, intent(in) :: sendCounts(:) + integer, intent(in) :: sendOffsets(:) + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: recvCounts(:) + integer, intent(in) :: recvOffsets(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that performs a total exchange + operation on the contiguous data of <type><kind>. PET i sends + contiguous elements of its sendData array to all PETs, including + itself. The sendCounts(j) elements sent to PET j are + those starting at position sendOffsets(j), and are + stored in recvData on PET in position recvOffsets(i). + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8, + ESMF_TYPEKIND_LOGICAL. + +
+TODO: The current version of this method does not provide an + implementation of the non-blocking feature. When calling this + method with syncflag = ESMF_SYNC_NONBLOCKING, error code + ESMF_RC_NOT_IMPL will be returned and an error will be + logged. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMBarrier(vm, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in), optional :: vm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that blocks calling PET until + all PETs of the VM context have issued the call. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMBroadcast(vm, bcstData, count, rootPet, & + syncflag, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(inout) :: bcstData(:) + integer, intent(in) :: count + integer, intent(in) :: rootPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that broadcasts a contiguous + data array of <type><kind> from rootPet to all other PETs of the + ESMF_VM object. When the call returns, the bcstData array + on all PETs contains the same data as on rootPet. + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8, + ESMF_TYPEKIND_LOGICAL, + ESMF_TYPEKIND_CHARACTER. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMCommWait(vm, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + type(ESMF_CommHandle), intent(in) :: commhandle + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Wait for non-blocking VM communication specified by the commhandle to + complete. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMCommWaitAll(vm, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Wait for all pending non-blocking VM communication within the + specified VM context to complete. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMEpochEnter(vm, epoch, keepAlloc, throttle, rc) +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_VM), intent(in), optional :: vm + type(ESMF_VMEpoch_Flag), intent(in), optional :: epoch + logical, intent(in), optional :: keepAlloc + integer, intent(in), optional :: throttle + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Enter a specific VM epoch. VM epochs change low level communication behavior + which can have significant performance implications. It is an error to call + ESMF_VMEpochEnter() again before exiting a previous epoch with + ESMF_VMEpochExit(). Also, blocking collective calls + (e.g. ESMF_VMBroadcast()) should not be used within a VMEpoch region. + Doing so will result in a deadlock. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMEpochExit(vm, keepAlloc, rc) +ARGUMENTS: +
-- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_VM), intent(in), optional :: vm + logical, intent(in), optional :: keepAlloc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Exit the current VM epoch. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMGather(vm, sendData, recvData, count, rootPet, & + syncflag, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: count + integer, intent(in) :: rootPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that gathers contiguous data + of <type><kind> from all PETs of an ESMF_VM object (including the + rootPet itself) into an array on rootPet. + The count elements sent from the sendData array on PET i + are stored contiguously in the recvData array on rootPet + starting at position i count 1. + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8, + ESMF_TYPEKIND_LOGICAL. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMGatherV(vm, sendData, sendCount, recvData, & + recvCounts, recvOffsets, rootPet, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + integer, intent(in) :: sendCount + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: recvCounts(:) + integer, intent(in) :: recvOffsets(:) + integer, intent(in) :: rootPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that gathers contiguous data + of <type><kind> from all PETs of an ESMF_VM object (including the + rootPet itself) into an array on rootPet. + The sendCount elements sent from the sendData array on PET + i are stored contiguously in the recvData array on rootPet + starting at position recvOffsets(i). + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8. + +
+TODO: The current version of this method does not provide an + implementation of the non-blocking feature. When calling this + method with syncflag = ESMF_SYNC_NONBLOCKING, error code + ESMF_RC_NOT_IMPL will be returned and an error will be + logged. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_VMGet() + recursive subroutine ESMF_VMGetDefault(vm, localPet, & + currentSsiPe, petCount, peCount, ssiCount, ssiMap, ssiMinPetCount, ssiMaxPetCount, & + ssiLocalPetCount, ssiLocalPet, ssiLocalDevCount, ssiLocalDevList, mpiCommunicator, & + pthreadsEnabledFlag, openMPEnabledFlag, ssiSharedMemoryEnabledFlag, esmfComm, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: localPet + integer, intent(out), optional :: currentSsiPe + integer, intent(out), optional :: petCount + integer, intent(out), optional :: peCount + integer, intent(out), optional :: ssiCount + integer, allocatable, intent(out), optional :: ssiMap(:) + integer, intent(out), optional :: ssiMinPetCount + integer, intent(out), optional :: ssiMaxPetCount + integer, intent(out), optional :: ssiLocalPetCount + integer, intent(out), optional :: ssiLocalPet + integer, intent(out), optional :: ssiLocalDevCount + integer, allocatable, intent(out), optional :: ssiLocalDevList(:) + integer, intent(out), optional :: mpiCommunicator + logical, intent(out), optional :: pthreadsEnabledFlag + logical, intent(out), optional :: openMPEnabledFlag + logical, intent(out), optional :: ssiSharedMemoryEnabledFlag + character(:), allocatable, intent(out), optional :: esmfComm + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get internal information about the specified ESMF_VM object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_VMGet() + subroutine ESMF_VMGetPetSpecific(vm, pet, peCount, & + accDeviceCount, & ! DEPRECATED ARGUMENT + ssiId, threadCount, threadId, vas, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + integer, intent(in) :: pet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: peCount + integer, intent(out), optional :: accDeviceCount ! DEPRECATED ARGUMENT + integer, intent(out), optional :: ssiId + integer, intent(out), optional :: threadCount + integer, intent(out), optional :: threadId + integer, intent(out), optional :: vas + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get internal information about a specific PET within an ESMF_VM + object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMGetGlobal(vm, rc) +ARGUMENTS: +
type(ESMF_VM), intent(out) :: vm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get the global ESMF_VM object. This is the VM object + that is created during ESMF_Initialize() and is the ultimate + parent of all VM objects in an ESMF application. It is identical to the VM + object returned by ESMF_Initialize(..., vm=vm, ...). + +
+The ESMF_VMGetGlobal() call provides access to information about the + global execution context via the global VM. This call is necessary because + ESMF does not created a global ESMF Component during + ESMF_Initialize() that could be queried for information about + the global execution context of an ESMF application. + +
+Usage of ESMF_VMGetGlobal() from within Component code is + strongly discouraged. ESMF Components should only access their own VM + objects through Component methods. Global information, if required by + the Component user code, should be passed down to the Component from the + driver through the Component calling interface. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMGetCurrent(vm, rc) +ARGUMENTS: +
type(ESMF_VM), intent(out) :: vm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get the ESMF_VM object of the current execution context. Calling + ESMF_VMGetCurrent() within an ESMF Component, will return the + same VM object as + ESMF_GridCompGet(..., vm=vm, ...) or + ESMF_CplCompGet(..., vm=vm, ...). + +
+The main purpose of providing ESMF_VMGetCurrent() is to simplify ESMF + adoption in legacy code. Specifically, code that uses MPI_COMM_WORLD + deep within its calling tree can easily be modified to use the correct MPI + communicator of the current ESMF execution context. The advantage is that + these modifications are very local, and do not require wide reaching + interface changes in the legacy code to pass down the ESMF component object, + or the MPI communicator. + +
+The use of ESMF_VMGetCurrent() is strongly discouraged in newly + written Component code. Instead, the ESMF Component object should be used as + the appropriate container of ESMF context information. This object should be + passed between the subroutines of a Component, and be queried for any + Component specific information. + +
+Outside of a Component context, i.e. within the driver context, the call + to ESMF_VMGetCurrent() is identical to ESMF_VMGetGlobal(). + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_VMIsCreated(vm, rc) +RETURN VALUE: +
logical :: ESMF_VMIsCreated +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the vm has been created. Otherwise return + .false.. If an error occurs, i.e. rc /= ESMF_SUCCESS is + returned, the return value of the function will also be .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMLog(vm, prefix, logMsgFlag, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: prefix + type(ESMF_LogMsg_Flag), intent(in), optional :: logMsgFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write information about vm to the ESMF default Log. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMLogSystem(prefix, logMsgFlag, rc) +ARGUMENTS: +
character(len=*), intent(in), optional :: prefix + type(ESMF_LogMsg_Flag), intent(in), optional :: logMsgFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Log the VM. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMPrint(vm, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Print internal information about the specified ESMF_VM to
+ stdout.
+
+
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMRecv(vm, recvData, count, srcPet, & + syncflag, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: count + integer, intent(in) :: srcPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Receive contiguous data from srcPet within the same ESMF_VM + object. + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8, + ESMF_TYPEKIND_LOGICAL, + ESMF_TYPEKIND_CHARACTER. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMReduce(vm, sendData, recvData, count, & + reduceflag, rootPet, syncflag, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: count + type(ESMF_Reduce_Flag), intent(in) :: reduceflag + integer, intent(in) :: rootPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that reduces a contiguous data + array across the ESMF_VM object into a contiguous data array of + the same <type><kind>. The result array is returned on rootPet. + Different reduction operations can be specified. + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8. + +
+TODO: The current version of this method does not provide an + implementation of the non-blocking feature. When calling this + method with syncflag = ESMF_SYNC_NONBLOCKING, error code + ESMF_RC_NOT_IMPL will be returned and an error will be + logged. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMScatter(vm, sendData, recvData, count, & + rootPet, syncflag, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: count + integer, intent(in) :: rootPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that scatters contiguous data + of <type><kind> from rootPet across all the PETs of an ESMF_VM + object. Every PET, including rootPet, receives a portion of the data. + The count number of elements received by PET i originate from + the sendData array on rootPet, starting at position i + count 1. Each PET stores the received contiguous data + portion at the start of its recvData array. + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8, + ESMF_TYPEKIND_LOGICAL. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMScatterV(vm, sendData, sendCounts, & + sendOffsets, recvData, recvCount, rootPet, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + integer, intent(in) :: sendCounts(:) + integer, intent(in) :: sendOffsets(:) + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: recvCount + integer, intent(in) :: rootPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Collective ESMF_VM communication call that scatters contiguous data + of <type><kind> from rootPet across all the PETs of an ESMF_VM + object. Every PET, including rootPet, receives a portion of the data. + The recvCount number of elements received by PET i originate + from the sendData array on rootPet, starting at position + sendOffsets(i). Each PET stores the received contiguous data + portion at the start of its recvData array. + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMSend(vm, sendData, count, dstPet, & + syncflag, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + integer, intent(in) :: count + integer, intent(in) :: dstPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Send contiguous data to dstPet within the same ESMF_VM object. + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8, + ESMF_TYPEKIND_LOGICAL, + ESMF_TYPEKIND_CHARACTER. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMSendRecv(vm, sendData, sendCount, dstPet, & + recvData, recvCount, srcPet, syncflag, commhandle, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + <type>(ESMF_KIND_<kind>), target, intent(in) :: sendData(:) + integer, intent(in) :: sendCount + integer, intent(in) :: dstPet + <type>(ESMF_KIND_<kind>), target, intent(out) :: recvData(:) + integer, intent(in) :: recvCount + integer, intent(in) :: srcPet + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_Sync_Flag), intent(in), optional :: syncflag + type(ESMF_CommHandle), intent(out), optional :: commhandle + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Send contiguous data to dstPet within the same ESMF_VM object + while receiving contiguous data from srcPet within the same + ESMF_VM object. The sendData and recvData arrays must be + disjoint! + +
+This method is overloaded for: + ESMF_TYPEKIND_I4, ESMF_TYPEKIND_I8, + ESMF_TYPEKIND_R4, ESMF_TYPEKIND_R8, + ESMF_TYPEKIND_LOGICAL, + ESMF_TYPEKIND_CHARACTER. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMValidate(vm, rc) +ARGUMENTS: +
type(ESMF_VM), intent(in) :: vm + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Validates that the vm is internally consistent. + The method returns an error code if problems are found. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMWtime(time, rc) +ARGUMENTS: +
real(ESMF_KIND_R8), intent(out) :: time + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get floating-point number of seconds of elapsed wall-clock time since the + beginning of execution of the application. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine ESMF_VMWtimeDelay(delay, rc) +ARGUMENTS: +
real(ESMF_KIND_R8), intent(in) :: delay + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Delay execution for amount of seconds. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_VMWtimePrec(prec, rc) +ARGUMENTS: +
real(ESMF_KIND_R8), intent(out) :: prec + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Get a run-time estimate of the timer precision as floating-point number + of seconds. This is a relatively expensive call since the timer precision + is measured several times before the maximum is returned as the estimate. + The returned value is PET-specific and may differ across the VM + context. + +
+The arguments are: +
+ + +
+ +
+ESMF's built in profiling capability collects runtime statistics +of an executing ESMF application through both automatic and manual code +instrumentation. Timing information for all phases of all ESMF components +executing in an application can be automatically collected using the +ESMF_RUNTIME_PROFILE environment variable (see below for settings). +Additionally, arbitrary user-defined code regions can be timed by +manually instrumenting code with special API calls. Timing profiles +of component phases and user-defined regions can be output in several +different formats: + +
+The following table lists important environment variables that control +aspects of ESMF profiling. + +
+
Environment Variable | +Description | +Example Values | +Default | +
ESMF_RUNTIME_PROFILE | +Enable/disables all profiling functions | +ON or OFF | +OFF | +
ESMF_RUNTIME_PROFILE_PETLIST | +Limits profiling to an explicit list of PETs | +“0-9 50 99” | +profile all PETs | +
ESMF_RUNTIME_PROFILE_OUTPUT | +Controls output format of profiles; multiple can be specified in a space separated list | +TEXT, SUMMARY, BINARY | +TEXT | +
+ +
+Whereas profiling collects summary information from an application, +tracing records a more detailed set of events for later analysis. Trace +analysis can be used to understand what happened during a program's +execution and is often used for diagnosing problems, debugging, and +performance analysis. + +
+ESMF has a built-in tracing capability that records events into special +binary log files. Unlike log files written by the ESMF_Log class, +which are primarily for human consumption (see Section 49.1), +the trace output files are +recorded in a compact binary representation and are processed by tools +to produce various analyses. ESMF event streams are recorded in the +Common Trace Format +(CTF). +CTF traces include one or more event streams, +as well as a metadata file describing the events in the streams. + +
+Several tools are available for reading in the CTF traces output by ESMF. +Of the tools listed below, the first one is designed specifically for +analyzing ESMF applications and the second two are general purpose tools +for working with all CTF traces. + +
+Events that can be captured by the ESMF tracer include the following. Events +are recorded with a high-precision timestamp to allow timing analyses. +
+The following table lists important environment variables that control +aspects of ESMF tracing. + +
+
Environment Variable | +Description | +Example Values | +Default | +
ESMF_RUNTIME_TRACE | +Enable/disables all tracing functions | +ON or OFF | +OFF | +
ESMF_RUNTIME_TRACE_CLOCK | +Sets the type of clock for timestamping events (see Section 52.2.6). | +REALTIME or MONOTONIC or MONOTONIC_SYNC | +REALTIME | +
ESMF_RUNTIME_TRACE_PETLIST | +Limits tracing to an explicit list of PETs | +“0-9 50 99” | +trace all PETs | +
ESMF_RUNTIME_TRACE_COMPONENT | +Enables/disable tracing of Component phase_enter and phase_exit events | +ON or OFF | +ON | +
ESMF_RUNTIME_TRACE_FLUSH | +Controls frequency of event stream flushing to file | +DEFAULT or EAGER | +DEFAULT | +
+ +
+ +
+ESMF profiling is disabled by default. To profile an application, +set the ESMF_RUNTIME_PROFILE variable to ON prior +to executing the application. You do not need to recompile +your code to enable profiling. + +
+
+# csh shell +$ setenv ESMF_RUNTIME_PROFILE ON + +# bash shell +$ export ESMF_RUNTIME_PROFILE=ON + +# (from now on, only the csh shell version will be shown) ++ +
+Then execute the application in the usual way. At the end of +the run the profile information will be available at the end +of each PET log (if ESMF Logs are turned on) or in a set of +separate files, one per PET, with names ESMF_Profile.XXX +where XXX is the PET number. Below is an example timing +profile. Some regions are left out for brevity. + +
+
+Region Count Total (s) Self (s) Mean (s) Min (s) Max (s) + [esm] Init 1 1 4.0878 0.0341 4.0878 4.0878 4.0878 + [OCN-TO-ATM] IPDv05p6b 1 2.6007 2.6007 2.6007 2.6007 2.6007 + [ATM-TO-OCN] IPDv05p6b 1 1.4333 1.4333 1.4333 1.4333 1.4333 + [ATM] IPDv00p2 1 0.0055 0.0055 0.0055 0.0055 0.0055 + [OCN] IPDv00p2 1 0.0023 0.0023 0.0023 0.0023 0.0023 + [ATM] IPDv00p1 1 0.0011 0.0011 0.0011 0.0011 0.0011 + [OCN] IPDv00p1 1 0.0009 0.0009 0.0009 0.0009 0.0009 + [ATM-TO-OCN] IPDv05p3 1 0.0008 0.0008 0.0008 0.0008 0.0008 + [ATM-TO-OCN] IPDv05p1 1 0.0008 0.0008 0.0008 0.0008 0.0008 + [ATM-TO-OCN] IPDv05p2b 1 0.0007 0.0007 0.0007 0.0007 0.0007 + [ATM-TO-OCN] IPDv05p4 1 0.0007 0.0007 0.0007 0.0007 0.0007 + [ATM-TO-OCN] IPDv05p2a 1 0.0007 0.0007 0.0007 0.0007 0.0007 + [ATM-TO-OCN] IPDv05p5 1 0.0007 0.0007 0.0007 0.0007 0.0007 + [OCN-TO-ATM] IPDv05p3 1 0.0006 0.0006 0.0006 0.0006 0.0006 + [OCN-TO-ATM] IPDv05p4 1 0.0006 0.0006 0.0006 0.0006 0.0006 + [OCN-TO-ATM] IPDv05p2b 1 0.0006 0.0006 0.0006 0.0006 0.0006 + [OCN-TO-ATM] IPDv05p2a 1 0.0006 0.0006 0.0006 0.0006 0.0006 + [OCN-TO-ATM] IPDv05p5 1 0.0006 0.0006 0.0006 0.0006 0.0006 + [OCN-TO-ATM] IPDv05p1 1 0.0005 0.0005 0.0005 0.0005 0.0005 + [esm] RunPhase1 1 2.7423 0.9432 2.7423 2.7423 2.7423 + [OCN-TO-ATM] RunPhase1 864 0.6094 0.6094 0.0007 0.0006 0.0179 + [ATM] RunPhase1 864 0.5296 0.2274 0.0006 0.0005 0.0011 + ATM:ModelAdvance 864 0.3022 0.3022 0.0003 0.0003 0.0005 + [ATM-TO-OCN] RunPhase1 864 0.3345 0.3345 0.0004 0.0002 0.0299 + [OCN] RunPhase1 864 0.3256 0.3256 0.0004 0.0003 0.0010 + [esm] FinalizePhase1 1 0.0029 0.0020 0.0029 0.0029 0.0029 + [OCN-TO-ATM] FinalizePhase1 1 0.0006 0.0006 0.0006 0.0006 0.0006 + [ATM-TO-OCN] FinalizePhase1 1 0.0002 0.0002 0.0002 0.0002 0.0002 + [OCN] FinalizePhase1 1 0.0001 0.0001 0.0001 0.0001 0.0001 + [ATM] FinalizePhase1 1 0.0000 0.0000 0.0000 0.0000 0.0000 ++ +
+A timed region is either an ESMF component phase (e.g., initialize, +run, or finalize) or a user-defined region of code surrounded by calls to +ESMF_TraceRegionEnter() and ESMF_TraceRegionExit(). (See +section 52.2.8 for more information on instrumenting +user-defined regions.) +Regions are organized hierarchically with sub-regions nested. +For example, in the profile above, +the [OCN] RunPhase1 is a sub-region of [esm] RunPhase1 and is +entirely contained inside that region. Regions with the same name may appear +at multiple places in the hierarchy, and so would appear in multiple rows +in the table. The statistics in that row apply to that region at that +location in the hierarchy. Component names appear in square brackets, +e.g., [ATM], [OCN], and [ATM-TO-OCN]. +By default, timings are based on elapsed wall clock time and are collected +on a per-PET basis. Therefore, regions timings may differ across PETs. Regions +are sorted with the most expensive regions appearing at the top. The following +describes the meaning of the statistics in each column: + +
+
Count | the number of times the region is executed |
Total | the aggregate time spent in the region, inclusive of all sub-regions |
Self | the aggregate time spend in the region, exclusive of all sub-regions |
Mean | the average amount of time for one execution of the region |
Min | time of the fastest execution of the region |
Max | time of the slowest execution of the region + |
+ +
+By default, separate timing profiles are generated for each PET +in the application. The per-PET profiles can be aggregated together +and output to a single file, ESMF_Profile.summary, by setting the +ESMF_RUNTIME_PROFILE_OUTPUT environment variable as follows: + +
+
+$ setenv ESMF_RUNTIME_PROFILE ON # turn on profiling +$ setenv ESMF_RUNTIME_PROFILE_OUTPUT SUMMARY # specify summary output ++ +
+Note the ESMF_RUNTIME_PROFILE environment variable must +also be set to ON since this controls all profiling capabilities. +The ESMF_Profile.summary file will contain a tree of +timed regions, but aggregated across all PETs. For example: + +
+
+Region PETs PEs Count Mean (s) Min (s) Min PET Max (s) Max PET + [esm] Init 1 4 4 1 4.0880 4.0878 2 4.0883 1 + [OCN-TO-ATM] IPDv05p6b 4 4 1 2.6007 2.6007 2 2.6007 3 + [ATM-TO-OCN] IPDv05p6b 4 4 1 1.4335 1.4333 0 1.4337 3 + [ATM-TO-OCN] IPDv05p4 4 4 1 0.0037 0.0007 0 0.0060 1 + [ATM] IPDv00p2 4 4 1 0.0034 0.0020 1 0.0055 0 + [ATM-TO-OCN] IPDv05p1 4 4 1 0.0020 0.0007 2 0.0033 3 + [OCN] IPDv00p2 4 4 1 0.0019 0.0015 3 0.0024 2 + [ATM-TO-OCN] IPDv05p3 4 4 1 0.0010 0.0008 0 0.0013 1 + [ATM-TO-OCN] IPDv05p2a 4 4 1 0.0009 0.0007 0 0.0012 3 + [ATM] IPDv00p1 4 4 1 0.0009 0.0007 3 0.0011 0 + [ATM-TO-OCN] IPDv05p2b 4 4 1 0.0008 0.0007 0 0.0010 3 + [ATM-TO-OCN] IPDv05p5 4 4 1 0.0008 0.0007 0 0.0010 3 + [ATM-TO-OCN] IPDv05p6a 4 4 1 0.0008 0.0005 2 0.0012 3 + [OCN-TO-ATM] IPDv05p3 4 4 1 0.0008 0.0006 2 0.0010 3 + [OCN-TO-ATM] IPDv05p4 4 4 1 0.0008 0.0006 0 0.0009 3 + [OCN-TO-ATM] IPDv05p2b 4 4 1 0.0007 0.0006 2 0.0009 3 + [OCN] IPDv00p1 4 4 1 0.0007 0.0005 1 0.0009 2 + [OCN-TO-ATM] IPDv05p2a 4 4 1 0.0007 0.0006 2 0.0009 1 + [OCN-TO-ATM] IPDv05p5 4 4 1 0.0007 0.0006 0 0.0009 3 + [OCN-TO-ATM] IPDv05p1 4 4 1 0.0006 0.0005 0 0.0008 1 + [OCN-TO-ATM] IPDv05p6a 4 4 1 0.0006 0.0004 2 0.0007 1 + [esm] RunPhase1 4 4 1 2.7444 2.7423 0 2.7454 1 + [OCN-TO-ATM] RunPhase1 4 4 864 0.6123 0.6004 2 0.6244 1 + [ATM] RunPhase1 4 4 864 0.5386 0.5296 0 0.5530 1 + ATM:ModelAdvance 4 4 864 0.3038 0.3022 0 0.3065 1 + [OCN] RunPhase1 4 4 864 0.3471 0.3256 0 0.3824 1 + [ATM-TO-OCN] RunPhase1 4 4 864 0.2843 0.1956 1 0.3345 0 + [esm] FinalizePhase1 4 4 1 0.0029 0.0029 1 0.0030 2 + [OCN-TO-ATM] FinalizePhase1 4 4 1 0.0007 0.0006 0 0.0008 3 + [ATM-TO-OCN] FinalizePhase1 4 4 1 0.0002 0.0001 3 0.0002 1 + [OCN] FinalizePhase1 4 4 1 0.0001 0.0001 3 0.0001 0 + [ATM] FinalizePhase1 4 4 1 0.0001 0.0000 0 0.0001 2 ++ +
+The meaning of the statistics in each column in as follows: +
PETs | the number of reporting PETs that executed the region |
PEs | the number of PEs associated with the reporting PETs that executed the region |
Count | the number of times each reporting PET executed the region + or “MULTIPLE” if not all PETs executed the region the same number of times |
Mean | the mean across all reporting PETs of the total time spent in the region |
Min | the minimum across all reporting PETs of the total time spent in the region |
Min PET | the PET that reported the minimum time |
Max | the maximum across all reporting PETs of the total time spent in the region |
Max PET | the PET that reported the maximum time + |
+Note that setting the ESMF_RUNTIME_PROFILE_PETLIST environment variable +(described below) may reduce the number of reporting PETs. Only reporting PETs are +included in the summary profile. To output both the per-PET and summary timing profiles, +set the ESMF_RUNTIME_PROFILE_OUTPUT environment variable as follows: + +
+
+$ setenv ESMF_RUNTIME_PROFILE_OUTPUT "TEXT SUMMARY" ++ +
+ +
+By default, all PETs in an application are profiled. It may be desirable +to only profile a subset of PETs to reduce the amount of output. +An explicit list of PETs can be specified by setting the +ESMF_RUNTIME_PROFILE_PETLIST environment variable. +The syntax of this environment variable is to list +PET numbers separated by spaces. PET ranges are also supported using +the “X-Y” syntax where X < Y. +For example: + +
+
+# only profile PETs 0, 20, and 35 through 39 +$ setenv ESMF_RUNTIME_PROFILE_PETLIST "0 20 35-39" ++ +
+When used in conjunction with the SUMMARY option above, the summarized +profile will only aggregate over the specified set of PETs. The one exception is that +PET 0 is always profiled if ESMF_RUNTIME_PROFILE=ON, regardless of the +ESMF_RUNTIME_TRACE_PETLIST setting. + +
+ +
+MPI functions can be included in the timing profile to indicate how much time +is spent inside communication calls. This can also help to determine load imbalance +in the system, since large times spent inside MPI may indicate that communication +between PETs is not tightly synchronized. This option includes all MPI calls in +the application, whether or not they originate from the ESMF library. Here is a partial +example summary profile that contains MPI times: + +
+
+Region PETs Count Mean (s) Min (s) Min PET Max (s) Max PET + [esm] RunPhase1 8 1 4.9307 4.6867 0 4.9656 1 + [OCN] RunPhase1 8 1824 0.8344 0.8164 0 0.8652 1 + [MED] RunPhase1 8 1824 0.8203 0.7900 5 0.8584 1 + [ATM] RunPhase1 8 1824 0.6387 0.6212 5 0.6610 1 + [ATM-TO-MED] RunPhase1 8 1824 0.5975 0.5317 0 0.6583 5 + MPI_Bcast 8 1824 0.0443 0.0025 4 0.1231 5 + MPI_Wait 8 MULTIPLE 0.0421 0.0032 0 0.0998 2 + [MED-TO-OCN] RunPhase1 8 1824 0.4879 0.4497 0 0.5362 4 + MPI_Wait 8 MULTIPLE 0.0234 0.0030 0 0.0821 4 + MPI_Bcast 8 1824 0.0111 0.0024 4 0.0273 5 + [OCN-TO-MED] RunPhase1 8 1824 0.4541 0.4075 0 0.4918 4 + MPI_Wait 8 MULTIPLE 0.0339 0.0017 0 0.0824 4 + MPI_Bcast 8 1824 0.0194 0.0026 4 0.0452 6 + [MED-TO-ATM] RunPhase1 8 1824 0.4487 0.4005 0 0.4911 5 + MPI_Bcast 8 1824 0.0338 0.0026 4 0.0942 5 + MPI_Wait 8 MULTIPLE 0.0241 0.0022 1 0.0817 2 + [esm] Init 1 8 1 0.6287 0.6287 1 0.6287 4 + [ATM-TO-MED] IPDv05p6b 8 1 0.1501 0.1500 1 0.1501 2 + MPI_Barrier 8 242 0.0082 0.0006 3 0.0157 7 + MPI_Wait 8 MULTIPLE 0.0034 0.0010 0 0.0053 7 + MPI_Allreduce 8 62 0.0030 0.0003 3 0.0063 7 + MPI_Alltoall 8 6 0.0015 0.0000 1 0.0022 5 + MPI_Allgather 8 21 0.0010 0.0002 1 0.0017 7 + MPI_Waitall 8 MULTIPLE 0.0006 0.0001 3 0.0015 7 + MPI_Send 8 MULTIPLE 0.0004 0.0001 7 0.0008 6 + MPI_Allgatherv 8 6 0.0001 0.0001 4 0.0001 0 + MPI_Scatter 8 5 0.0000 0.0000 0 0.0000 7 + MPI_Reduce 8 5 0.0000 0.0000 1 0.0000 0 + MPI_Recv 8 MULTIPLE 0.0000 0.0000 0 0.0000 3 + MPI_Bcast 8 1 0.0000 0.0000 0 0.0000 7 ++ +
+The procedure for including MPI +functions in the timing profile depends on whether the application is +dynamically or statically linked. Most applications are dynamically linked, +however on some systems (such as Cray), static linking may be used. +Note that for either option, ESMF must be built with ESMF_TRACE_LIB_BUILD=ON, +which is the default. + +
+In dynamically linked applications, the LD_PRELOAD (Linux) or +DYLD_INSERT_LIBRARIES (Darwin) environment variable must be used when +executing the MPI application. This instructs the dynamic loader to interpose +certain MPI symbols so they can be captured by the ESMF profiler. To simplify +this process, a script is provided at $(ESMF_INSTALL_LIBDIR)/preload.sh +that sets the appropriate variable. + +
+For example, if you typically execute your application as as follows: + +
+
+$ mpirun -np 8 ./myApp ++ +
+then you should add the preload.sh script in front of the +executable when starting the application as follows: + +
+
+# replace $(ESMF_INSTALL_LIBDIR) with absolute path +# ... to the ESMF installation lib directory +$ mpirun -np 8 $(ESMF_INSTALL_LIBDIR)/preload.sh ./myApp ++ +
+An advantage of this approach is that your application does not need to +be recompiled. The MPI timing information will be included in the per-PET profiles and/or the summary +profile, depending on the setting of environment variable +ESMF_RUNTIME_PROFILE_OUTPUT. + +
+Notice that an additional step is required for dynamically linked applications +on Darwin systems with System Integrity Protection (SIP) enabled! In +addition to using the $(ESMF_INSTALL_LIBDIR)/preload.sh script during +launching of the executable as shown above, the executable must also be +linked against the dynamic ESMF trace preload library. This must happen during +the link step of the executable. It is most easily accomplished by using +variable $(ESMF_F90ESMFPRELOADLINKLIBS) instead of the typical +$(ESMF_F90ESMFLINKLIBS) variable for the final link command. Both +variables are defined in the esmf.mk file that should be imported by +the application Makefile. For example: + +
+
+# import esmf.mk +include $(ESMFMKFILE) + +# other makefile targets here... + +# example final link command, with $(ESMF_F90ESMFPRELOADLINKLIBS) +myApp: myApp.o driver.o model.o + $(ESMF_F90LINKER) $(ESMF_F90LINKOPTS) $(ESMF_F90LINKPATHS) \ + $(ESMF_F90LINKRPATHS) -o $@ $^ $(ESMF_F90ESMFPRELOADLINKLIBS) ++ +
+In statically linked applications, the application must be re-linked +with specific options provided to the linker. These options instruct the linker +to wrap the MPI symbols with the ESMF profiling functions. The linking flags that +must be provided are included in the esmf.mk Makefile fragment that +is part of the ESMF installation. These link flags should be imported into +your application Makefile, and included in the final link command. To do this, +first import the esmf.mk file into your application Makefile. The path +to this file is typically stored in the ESMFMKFILE environment variable. +Then, pass the variables $(ESMF_TRACE_STATICLINKOPTS) and +$(ESMF_TRACE_STATICLINKLIBS) to the final linking command. For example: + +
+
+# import esmf.mk +include $(ESMFMKFILE) + +# other makefile targets here... + +# example final link command, with $(ESMF_TRACE_STATICLINKOPTS) +# ... and $(ESMF_TRACE_STATICLINKLIBS) added +myApp: myApp.o driver.o model.o + $(ESMF_F90LINKER) $(ESMF_F90LINKOPTS) $(ESMF_F90LINKPATHS) \ + $(ESMF_F90LINKRPATHS) -o $@ $^ $(ESMF_F90ESMFLINKLIBS) \ + $(ESMF_TRACE_STATICLINKOPTS) $(ESMF_TRACE_STATICLINKLIBS) ++ +
+This option will statically wrap all of the MPI functions and include them +in the profile output. Execute the application in the normal way +with the environment variable ESMF_RUNTIME_PROFILE set to ON. +You will see the MPI functions included in the timing profile. + +
+ +
+ESMF tracing is disabled by default. To enable tracing, set the +ESMF_RUNTIME_TRACE environment variable to ON. You +do not need to recompile your code to enable tracing. + +
+
+# csh shell +$ setenv ESMF_RUNTIME_TRACE ON + +# bash shell +$ export ESMF_RUNTIME_TRACE=ON ++ +
+When enabled, the default behavior is to trace all PETs of the +ESMF application. Although the ESMF tracer is designed to write +events in a compact form, tracing can produce an extremely +large number of events depending on the total number of PETs and +the length of the run. To reduce output, it is possible to restrict +the PETs that produce trace output by setting the ESMF_RUNTIME_TRACE_PETLIST +environment variable. For example, this setting: + +
+
+$ setenv ESMF_RUNTIME_TRACE_PETLIST "0 101 192-196" ++ +
+will instruct the tracer to only trace PETs 0, 101, and 192 through 196 +(inclusive). The syntax of this environment variable is to list +PET numbers separated by spaces. PET ranges are also supported using +the “X-Y” syntax where X < Y. For PET counts greater than 100, it is +recommended to set this environment variable. The one exception is that +PET 0 is always traced, regardless of the ESMF_RUNTIME_TRACE_PETLIST +setting. + +
+ESMF's profiling and tracing options can be used together. A typical +use would be to set ESMF_RUNTIME_PROFILE=ON for all PETs to +capture summary timings, and set ESMF_RUNTIME_TRACE=ON and +ESMF_RUNTIME_TRACE_PETLIST to a subset of of PETs, +such as the root PET of each ESMF component. This helps to keep trace +sizes small while still providing timing summaries over all PETs. + +
+When tracing is enabled, phase_enter and phase_exit events will +automatically be recorded for all initialize, run, and finalize phases of all +Components in the application. To trace only user-instrumented regions (via +the ESMF_TraceRegionEnter() and ESMF_TraceRegionExit() calls), +Component-level tracing can be turned off by setting: + +
+
+$ setenv ESMF_RUNTIME_TRACE_COMPONENT OFF ++ +
+After running an ESMF application with tracing enabled, a directory +called traceout will be created in the run directory and it will +contain a metadata file and an event stream file esmf_stream_XXXX +for each PET with tracing enabled. Together these files form a valid +CTF trace which may be analyzed with any of the tools listed above. + +
+Trace events are flushed to file at a regular interval. If the application +crashes, some of the most recent events may not be flushed to file. To +maximize the number of events appearing in the trace, an option is available +to flush events to file more frequently. Because this option may have +negative performance implications due to increased file I/O, it is not +recommended unless needed. To turn on eager flushing use: + +
+
+$ setenv ESMF_RUNTIME_TRACE_FLUSH EAGER ++ +
+ +
+There are three options for the kind of clock to use to timestamp +events when profiling/tracing an application. +These options are controlled by setting the environment variable +ESMF_RUNTIME_TRACE_CLOCK. +
REALTIME | The REALTIME clock timestamps events with the current time on + the system. This is the default clock if the above environment + variable is not set. This setting can be useful when tracing PETs that + span multiple physical computing nodes assuming that the system clocks + on each node are adequately synchronized. On most HPC systems, system + clocks are periodically updated to stay in sync. A disadvantage of this + clock is that periodic adjustments mean the clock is not monotonically + increasing so some timings may be inaccurate if the system clock jumps + forward or backward significantly. Testing has shown that this is not + typically an issue on most systems. |
MONOTONIC | The MONOTONIC clock is guaranteed to be monotonically increasing + and does not suffer from periodic adjustments. The timestamps represent + an amount of time since some arbitrary point in the past. There is no + guarantee that these timestamps will be synchronized across physical + computing nodes, so this option should only be used for tracing a set of PETs + running on a single physical machine. |
MONOTONIC_SYNC | The MONOTONIC_SYNC clock is similar to the MONOTONIC clock + in that it is guaranteed to be monotonically increasing. In addition, at + application startup, all PET clocks are synchronized to a common time + by determining a PET-local offset to be applied to timestamps. Therefore this option + can be used to compare trace streams across physical nodes. + |
+ +
+ +
+ +
+This example illustrates how to trace a simple ESMF + application and print the event stream using Babeltrace. + The first part of the code is a module representing + a trivial ESMF Gridded Component. The second part is a + main program that creates and executes the component. +
+
+module SimpleComp + + use ESMF + implicit none + + private + public SetServices + +contains + + subroutine SetServices(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, & + userRoutine=Init, rc=rc) + call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + userRoutine=Run, rc=rc) + call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_FINALIZE, & + userRoutine=Finalize, rc=rc) + + rc = ESMF_SUCCESS + + end subroutine SetServices + + subroutine Init(gcomp, istate, estate, clock, rc) + type(ESMF_GridComp):: gcomp + type(ESMF_State):: istate, estate + type(ESMF_Clock):: clock + integer, intent(out):: rc + + print *, "Inside Init" + + end subroutine Init + + subroutine Run(gcomp, istate, estate, clock, rc) + type(ESMF_GridComp):: gcomp + type(ESMF_State):: istate, estate + type(ESMF_Clock):: clock + integer, intent(out):: rc + + print *, "Inside Run" + + end subroutine Run + + subroutine Finalize(gcomp, istate, estate, clock, rc) + type(ESMF_GridComp):: gcomp + type(ESMF_State):: istate, estate + type(ESMF_Clock):: clock + integer, intent(out):: rc + + print *, "Inside Finalize" + + end subroutine Finalize + +end module SimpleComp ++ +
+
+program ESMF_TraceEx ++ +
+
+ ! Use ESMF framework module + use ESMF + use SimpleComp, only: SetServices ++ +
+
+ implicit none + + ! Local variables + integer :: rc, finalrc, i + type(ESMF_GridComp) :: gridcomp ++ +
+
+ ! initialize ESMF + finalrc = ESMF_SUCCESS + call ESMF_Initialize(vm=vm, defaultlogfilename="TraceEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+
+ ! create the component and then execute + ! initialize, run, and finalize routines + gridcomp = ESMF_GridCompCreate(name="test", rc=rc) ++ +
+
+ call ESMF_GridCompSetServices(gridcomp, userRoutine=SetServices, rc=rc) ++ +
+
+ call ESMF_GridCompInitialize(gridcomp, rc=rc) ++ +
+
+ do i=1, 5 + call ESMF_GridCompRun(gridcomp, rc=rc) + enddo ++ +
+
+ call ESMF_GridCompFinalize(gridcomp, rc=rc) ++ +
+
+ call ESMF_GridCompDestroy(gridcomp, rc=rc) ++ +
+
+ call ESMF_Finalize(rc=rc) ++ +
+
+end program ESMF_TraceEx ++ +
+Assuming the code above is executed on four PETs with + the environment variable ESMF_RUNTIME_TRACE set to + ON, then a folder will be created in the run directory + called traceout containing a metadata file and + four event stream files named esmf_stream_XXXX + where XXXX is the PET number. If Babeltrace is + available on the system, the list of events can be printed + by executing the following from the run directory: +
+ $ babeltrace ./traceout ++ For details about iterating over trace events and performing + analyses on CTF traces, see the corresponding documentation + in the tools listed in Section 52.1.2. + + +
+ +
+ +
+ +
+This example illustrates how to manually instrument code with + entry and exit points for user-defined code regions. Note that the + API calls ESMF_TraceRegionEnter and ESMF_TraceRegionExit + should always appear in pairs, wrapping a particular section + of code. The environment variable ESMF_RUNTIME_TRACE + or ESMF_RUNTIME_PROFILE must be set to ON to enable these + regions. If not at least one is set, the calls to + ESMF_TraceRegionEnter and ESMF_TraceRegionExit + will simply return immediately. For this reason, it is safe to + leave this instrumentation in application code, even when not being profiled. +
+
+ ! Use ESMF framework module + use ESMF ++ +
+
+ implicit none + + ! Local variables + integer :: rc, finalrc + integer :: i, j, tmp ++ +
+
+ ! initialize ESMF + finalrc = ESMF_SUCCESS + call ESMF_Initialize(vm=vm, defaultlogfilename="TraceUserEx.Log", & + logkindflag=ESMF_LOGKIND_MULTI, rc=rc) ++ +
+
+ ! record entrance into "outer_region" + call ESMF_TraceRegionEnter("outer_region", rc=rc) + + tmp = 0 + do i=1, 10 + + ! record entrance into "inner_region_1" + call ESMF_TraceRegionEnter("inner_region_1", rc=rc) + ! arbitrary computation + do j=1,10000 + tmp=tmp+j+i + enddo + ! record exit from "inner_region_1" + call ESMF_TraceRegionExit("inner_region_1", rc=rc) + + tmp = 0 + + ! record entrance into "inner_region_2" + call ESMF_TraceRegionEnter("inner_region_2", rc=rc) + ! arbitrary computation + do j=1,5000 + tmp=tmp+j+i + enddo + ! record exit from "inner_region_2" + call ESMF_TraceRegionExit("inner_region_2", rc=rc) + enddo + + ! record exit from "outer_region" + call ESMF_TraceRegionExit("outer_region", rc=rc) ++ +
+
+ call ESMF_Finalize(rc=rc) ++ +
+ + +
+ +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_TraceRegionEnter(name, rc) +ARGUMENTS: +
character(len=*), intent(in) :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Record an event in the trace for this PET indicating entry + into a user-defined region with the given name. This call + must be paired with a call to ESMF_TraceRegionExit() + with a matching name parameter. User-defined regions may be + nested. + If tracing is disabled on the calling PET or for the application + as a whole, no event will be recorded and + the call will return immediately. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_TraceRegionExit(name, rc) +ARGUMENTS: +
character(len=*), intent(in) :: name + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Record an event in the trace for this PET indicating exit + from a user-defined region with the given name. This call + must appear after a call to ESMF_TraceRegionEnter() + with a matching name parameter. + If tracing is disabled on the calling PET or for the application + as a whole, no event will be recorded and + the call will return immediately. + +
+The arguments are: +
+The ESMF Fortran I/O and System utilities provide portable methods to +access capabilities which are often implemented in different +ways amongst different environments. These utility methods are +divided into three groups: command line access, Fortran I/O, and +sorting. + +
+Command line arguments may be accessed using three methods: +ESMF_UtilGetArg() returns a given command line argument, +ESMF_UtilGetArgC() returns a count of the number of command line +arguments available. Finally, the ESMF_UtilGetArgIndex() method +returns the index of a desired argument value, given its keyword name. + +
+Two I/O methods are implemented: ESMF_IOUnitGet(), +to obtain an unopened Fortran unit number within the range of unit numbers that +ESMF is allowed to use, and ESMF_IOUnitFlush() to flush the +I/O buffer associated with a specific Fortran unit. + +
+Finally, the ESMF_UtilSort() method sorts integer, floating point, +and character string data types in either ascending or descending order. + + +
+ +
+
+ call ESMF_UtilIOUnitGet (unit=grid_unit, rc=rc) + open (unit=grid_unit, file='grid_data.dat', status='old', action='read') ++ +
+By default, unit numbers between 50 and 99 are scanned to find an unopened +unit number. + +
+Internally, ESMF also uses ESMF_UtilIOUnitGet() when it needs to open +Fortran unit numbers for file I/O. By using the same API for both user and +ESMF code, unit number collisions can be avoided. + +
+When integrating ESMF into an application where there are conflicts with +other uses of the same unit number range, such as when hard-coded unit number +values are used, an alternative unit number range can be specified. +The ESMF_Initialize() optional arguments IOUnitLower and IOUnitUpper +may be set as needed. Note that IOUnitUpper must be set to a value higher than +IOUnitLower, and that both must be non-negative. Otherwise ESMF_Initialize +will return a return code of ESMF_FAILURE. ESMF itself does not typically need more +than about five units for internal use. + +
+
+ call ESMF_Initialize (..., IOUnitLower=120, IOUnitUpper=140) ++ +
+All current Fortran environments have preconnected unit numbers, such as +units 5 and 6 for standard input and output, in the single digit range. +So it is recommended that the unit number range is chosen to begin at unit 10 +or higher to avoid these preconnected units. + +
+ +
+Fortran run-time libraries generally use buffering techniques to improve I/O +performance. However output buffering can be problematic when output is needed, +but is “trapped” in the buffer because it is not full. +This is a common occurrance when debugging a program, and inserting WRITE statements +to track down the bad area of code. If the program crashes before the output +buffer has been flushed, the desired debugging output may never be seen -- giving +a misleading indication of where the problem occurred. It would be desirable +to ensure that the output buffer is flushed at predictable +points in the program in order to get the needed results. +Likewise, in parallel code, predictable flushing of output buffers is a common +requirement, often in conjunction with ESMF_VMBarrier() calls. + +
+The ESMF_UtilIOUnitFlush() API is provided to flush a unit as desired. Here is +an example of code which prints debug values, and serializes the output to a +terminal in PET order: + +
+
+ type(ESMF_VM) :: vm + + integer :: tty_unit + integer :: me, npets + + call ESMF_Initialize (vm=vm, rc=rc) + call ESMF_VMGet (vm, localPet=me, petCount=npes) + + call ESMF_UtilIOUnitGet (unit=tty_unit) + open (unit=tty_unit, file='/dev/tty', status='old', action='write') + ... + call ESMF_VMBarrier (vm=vm) + do, i=0, npets-1 + if (i == me) then + write (tty_unit, *) 'PET: ', i, ', values are: ', a, b, c + call ESMF_UtilIOUnitFlush (unit=tty_unit) + end if + call ESMF_VMBarrier (vm=vm) + end do ++ +
+ +
+When ESMF needs to open a Fortran I/O unit, it calls ESMF_IOUnitGet() to find +an unopened unit number. As delivered, the range of unit numbers that are +searched are between ESMF_LOG_FORTRAN_UNIT_NUMBER (normally set to +50), and ESMF_LOG_UPPER (normally set to 99.) +Unopened unit numbers are found by using the Fortran INQUIRE statement. + +
+When integrating ESMF into an application where there are conflicts with +other uses of the same unit number range, an alternative range can be specified +in the ESMF_Initialize() call by setting the IOUnitLower and IOUnitUpper +arguments as needed. ESMF_IOUnitGet() will then search the alternate range +of unit numbers. Note that IOUnitUpper must be set to a value higher than +IOUnitLower, and that both must be non-negative. Otherwise ESMF_Initialize +will return a return code of ESMF_FAILURE. + +
+Fortran unit numbers are not standardized in the Fortran 90 Standard. The standard +only requires that they be non-negative integers. But other than that, it is +up to the compiler writers and application developers to provide and +use units which work with the particular implementation. For example, +units 5 and 6 are a defacto standard for “standard input” and +“standard output” -- even though this is not specified in the actual Fortran +standard. The Fortran standard also does not specify which unit numbers can +be used, nor does it specify how many can be open simultaneously. + +
+Since all current compilers have preconnected unit numbers, and these are +typically found on units lower than 10, it is recommended that applications +use unit numbers 10 and higher. + +
+ +
+When ESMF needs to flush a Fortran unit, the ESMF_IOUnitFlush() API is used +to centralize the file flushing capability, because Fortran has not historically +had a standard mechanism for flushing output buffers. Most compilers run-time libraries +support various library extensions to provide this functionality -- though, +being non-standard, the spelling and number of arguments vary between implementations. +Fortran 2003 also provides for a FLUSH statement which is built into the +language. When possible, ESMF_IOUnitFlush() uses the F2003 FLUSH statement. +With older compilers, the appropriate library call is made. + +
+ +
+The ESMF_UtilSort() algorithms are the same as those in the LAPACK +sorting procedures SLASRT() and DLASRT(). Two algorithms are used. +For small sorts, arrays with 20 or fewer elements, a simple Insertion sort is +used. For larger sorts, a Quicksort algorithm is used. + +
+Compared to the original LAPACK code, a full Fortran 90 style +interface is supported for ease of use and enhanced compile time checking. +Additional support is also provided for integer and character string data +types. + +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_UtilGetArg(argindex, argvalue, arglength, rc) +ARGUMENTS: +
integer, intent(in) :: argindex + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(*), intent(out), optional :: argvalue + integer, intent(out), optional :: arglength + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This method returns a copy of a command line argument specified + when the process was started. This argument is the same as an + equivalent C++ program would find in the argv array. + +
+Some MPI implementations do not consistently provide command line + arguments on PETs other than PET 0. It is therefore recommended + that PET 0 call this method and broadcast the results to the other + PETs by using the ESMF_VMBroadcast() method. + +
+The arguments are: + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_UtilGetArgC(count, rc) +ARGUMENTS: +
integer, intent(out) :: count + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This method returns the number of command line arguments specified + when the process was started. + +
+The number of arguments returned does not include the name of the + command itself - which is typically returned as argument zero. + +
+Some MPI implementations do not consistently provide command line + arguments on PETs other than PET 0. It is therefore recommended + that PET 0 call this method and broadcast the results to the other + PETs by using the ESMF_VMBroadcast() method. + +
+The arguments are: + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_UtilGetArgIndex(argvalue, argindex, rc) +ARGUMENTS: +
character(*), intent(in) :: argvalue + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: argindex + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+This method searches for, and returns the index of a desired command + line argument. An example might be to find a specific keyword + (e.g., -esmf_path) so that its associated value argument could be + obtained by adding 1 to the argindex and calling ESMF_UtilGetArg(). + +
+Some MPI implementations do not consistently provide command line + arguments on PETs other than PET 0. It is therefore recommended + that PET 0 call this method and broadcast the results to the other + PETs by using the ESMF_VMBroadcast() method. + +
+The arguments are: + +
+
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_UtilIOGetCWD (pathName, rc) +PARAMETERS: +
character(*), intent(out) :: pathName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Call the system-dependent routine to get the current directory from the file + system. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_UtilIOMkDir (pathName, & + mode, relaxedFlag, & + rc) +PARAMETERS: +
character(*), intent(in) :: pathName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: mode + logical, intent(in), optional :: relaxedFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Call the system-dependent routine to create a directory in the file system. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_UtilIORmDir (pathName, & + relaxedFlag, rc) +PARAMETERS: +
character(*), intent(in) :: pathName + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + logical, intent(in), optional :: relaxedFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Call the system-dependent routine to remove a directory from the file + system. Note that the directory must be empty in order to be successfully + removed. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_UtilString2Double(string, rc) +RETURN VALUE: +
real(ESMF_KIND_R8) :: ESMF_UtilString2Double +ARGUMENTS: +
character(len=*), intent(in) :: string + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the numerical real value represented by the string. + +
+Leading and trailing blanks in string are ignored when directly + converting into integers. + +
+This procedure may fail when used in an expression in a write statement + with some older, pre-Fortran 2003, compiler environments that do not support + re-entrant I/O calls. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_UtilString2Int(string, & + specialStringList, specialValueList, rc) +RETURN VALUE: +
integer :: ESMF_UtilString2Int +ARGUMENTS: +
character(len=*), intent(in) :: string + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: specialStringList(:) + integer, intent(in), optional :: specialValueList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the numerical integer value represented by the string. + If string matches a string in the optional specialStringList, the + corresponding special value will be returned instead. + +
+If special strings are to be taken into account, both + specialStringList and specialValueList arguments must be + present and of same size. + +
+An error is returned, and return value set to 0, if string is not + found in specialStringList, and does not convert into an integer + value. + +
+Leading and trailing blanks in string are ignored when directly + converting into integers. + +
+This procedure may fail when used in an expression in a write statement + with some older, pre-Fortran 2003, compiler environments that do not support + re-entrant I/O calls. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_UtilString2Real(string, rc) +RETURN VALUE: +
real :: ESMF_UtilString2Real +ARGUMENTS: +
character(len=*), intent(in) :: string + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the numerical real value represented by the string. + +
+Leading and trailing blanks in string are ignored when directly + converting into integers. + +
+This procedure may fail when used in an expression in a write statement + with some older, pre-Fortran 2003, compiler environments that do not support + re-entrant I/O calls. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_UtilStringDiffMatch(string1, string2, minusStringList, & + plusStringList, rc) +RETURN VALUE: +
logical :: ESMF_UtilStringDiffMatch +ARGUMENTS: +
character(len=*), intent(in) :: string1 + character(len=*), intent(in) :: string2 + character(len=*), intent(in) :: minusStringList(:) + character(len=*), intent(in) :: plusStringList(:) + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Match the list of differences between string1 and string2 + against plus and minus string pairs. + The generated differences are based on Myers diff algorithm implementation + provided by https://github.com/gritzko/myers-diff. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_UtilStringInt2String (i, rc) +ARGUMENTS: +
integer, intent(in) :: i + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc +RETURN VALUE: +
character(int2str_len (i)) :: ESMF_UtilStringInt2String ++DESCRIPTION: +
+Converts given an integer to string representation. The returned string is + sized such that it does not contain leading or trailing blanks. + +
+This procedure may fail when used in an expression in a write statement + with some older, pre-Fortran 2003, compiler environments that do not support + re-entrant I/O calls. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_UtilStringLowerCase(string, rc) +ARGUMENTS: +
character(len=*), intent(in) :: string + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc +RETURN VALUE: +
character(len (string)) :: ESMF_UtilStringLowerCase ++DESCRIPTION: +
+Converts given string to lowercase. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
function ESMF_UtilStringUpperCase(string, rc) +ARGUMENTS: +
character(len=*), intent(in) :: string + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc +RETURN VALUE: +
character(len (string)) :: ESMF_UtilStringUpperCase ++DESCRIPTION: +
+Converts given string to uppercase. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_UtilIOUnitFlush(unit, rc) +PARAMETERS: +
integer, intent(in) :: unit + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Call the system-dependent routine to force output on a specific + Fortran unit number. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_UtilIOUnitGet(unit, rc) +ARGUMENTS: +
integer, intent(out) :: unit + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(out), optional :: rc ++STATUS: + +
+DESCRIPTION:
+
+
+
+Scan for, and return, a free Fortran I/O unit number. + By default, the range of unit numbers returned is between 50 and 99 + (parameters ESMF_LOG_FORTRAN_UNIT_NUMBER and ESMF_LOG_UPPER + respectively.) When integrating ESMF into an application where these values + conflict with other usages, the range of values may be moved by setting the + optional IOUnitLower and IOUnitUpper arguments in the initial + ESMF_Initialize() call with values in a safe, alternate, range. + +
+The Fortran unit number which is returned is not reserved in any way. + Successive calls without intervening OPEN or CLOSE statements + (or other means of connecting to units), might not return a unique unit + number. It is recommended that an OPEN statement immediately follow + the call to ESMF_IOUnitGet() to activate the unit. + +
+The arguments are: +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_UtilSort (list, direction, rc) +ARGUMENTS: +
<list>, see below for supported values + type(ESMF_SortFlag), intent(in) :: direction + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Supported values for <list> are: +
+Use Quick Sort, reverting to Insertion sort on lists of + size <= 20. + +
+This is an ESMFized version of SLASRT from LAPACK version 3.1. + Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd. + November 2006 + +
+The arguments are: +
+ + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_refdoc/node7.html b/docs/nightly/fix/reconcile-info/ESMF_refdoc/node7.html new file mode 100644 index 000000000..e967fcd2c --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_refdoc/node7.html @@ -0,0 +1,59 @@ + + + + + ++ +
+ +
+ +
+DESCRIPTION:
+
+An integer named constant which is used to indicate that a particular dimension is arbitrarily distributed.
+
+
+ +
+ +
+ +
+The type of this flag is: + +
+type(ESMF_AttNest_Flag) + +
+The valid values are: +
+ +
+The type of this flag is: + +
+type(ESMF_AttReconcileFlag) + +
+The valid values are: +
+ +
+ +
+ +
+The type of this flag is: + +
+type(ESMF_CompType_Flag) + +
+The valid values are: +
+ +
+The type of this flag is: + +
+type(ESMF_Context_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+ A set of values which indicates in which system the coordinates in a class (e.g. Grid) are. This type is useful both
+to indicate to other users the type of the coordinates, but also to control how the coordinates are interpreted in ESMF
+methods which depend on the coordinates (e.g. regridding methods like ESMF_FieldRegridStore()).
+
+
+The type of this flag is: + +
+type(ESMF_CoordSys_Flag) + +
+The valid values are: +
+
+
+
+ +
+The type of this flag is: + +
+type(ESMF_CubedSphereCalc_Flag) + +
+The valid values are: +
+ +
+The type of this flag is: + +
+type(ESMF_DataCopy_Flag) + +
+The valid values are: +
+ +
+The type of this flag is: + +
+type(ESMF_Decomp_Flag) + +
+The valid values are: +
+ +
+ +
+ +
+This flag is documented in section 16.2.1. + +
+ +
+DESCRIPTION:
+
+Specify which extrapolation method to use on unmapped destination points after regridding.
+
+
+The type of this flag is: + +
+type(ESMF_ExtrapMethod_Flag) + +
+The valid values are: +
+ +
+ +
+The type of this flag is: + +
+type(ESMF_FileFormat_Flag) + +
+The valid values are: +
+
+
+
+
+
+
+ +
+The type of this flag is: + +
+type(ESMF_FileMode_Flag) + +
+The valid values are: +
+
+ +
+The type of this flag is: + +
+type(ESMF_FileStatus_Flag) + +
+The valid values are: +
+
+ +
+DESCRIPTION:
+
+ Different types of geometries upon which an ESMF Field or ESMF Fieldbundle may
+be built.
+
+
+The type of this flag is: + +
+type(ESMF_GeomType_Flag) + +
+The valid values are: +
+ +
+ +
+ +
+ +
+ +
+ +
+The type of this flag is: + +
+type(ESMF_Index_Flag) + +
+The valid values are: +
+ +
+The type of this flag is: + +
+type(ESMF_IOFmt_Flag) + +
+The valid values are: +
+ +
+The type of this flag is: + +
+logical + +
+The valid values are: +
+ +
+The type of this flag is: + +
+logical + +
+The valid values are: +
+ +
+The type of this flag is: + +
+logical + +
+The valid values are: +
+ +
+The type of this flag is: + +
+type(ESMF_ItemOrder_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+Named constants to be used as kind-parameter in Fortran variable
+ declarations. For example:
+
+ integer(ESMF_KIND_I4) :: integerVariable + integer(kind=ESMF_KIND_I4) :: integerVariable + real(ESMF_KIND_R4) :: realVariable + real(kind=ESMF_KIND_R4) :: realVariable ++The Fortran standard does not mandate what numeric values correspond to +actual number of bytes allocated for the various kinds. The following constants +are defined by ESMF to be correct across the supported Fortran compilers. +Note that not all compilers support every kind listed below; in particular +1 and 2 byte integers can be problematic. + +
+The type of these named constants is: + +
+integer + +
+The named constants are: +
+ +
+DESCRIPTION:
+
This argument allows the user to select the path of the line which connects two points on the surface of a sphere.
+This in turn controls the path along which distances are calculated and the shape of the edges that make up a cell.
+
+
+The type of this flag is: + +
+type(ESMF_LineType_Flag) + +
+The valid values are: +
+ +
+ +
+ +
+ +
+ +
+The type of this flag is: + +
+type(ESMF_MeshLoc) + +
+The valid values are: +
+
+ +
+The type of this flag is: + +
+type(ESMF_MeshOp_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+The ESMF Mesh class can exist in several states. The ESMF_MESHSTATUS
+flag is used to indicate which of these states a Mesh is currently in.
+
+
+The type of this flag is: + +
+type(ESMF_MeshStatus_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+Specify standard ESMF Component method.
+
+
+The type of this flag is: + +
+type(ESMF_Method_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
When doing conservative regridding (e.g. ESMF_REGRIDMETHOD_CONSERVE), this option allows the user to select the type of normalization used when producing the weights.
+
+
+type(ESMF_NormType_Flag) + +
+The valid values are: +
+ +
+ +
+ +
+DESCRIPTION:
+
+
+When interpolating between two Grids which have been mapped to a sphere these can be used to specify the type of artificial pole to create on the source Grid during interpolation. Creating the pole allows destination points above the top row or below the bottom row of the source Grid to still be mapped.
+
+
+The type of this flag is: + +
+type(ESMF_PoleMethod_Flag) + +
+The valid values are: +
+ +
+The type of this flag is: + +
+type(ESMF_Reduce_Flag) + +
+The valid values are: +
+ +
+The type of this flag is: + +
+type(ESMF_Region_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+Specify which interpolation method to use during regridding. For a more detailed discussion of these methods, as well as ESMF regridding in general, see Section 24.2.
+
+
+The type of this flag is: + +
+type(ESMF_RegridMethod_Flag) + +
+The valid values are: +
+
+ +
+DESCRIPTION:
+
+ These values can be output during regridding (e.g. from ESMF_FieldRegridStore() via the dstStatusField argument). They indicate the status of each destination location.
+
+
+The type of this flag is: + +
+integer(ESMF_KIND_I4) + +
+The valid values for all regrid methods are: +
+In addition to the above, regridding using the conservative method can result in other values. The reason for this is that in that method one destination cell can overlap multiple source cells, so a single destination can have a combination of values. +The following are the additional values that apply to the conservative method: +
+ +
+The type of this flag is: + +
+type(ESMF_RouteSync_Flag) + +
+The valid values are: +
+ +
+ +
+ +
+The type of this flag is: + +
+type(ESMF_StartRegion_Flag) + +
+The valid values are: +
+ +
+ +
+ +
+For VM communication calls the ESMF_SYNC_BLOCKING and ESMF_SYNC_NONBLOCKING +modes provide behavior that is practically identical to the blocking and +non-blocking communication calls familiar from MPI. + +
+The details of how the blocking mode setting affects Component methods are +more complex. This is a consequence of the fact that ESMF Components can be +executed in threaded or non-threaded mode. However, in the default, +non-threaded case, where an ESMF application runs as a pure MPI or mpiuni +program, most of the complexity is removed. + +
+See the VM item in 6.6 for an +explanation of the PET and VAS concepts used in the following +descriptions. + +
+The type of this flag is: + +
+type(ESMF_Sync_Flag) + +
+The valid values are: +
+Component calls: The called method will block until all PETs of + the VM have completed the operation. + +
+For a non-threaded, pure MPI + component the behavior is identical to calling a barrier before + returning from the method. Generally this kind of rigid + synchronization is not the desirable mode of operation for an MPI + application, but may be useful for application debugging. + In the opposite case, where all PETs of the component are running as + threads in shared memory, i.e. in a single VAS, strict synchronization + of all PETs is required to prevent race conditions. + +
+
+Component calls: The called method will block each PET until + all operations in the PET-local VAS have completed. + +
+This mode is a combination of ESMF_SYNC_BLOCKING and + ESMF_SYNC_NONBLOCKING modes. It provides a default setting + that leads to the typically desirable behavior for pure MPI + components as well as those that share address spaces between PETs. + +
+For a non-threaded, pure MPI component each PET returns + independent of the other PETs. This is generally the expected + behavior in the pure MPI case where calling into a component method is + practically identical to a subroutine call without extra + synchronization between the processes. + +
+In the case where some PETs of the component are running as + threads in shared memory ESMF_SYNC_VASBLOCKING becomes identical + to ESMF_SYNC_BLOCKING within thread groups, to prevent race + conditions, while there is no synchronization between the thread + groups. + +
+
+Component calls: The behavior of this mode is fundamentally + different for threaded and non-threaded components, + independent on whether the components use shared memory or not. + The ESMF_SYNC_NONBLOCKING mode is the most complex mode for + calling component methods and should only be used if the extra + control, described below, is absolutely necessary. + +
+For non-threaded components (the ESMF default) + calling a component method with ESMF_SYNC_NONBLOCKING + is identical to calling it with ESMF_SYNC_VASBLOCKING. However, + different than for ESMF_SYNC_VASBLOCKING, a call to + ESMF_GridCompWait() or ESMF_CplCompWait() is + required in order to deallocate memory internally allocated for the + ESMF_SYNC_NONBLOCKING mode. + +
+For threaded components the calling PETs + of the parent component will not be blocked and return immediately + after initiating the requested child component method. In this + scenario parent and child components will run concurrently in + identical VASs. This is the most complex mode of operation. + It is unsafe to modify or use VAS local data that + may be accessed by concurrently running components until the child + component method has completed. Use the appropriate + ESMF_GridCompWait() or ESMF_CplCompWait() method to + block the local parent PET until the child component method has + completed in the local VAS. +
+ +
+The type of this flag is: + +
+type(ESMF_TermOrder_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+Named constants used to indicate type and kind combinations supported by the
+overloaded ESMF interfaces. The corresponding Fortran kind-parameter constants
+are described in section 54.35.
+
+
+The type of these named constants is: + +
+type(ESMF_TypeKind_Flag) + +
+The named constants numerical types are: +
+
+The named constants non-numerical types are: +
+
+ +
+The type of this flag is: + +
+type(ESMF_UnmappedAction_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+The following named constants define the precise version of ESMF in use.
+
+
+
+ +
+ +
+ +
+The schematic below shows the Unified Modeling Language (UML) notation +for the class diagrams presented in this Reference Manual. For +more on UML, see references such as The Unified Modeling Language +Reference Manual, Rumbaugh et al, [29]. + +
+
+ +
+The tables below show the possible error return codes for Fortran and +C methods. + +
+ +
+ +
+ +
+
+ + ===================================== + Fortran Symmetric Return Codes 1-500 + ===================================== + + ESMF_SUCCESS 0 + ESMF_RC_OBJ_BAD 1 + ESMF_RC_OBJ_INIT 2 + ESMF_RC_OBJ_CREATE 3 + ESMF_RC_OBJ_COR 4 + ESMF_RC_OBJ_WRONG 5 + ESMF_RC_ARG_BAD 6 + ESMF_RC_ARG_RANK 7 + ESMF_RC_ARG_SIZE 8 + ESMF_RC_ARG_VALUE 9 + ESMF_RC_ARG_DUP 10 + ESMF_RC_ARG_SAMETYPE 11 + ESMF_RC_ARG_SAMECOMM 12 + ESMF_RC_ARG_INCOMP 13 + ESMF_RC_ARG_CORRUPT 14 + ESMF_RC_ARG_WRONG 15 + ESMF_RC_ARG_OUTOFRANGE 16 + ESMF_RC_ARG_OPT 17 + ESMF_RC_NOT_IMPL 18 + ESMF_RC_FILE_OPEN 19 + ESMF_RC_FILE_CREATE 20 + ESMF_RC_FILE_READ 21 + ESMF_RC_FILE_WRITE 22 + ESMF_RC_FILE_UNEXPECTED 23 + ESMF_RC_FILE_CLOSE 24 + ESMF_RC_FILE_ACTIVE 25 + ESMF_RC_PTR_NULL 26 + ESMF_RC_PTR_BAD 27 + ESMF_RC_PTR_NOTALLOC 28 + ESMF_RC_PTR_ISALLOC 29 + ESMF_RC_MEM 30 + ESMF_RC_MEM_ALLOCATE 31 + ESMF_RC_MEM_DEALLOCATE 32 + ESMF_RC_MEMC 33 + ESMF_RC_DUP_NAME 34 + ESMF_RC_LONG_NAME 35 + ESMF_RC_LONG_STR 36 + ESMF_RC_COPY_FAIL 37 + ESMF_RC_DIV_ZERO 38 + ESMF_RC_CANNOT_GET 39 + ESMF_RC_CANNOT_SET 40 + ESMF_RC_NOT_FOUND 41 + ESMF_RC_NOT_VALID 42 + ESMF_RC_INTNRL_LIST 43 + ESMF_RC_INTNRL_INCONS 44 + ESMF_RC_INTNRL_BAD 45 + ESMF_RC_SYS 46 + ESMF_RC_BUSY 47 + ESMF_RC_LIB 48 + ESMF_RC_LIB_NOT_PRESENT 49 + ESMF_RC_ATTR_UNUSED 50 + ESMF_RC_OBJ_NOT_CREATED 51 + ESMF_RC_OBJ_DELETED 52 + ESMF_RC_NOT_SET 53 + ESMF_RC_VAL_WRONG 54 + ESMF_RC_VAL_ERRBOUND 55 + ESMF_RC_VAL_OUTOFRANGE 56 + ESMF_RC_ATTR_NOTSET 57 + ESMF_RC_ATTR_WRONGTYPE 58 + ESMF_RC_ATTR_ITEMSOFF 59 + ESMF_RC_ATTR_LINK 60 + ESMF_RC_BUFFER_SHORT 61 + ESMF_RC_TIMEOUT 62 + ESMF_RC_FILE_EXISTS 63 + ESMF_RC_FILE_NOTDIR 64 + ESMF_RC_MOAB_ERROR 65 + ESMF_RC_NOOP 66 + ESMF_RC_NETCDF_ERROR 67 + + 68-499 reserved for future Fortran symmetric return code definitions + + ===================================== + C/C++ Symmetric Return Codes 501-999 + ===================================== + + ESMC_RC_OBJ_BAD 501 + ESMC_RC_OBJ_INIT 502 + ESMC_RC_OBJ_CREATE 503 + ESMC_RC_OBJ_COR 504 + ESMC_RC_OBJ_WRONG 505 + ESMC_RC_ARG_BAD 506 + ESMC_RC_ARG_RANK 507 + ESMC_RC_ARG_SIZE 508 + ESMC_RC_ARG_VALUE 509 + ESMC_RC_ARG_DUP 510 + ESMC_RC_ARG_SAMETYPE 511 + ESMC_RC_ARG_SAMECOMM 512 + ESMC_RC_ARG_INCOMP 513 + ESMC_RC_ARG_CORRUPT 514 + ESMC_RC_ARG_WRONG 515 + ESMC_RC_ARG_OUTOFRANGE 516 + ESMC_RC_ARG_OPT 517 + ESMC_RC_NOT_IMPL 518 + ESMC_RC_FILE_OPEN 519 + ESMC_RC_FILE_CREATE 520 + ESMC_RC_FILE_READ 521 + ESMC_RC_FILE_WRITE 522 + ESMC_RC_FILE_UNEXPECTED 523 + ESMC_RC_FILE_CLOSE 524 + ESMC_RC_FILE_ACTIVE 525 + ESMC_RC_PTR_NULL 526 + ESMC_RC_PTR_BAD 527 + ESMC_RC_PTR_NOTALLOC 528 + ESMC_RC_PTR_ISALLOC 529 + ESMC_RC_MEM 530 + ESMC_RC_MEM_ALLOCATE 531 + ESMC_RC_MEM_DEALLOCATE 532 + ESMC_RC_MEMC 533 + ESMC_RC_DUP_NAME 534 + ESMC_RC_LONG_NAME 535 + ESMC_RC_LONG_STR 536 + ESMC_RC_COPY_FAIL 537 + ESMC_RC_DIV_ZERO 538 + ESMC_RC_CANNOT_GET 539 + ESMC_RC_CANNOT_SET 540 + ESMC_RC_NOT_FOUND 541 + ESMC_RC_NOT_VALID 542 + ESMC_RC_INTNRL_LIST 543 + ESMC_RC_INTNRL_INCONS 544 + ESMC_RC_INTNRL_BAD 545 + ESMC_RC_SYS 546 + ESMC_RC_BUSY 547 + ESMC_RC_LIB 548 + ESMC_RC_LIB_NOT_PRESENT 549 + ESMC_RC_ATTR_UNUSED 550 + ESMC_RC_OBJ_NOT_CREATED 551 + ESMC_RC_OBJ_DELETED 552 + ESMC_RC_NOT_SET 553 + ESMC_RC_VAL_WRONG 554 + ESMC_RC_VAL_ERRBOUND 555 + ESMC_RC_VAL_OUTOFRANGE 556 + ESMC_RC_ATTR_NOTSET 557 + ESMC_RC_ATTR_WRONGTYPE 558 + ESMC_RC_ATTR_ITEMSOFF 559 + ESMC_RC_ATTR_LINK 560 + ESMC_RC_BUFFER_SHORT 561 + ESMC_RC_TIMEOUT 562 + ESMC_RC_FILE_EXISTS 563 + ESMC_RC_FILE_NOTDIR 564 + ESMC_RC_MOAB_ERROR 565 + ESMC_RC_NOOP 566 + ESMC_RC_NETCDF_ERROR 567 + + 568-999 reserved for future C/C++ symmetric return code definitions + + ===================================== + C/C++ Non-symmetric Return Codes 1000 + ===================================== + + ESMC_RC_OPTARG_BAD 1000 ++ + +
+ +
+ +
+DESCRIPTION:
+
+Indicates which type of copy behavior is used when copying ESMF Attribute objects.
+
+
+The type of this flag is: + +
+type(ESMF_AttCopy_Flag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+Indicates which type of Attribute object count to return.
+
+
+The type of this flag is: + +
+type(ESMF_AttGetCountFlag) + +
+The valid values are: +
+ +
+DESCRIPTION:
+
+Indicates which file format to use in the write operation.
+
+
+The type of this flag is: + +
+type(ESMF_AttWriteFlag) + +
+The valid values are: +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_AttributeAdd() + subroutine ESMF_AttAddPackInfo(info, convention, purpose, attrList, & + nestConvention, nestPurpose, attpack, rc) +ARGUMENTS: +
type(<ESMF_Info>), intent(inout) :: info + character (len = *), intent(in) :: convention + character (len = *), intent(in) :: purpose + character (len = *), intent(in), optional :: attrList(:) + character (len = *), intent(in) optional :: nestConvention + character (len = *), intent(in) optional :: nestPurpose + type(ESMF_AttPack), intent(out), optional :: attpack + integer, intent(inout), optional :: rc ++STATUS: + DEPRECATED CLASS! +
+DESCRIPTION:
+
+
+
+Add an ESMF Attribute package. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_AttributeAdd() + subroutine ESMF_AttAddPackStd(target, convention, purpose, attrList, & + nestConvention, nestPurpose, attpack, rc) +ARGUMENTS: +
type(<object>), intent(inout) :: target + character (len = *), intent(in) :: convention + character (len = *), intent(in) :: purpose + character (len = *), intent(in), optional :: attrList(:) + character (len = *), intent(in) optional :: nestConvention + character (len = *), intent(in) optional :: nestPurpose + type(ESMF_AttPack), intent(out), optional :: attpack + integer, intent(inout), optional :: rc ++STATUS: + DEPRECATED CLASS! +
+DESCRIPTION:
+
+
+
+Add an ESMF Attribute package containing a nested Attribute package. + +
+Supported values for <object> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_AttributeCopy() + subroutine ESMF_AttributeCopy(src, dst, attcopy, rc) +ARGUMENTS: +
type(<object>), intent(in) :: src + type(<object>), intent(inout) :: dst + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_AttCopy_Flag), intent(in), optional :: attcopy + integer, intent(out), optional :: rc ++STATUS: + DEPRECATED CLASS! +
+DESCRIPTION:
+
+
+
+Copy an Attribute hierarchy from src to dst. + +
+Supported values for <object> are: +
+NOTE: Copies between different ESMF object types are not possible. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AttributeGet(target, name, attpack, <value> & + <defaultvalue>, attnestflag, isPresent, rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + character (len = *), intent(in) :: name + type(ESMF_AttPack), intent(inout) :: attpack + <value>, see below for supported values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + <defaultvalue>, see below for supported values + type(ESMF_AttNest_Flag),intent(in), optional :: attnestflag + logical, intent(out), optional :: isPresent + integer, intent(inout), optional :: rc ++STATUS: + DEPRECATED CLASS! +
+DESCRIPTION:
+
+
+
+Return an Attribute value from the target, or from an Attribute + package on the target, specified by attpack. A defaultvalue + argument may be given if a return code is not desired when the Attribute is + not found. + +
+Supported values for <object> are: +
+Supported types for <value> and <defaultvalue> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AttributeGet(target, name, attpack, <valueList>, & + <defaultvalueList>, attnestflag, itemCount, & + isPresent, rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + character (len = *), intent(in) :: name + type(ESMF_AttPack), intent(inout) :: attpack + <valueList>, see below for supported values + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + <defaultvalueList>, see below for supported values + type(ESMF_AttNest_Flag),intent(in), optional :: attnestflag + integer, intent(out), optional :: itemCount + logical, intent(out), optional :: isPresent + integer, intent(inout), optional :: rc ++STATUS: + DEPRECATED CLASS! +
+DESCRIPTION:
+
+
+
+Return an Attribute valueList from the target, or from an + Attribute package on the target, specified by attpack. A + defaultvalueList list argument may be given if a return code is not + desired when the Attribute is not found. + +
+Supported values for <object> are: +
+Supported types for <valueList> and <defaultvalueList> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AttributeGet(target, name, <value>, <defaultvalue>, & + convention, purpose, attnestflag, isPresent, rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + character (len = *), intent(in) :: name + <value>, see below for supported values + <defaultvalue>, see below for supported values + character (len = *), intent(in), optional :: convention + character (len = *), intent(in), optional :: purpose + type(ESMF_AttNest_Flag),intent(in), optional :: attnestflag + logical, intent(out), optional :: isPresent + integer, intent(inout), optional :: rc ++STATUS: + The following parameters were removed in ESMF version 8.1.0: + +
+STATUS:
+ DEPRECATED CLASS!
+
+The entire ESMF_Attribute class has been deprecated and is scheduled for removal with ESMF 9.0.0. This includes all of the class derived types, named constants, and methods. Please use the replacment class ESMF_Info, section 40 instead!
+
+
+DESCRIPTION:
+
+
+
+Return an Attribute value from the target, or from an Attribute + package on the target, specified by convention and purpose. + A defaultvalue argument may be given if a return code is not desired + when the Attribute is not found. + +
+Supported values for <object> are: +
+Supported types for <value> and <defaultvalue> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AttributeGet(target, name, <valueList>, <defaultvalueList>, & + convention, purpose, attnestflag, itemCount, isPresent, rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + character (len = *), intent(in) :: name + <valueList>, see below for supported values + <defaultvalueList>, see below for supported values + character (len = *), intent(in), optional :: convention + character (len = *), intent(in), optional :: purpose + type(ESMF_AttNest_Flag),intent(in), optional :: attnestflag + integer, intent(out), optional :: itemCount + logical, intent(out), optional :: isPresent + integer, intent(inout), optional :: rc ++STATUS: + The following parameters were removed in ESMF version 8.1.0: + +
+STATUS:
+ DEPRECATED CLASS!
+
+The entire ESMF_Attribute class has been deprecated and is scheduled for removal with ESMF 9.0.0. This includes all of the class derived types, named constants, and methods. Please use the replacment class ESMF_Info, section 40 instead!
+
+
+DESCRIPTION:
+
+
+
+Return an Attribute valueList from the target, or from an + Attribute package on the target, specified by convention + and purpose. A defaultvalueList list argument may be given if + a return code is not desired when the Attribute is not found. + +
+Supported values for <object> are: +
+Supported types for <valueList> and <defaultvalueList> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_AttributeGet() + subroutine ESMF_AttributeGetCount(target, attpack, count, & + attcountflag, attnestflag, rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + type(ESMF_AttPack), intent(inout) :: attpack + integer, intent(inout) :: count + type(ESMF_AttGetCountFlag), intent(in), optional :: attcountflag + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(inout), optional :: rc ++STATUS: + DEPRECATED CLASS! +
+DESCRIPTION:
+
+
+
+Return the Attribute count for target. + +
+Supported values for <object> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_AttributeGet() + subroutine ESMF_AttributeGetCount(target, count, convention, purpose, & + attcountflag, attnestflag, rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + integer, intent(inout) :: count + character (len=*), intent(in), optional :: convention + character (len=*), intent(in), optional :: purpose + type(ESMF_AttGetCountFlag), intent(in), optional :: attcountflag + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(inout), optional :: rc ++STATUS: + The following parameters were removed in ESMF version 8.1.0: + +
+STATUS:
+ DEPRECATED CLASS!
+
+The entire ESMF_Attribute class has been deprecated and is scheduled for removal with ESMF 9.0.0. This includes all of the class derived types, named constants, and methods. Please use the replacment class ESMF_Info, section 40 instead!
+
+
+DESCRIPTION:
+
+
+
+Return the Attribute count for target. + +
+Supported values for <object> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_AttributeGet() + subroutine ESMF_AttributeGetInfoByNamAP(target, name, attpack, & + attnestflag, typekind, itemCount, isPresent, rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + character (len = *), intent(in) :: name + type(ESMF_AttPack), intent(inout) :: attpack + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: itemCount + logical, intent(out), optional :: isPresent + integer, intent(inout), optional :: rc ++STATUS: + DEPRECATED CLASS! +
+DESCRIPTION:
+
+
+
+Return information associated with an Attribute in an Attribute package, + including typekind and itemCount. + +
+Supported values for <object> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_AttributeGet() + subroutine ESMF_AttributeGetInfoByNam(target, name, & + convention, purpose, attnestflag, typekind, itemCount, isPresent, rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + character (len = *), intent(in) :: name + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len=*), intent(in), optional :: convention + character (len=*), intent(in), optional :: purpose + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: itemCount + logical, intent(out), optional :: isPresent + integer, intent(inout), optional :: rc ++STATUS: + The following parameters were removed in ESMF version 8.1.0: + +
+STATUS:
+ DEPRECATED CLASS!
+
+The entire ESMF_Attribute class has been deprecated and is scheduled for removal with ESMF 9.0.0. This includes all of the class derived types, named constants, and methods. Please use the replacment class ESMF_Info, section 40 instead!
+
+
+DESCRIPTION:
+
+
+
+Return information associated with the named Attribute, + including typekind and itemCount. + +
+Supported values for <object> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_AttributeGet() + subroutine ESMF_AttributeGetInfoByNum(target, attributeIndex, & + name, convention, purpose, attnestflag, typekind, itemcount, isPresent, & + rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + integer, intent(in) :: attributeIndex + character (len = *), intent(out) :: name + character (len = *), intent(in), optional :: convention + character (len = *), intent(in), optional :: purpose + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: itemCount + logical, intent(out), optional :: isPresent + integer, intent(inout), optional :: rc ++STATUS: + The following parameters were removed in ESMF version 8.1.0: + +
+STATUS:
+ DEPRECATED CLASS!
+
+The entire ESMF_Attribute class has been deprecated and is scheduled for removal with ESMF 9.0.0. This includes all of the class derived types, named constants, and methods. Please use the replacment class ESMF_Info, section 40 instead!
+
+
+DESCRIPTION:
+
+
+
+Returns information associated with the indexed Attribute, + including name, typekind and itemCount. Keep in + mind that these indices start from 1, as expected in a Fortran API. + +
+Supported values for <object> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using ESMF_AttributeGetAttPack() + subroutine ESMF_AttGetAttPack(target, convention, purpose, & + attpack, attnestflag, isPresent, rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + character (len = *), intent(in) :: convention + character (len = *), intent(in) :: purpose + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + type(ESMF_AttPack), intent(inout), optional :: attpack + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + logical, intent(out), optional :: isPresent + integer, intent(out), optional :: rc ++STATUS: + The following parameters were removed in ESMF version 8.1.0: + +
+STATUS:
+ DEPRECATED CLASS!
+
+The entire ESMF_Attribute class has been deprecated and is scheduled for removal with ESMF 9.0.0. This includes all of the class derived types, named constants, and methods. Please use the replacment class ESMF_Info, section 40 instead!
+
+
+DESCRIPTION:
+
+
+
+Get an ESMF Attribute package object. + +
+Supported values for <object> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AttributeRemove(target, name, & + attpack, attnestflag, rc) +ARGUMENTS: +
type(<object>), intent(inout) :: target + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character (len = *), intent(in), optional :: name + type(ESMF_AttPack), intent(inout), optional :: attpack + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(inout), optional :: rc ++STATUS: + DEPRECATED CLASS! +
+DESCRIPTION:
+
+
+
+Remove an Attribute, or Attribute package on target. + +
+Supported values for <object> are: +
+The arguments are: +
+NOTE: An entire Attribute package can be removed by specifying + attpack only, without name. By specifying + attpack an Attribute will be removed + from the corresponding Attribute package, if it exists. An + Attribute can be removed directly from target by specifying + name, without attpack. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AttributeRemove(target, name, convention, purpose, & + attnestflag, rc) +ARGUMENTS: +
type(<object>), intent(inout) :: target + character (len = *), intent(in), optional :: name + character (len = *), intent(in), optional :: convention + character (len = *), intent(in), optional :: purpose + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(inout), optional :: rc ++STATUS: + The following parameters were removed in ESMF version 8.1.0: + +
+STATUS:
+ DEPRECATED CLASS!
+
+The entire ESMF_Attribute class has been deprecated and is scheduled for removal with ESMF 9.0.0. This includes all of the class derived types, named constants, and methods. Please use the replacment class ESMF_Info, section 40 instead!
+
+
+DESCRIPTION:
+
+
+
+Remove an Attribute, or Attribute package on target. + +
+Supported values for <object> are: +
+The arguments are: +
+NOTE: An entire Attribute package can be removed by specifying + convention, purpose, and attPackInstanceName + only, without name. An + Attribute can be removed directly from <object> by specifying + name, without convention, purpose, and + attPackInstanceName. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AttributeSet(target, name, <value>, attpack, & + itemcount, attnestflag, rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + character (len = *), intent(in) :: name + <value>, see below for supported values + type(ESMF_AttPack), intent(inout) :: attpack + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: itemcount + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(inout), optional :: rc ++STATUS: + DEPRECATED CLASS! +
+DESCRIPTION:
+
+
+
+Attach an Attribute to target, or set an Attribute in an + Attribute package. The Attribute has a name and value, + and, if in an Attribute package, a attpack. + +
+The itemcount and attnestflag are NOOP. The + target is a NOOP if the attpack is used. + +
+Supported values for <object> are: +
+Supported types for <value> and <defaultvalue> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AttributeSet(target, name, <valueList>, attpack, & + itemCount, attnestflag, rc) +ARGUMENTS: +
type(<object>), intent(in) :: target + character (len = *), intent(in) :: name + <valueList>, see below for supported values + type(ESMF_AttPack), intent(inout) :: attpack + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + integer, intent(in), optional :: itemcount + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(inout), optional :: rc ++STATUS: + DEPRECATED CLASS! +
+DESCRIPTION:
+
+
+
+Attach an Attribute to target, or set an Attribute in an + Attribute package. The Attribute has a name and a + valueList, with an itemCount, and, if in an Attribute + package, a attpack. + +
+The itemcount and attnestflag are NOOP. The + target is a NOOP if the attpack is used. + +
+Supported values for <object> are: +
+Supported types for <valueList> and <defaultvalueList> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AttributeSet(target, name, <value>, & + convention, purpose, itemcount, attnestflag, rc) +ARGUMENTS: +
type(<object>), intent(inout) :: target + character (len = *), intent(in) :: name + <value>, see below for supported values + character (len = *), intent(in), optional :: convention + character (len = *), intent(in), optional :: purpose + integer, intent(in), optional :: itemcount + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(inout), optional :: rc ++STATUS: + The following parameters were removed in ESMF version 8.1.0: + +
+STATUS:
+ DEPRECATED CLASS!
+
+The entire ESMF_Attribute class has been deprecated and is scheduled for removal with ESMF 9.0.0. This includes all of the class derived types, named constants, and methods. Please use the replacment class ESMF_Info, section 40 instead!
+
+
+DESCRIPTION:
+
+
+
+Attach an Attribute to target, or set an Attribute in an + Attribute package. The Attribute has a name and value, + and, if in an Attribute package, convention and purpose. + +
+The itemcount and attnestflag are NOOP. + +
+Supported values for <object> are: +
+Supported types for <value> and <defaultvalue> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AttributeSet(target, name, <valueList>, & + convention, purpose, itemCount, attnestflag, rc) +ARGUMENTS: +
type(<object>), intent(inout) :: target + character (len = *), intent(in) :: name + <valueList>, see below for supported values + character (len = *), intent(in), optional :: convention + character (len = *), intent(in), optional :: purpose + integer, intent(in), optional :: itemcount + type(ESMF_AttNest_Flag), intent(in), optional :: attnestflag + integer, intent(inout), optional :: rc ++STATUS: + The following parameters were removed in ESMF version 8.1.0: + +
+STATUS:
+ DEPRECATED CLASS!
+
+The entire ESMF_Attribute class has been deprecated and is scheduled for removal with ESMF 9.0.0. This includes all of the class derived types, named constants, and methods. Please use the replacment class ESMF_Info, section 40 instead!
+
+
+DESCRIPTION:
+
+
+
+Attach an Attribute to target, or set an Attribute in an + Attribute package. The Attribute has a name and a + valueList, with an itemCount, and, if in an Attribute + package, convention and purpose. + +
+The itemcount and attnestflag are NOOP. + +
+Supported values for <object> are: +
+Supported types for <valueList> and <defaultvalueList> are: +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine ESMF_AttributeUpdate(target, vm, rootList, rc) +ARGUMENTS: +
<target>, see below for supported values + type(ESMF_VM), intent(in) :: vm + integer, intent(in) :: rootList(:) + integer, intent(out), optional :: rc ++STATUS: + The following parameters were removed in ESMF version 8.1.0: + +
+STATUS:
+ DEPRECATED CLASS!
+
+The entire ESMF_Attribute class has been deprecated and is scheduled for removal with ESMF 9.0.0. This includes all of the class derived types, named constants, and methods. Please use the replacment class ESMF_Info, section 40 instead!
+
+
+DESCRIPTION:
+
+
+
+Update an Attribute hierarchy during runtime. The information from + the PETs in the rootList is transferred to the PETs that are not + in the rootList. Care should be taken to ensure that the + information contained in the Attributes on the PETs in the rootList + is consistent. + +
+Supported values for <object> are: +
+The arguments are: +
+ + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_refdoc/prev.png b/docs/nightly/fix/reconcile-info/ESMF_refdoc/prev.png new file mode 100644 index 000000000..e60b8b407 Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMF_refdoc/prev.png differ diff --git a/docs/nightly/fix/reconcile-info/ESMF_refdoc/prev_g.png b/docs/nightly/fix/reconcile-info/ESMF_refdoc/prev_g.png new file mode 100644 index 000000000..ac6f0bceb Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMF_refdoc/prev_g.png differ diff --git a/docs/nightly/fix/reconcile-info/ESMF_refdoc/up.png b/docs/nightly/fix/reconcile-info/ESMF_refdoc/up.png new file mode 100644 index 000000000..3937e168f Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMF_refdoc/up.png differ diff --git a/docs/nightly/fix/reconcile-info/ESMF_refdoc/up_g.png b/docs/nightly/fix/reconcile-info/ESMF_refdoc/up_g.png new file mode 100644 index 000000000..fb36cf765 Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMF_refdoc/up_g.png differ diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc.pdf b/docs/nightly/fix/reconcile-info/ESMF_usrdoc.pdf new file mode 100644 index 000000000..f3744e3ec Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMF_usrdoc.pdf differ diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/ESMF_usrdoc.css b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/ESMF_usrdoc.css new file mode 100644 index 000000000..f49016949 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/ESMF_usrdoc.css @@ -0,0 +1,40 @@ +/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ +.MATH { font-family: "Century Schoolbook", serif; } +.MATH I { font-family: "Century Schoolbook", serif; font-style: italic } +.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold } + +/* implement both fixed-size and relative sizes */ +SMALL.XTINY { font-size : xx-small } +SMALL.TINY { font-size : x-small } +SMALL.SCRIPTSIZE { font-size : smaller } +SMALL.FOOTNOTESIZE { font-size : small } +SMALL.SMALL { } +BIG.LARGE { } +BIG.XLARGE { font-size : large } +BIG.XXLARGE { font-size : x-large } +BIG.HUGE { font-size : larger } +BIG.XHUGE { font-size : xx-large } + +/* heading styles */ +H1 { } +H2 { } +H3 { } +H4 { } +H5 { } + +/* mathematics styles */ +DIV.displaymath { } /* math displays */ +TD.eqno { } /* equation-number cells */ + + +/* document-specific styles come next */ +DIV.LaTeX { } +SPAN.bf { } +SPAN.bfseries { } +DIV.center { } +SPAN.it { } +DIV.logo-LaTeX { } +DIV.navigation { } +PRE.preform { } +SPAN.arabic { } +SPAN.textit { font-style: italic } diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/ESMF_usrdoc.html b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/ESMF_usrdoc.html new file mode 100644 index 000000000..26b372006 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/ESMF_usrdoc.html @@ -0,0 +1,405 @@ + + + + + ++ +
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The ESMF software is based on the contributions of a broad community. +Below are the software packages that are included in ESMF or strongly +influenced our design. We'd like to express our gratitude to the +developers of these codes for access to their software as well as their +ideas and advice. + +
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The ESMF software is based on the contributions of a broad community. +Below are the software packages that are included in ESMF or strongly +influenced our design. We'd like to express our gratitude to the +developers of these codes for access to their software as well as their +ideas and advice. + +
+ +
+
+
+
+
+
+
+
+
+
+
+This section goes into more detail about how to build and install the ESMF +software. + +
+ +
+Major releases of the ESMF software can be downloaded by following +the instructions on the the Download link on the ESMF +website, http://www.earthsystemmodeling.org. + +
+The ESMF is distributed as a full source code tree. +Follow the instructions in the following sections +to build the library and link it with your application. + +
+ +
+Users aware of these risks may check out development snapshots +using the appropriate git tag. + +
+Starting with ESMF 8.3.0 beta snapshot 07, the naming convention for development tags has the form: + +
+
+v<VERSION>b<NUMBER> ++ +
+For example: +
+v8.3.0b07 ++ +
+Prior to this version, the tag naming convention for development tags is: + +
+
+ESMF_<VERSION>_beta_snapshot_<NUMBER> ++ +
+For example: +
+ESMF_8_2_0_beta_snapshot_23 ++ +
+Use the following example command as a guide to check out a specific development tag: + +
+
+ git clone https://github.com/esmf-org/esmf.git --branch v8.3.0b13 --depth 1 ++ +
+Once downloaded, development snapshots are built in the same way as releases. + +
+ +
+ +
+The following compilers and utilities are required for compiling, linking and +testing the ESMF software. It is good common practice to use a consistent set +of Fortran/C++/C compilers from the same vendor, e.g. GNU, Intel, etc. +However, some vendor combinations of Fortran, C++, and C compilers, +e.g. Intel ifort with GNU g++, are also supported. + +
+Internal packages that can optionally reference external libraries: + +
+Optional external packages that must be specified for certain functions: + +
+ESMF can be built using a single-processor MPI-bypass library +that comes with ESMF by setting ESMF_COMM=mpiuni. This allows ESMF applications +to be linked and run in single-process mode. + +
+In order to build html and pdf versions of the ESMF documentation, +LATEX, +the latex2html +conversion utility, and the Unix/Linux dvipdf utility must be installed. +The csh shell is also required to complete the documentation build. + +
+ +
+ESMF supports the Intel compiler suite via ESMF_COMPILER=intel. Starting in 2020, Intel began promoting their +new LLVM-based C/C++ and Fortran compiler line under the oneAPI brand. As of 2023, the older compilers are still +part of the Intel compiler suite and referred to as Intel Compiler Classic. ESMF supports both the classic and oneAPI +compiler lines. The following paragraphs provide important details that allow users to fine-tune the interaction +with the Intel compilers. + +
+Under ESMF_OS=Linux, with ESMF_COMPILER=intel and ESMF_COMM=mpiuni set, the C, C++, and +Fortran compiler front-ends default to the classic options icc, icpc, and ifort, respectively. Any +of these defaults can be overridden by explicitly setting the ESMF_C, ESMF_CXX, or ESMF_F90 +environment variables to the oneAPI options icx, icpx, and ifx, respectively. + +
+Under ESMF_OS=Linux, with ESMF_COMPILER=intel and ESMF_COMM=intelmpi set, the C, C++, and +Fortran compiler front-ends default to the MPI compiler wrappers mpiicc, mpicpc, and mpiifort, +respectively. It depends on the IntelMPI installation details whether classic, oneAPI, or a mixture of compilers +are used underneath the MPI wrappers. The IntelMPI defaults can be overridden by explicitly setting the +I_MPI_CC, I_MPI_CXX, or I_MPI_F90 environment variables. This is an IntelMPI feature. + +
+The recommendation for Cray systems that use the Cray compiler wrappers cc, CC, and ftn, +respectively, is to use ESMF_OS=Unicos. In most cases this setting is detected automatically by the ESMF +build system, and should not be overridden. + +
+Under ESMF_OS=Unicos, with ESMF_COMPILER=intel, the C, C++, and Fortran compiler front-ends default to +cc, CC, and ftn, respectively, regardless of the ESMF_COMM setting. The appropriate +classic, oneAPI, or mixed compiler combination is typically determined by the Intel environment module loaded. +Common module names on Cray systems are intel-classic, intel-oneAPI, and intel, respectively. + +
+Tip: Use the ESMF "make info" target to query compiler version information. This can be used to determine the +appropriate settings, and to diagnose issues before kicking off the complete ESMF build procedure. + +
+ +
+ESMF supports MacOS systems via the ESMF_OS=Darwin setting, which +typically is auto-detected by the ESMF build system. Various compilers and +MPI implementations are supported under Darwin using the ESMF_COMPILER +and ESMF_COMM environment variables. There are some combinations under +Darwin that require special attention; these combinations are listed below. + +
+On Darwin with ESMF_COMPILER=gfortran and ESMF_COMM=mpich, +using MPICH3 built from source, it is important to specify the +-enable-two-level-namespace configure option when building the MPICH3 +library. By default, i.e. without this option, the produced MPICH compiler +wrappers include a linker flag (-flat_namespace) that causes issues with +C++ exception handling under GNU g++. Building and linking ESMF applications +with MPICH compiler wrappers that specify this linker option leads to +"mysterious" application aborts during execution. + +
+On Darwin with ESMF_COMPILER=intel, command line arguments cannot be +accessed from ESMF applications when linked against the shared library version +(libesmf.dylib). There is no issue when linked against the static +version (libesmf.a). Setting the environment variable +ESMF_SHARED_LIB_BUILD=OFF when building ESMF can be used as a +work around for this issue. + +
+ +
+Some portions of the ESMF library can offer enhanced capabilities when +certain third party libraries are available. This section describes +these dependencies and the associated environment settings +that allow the user to control them. + +
+On many platforms, the ESMF library is also created as a shared library. +When third party libraries are called from ESMF, it is recommended that they are +also available as shared libraries. In cases where they are not, they should at +least be compiled with the position independent code option enabled (e.g., -fPIC on +Linux with gfortran/gcc) where necessary, so that the ESMF shared library +build can successfully incorporate them. + +
+ +
+The following environment variables control whether a minimal set of +LAPACK code that comes with ESMF is used, or whether ESMF should link against +an externally available LAPACK installation. Alternatively, ESMF's +LAPACK-dependent features can be turned off altogether. + +
+
+
+
+
+
+
+
+
+
+
+Specifies the path where the LAPACK library is located. + +
+
+Specifies the linker directive needed to link the LAPACK library to +the application. On some systems, the BLAS library must also be included. +
+ +
+Beginning with NetCDF 4.2, the C and Fortran API libraries are released as separate packages. +To compile ESMF with NetCDF 4.2 and newer releases, the ESMF_NETCDF environment variable +can be set to "split". The "split" option requires the NetCDF C library, +and the NetCDF Fortran API library be installed in the same directory. As an alternative, +the "nc-config" option may be used to automatically determine the include and lib directory +locations. The "nc-config" option supports separate C and Fortran directories. + +
+The following environment variables enable, and specify the name and location +of the desired NetCDF library and associated header files: + +
+
+
+
+
+
+
+
+Specifies the path where the NetCDF header files are located. + +
+
+Specifies the path where the NetCDF library file is located. + +
+
+Specifies the linker directives needed to link the NetCDF library to +the application. + +
+The default value depends on the setting of ESMF_NETCDF. For the +typical case where ESMF_NETCDF is set to "standard", +ESMF_NETCDF_LIBS is set to "-lnetcdf". +When ESMF_NETCDF is set to "split", ESMF_NETCDF_LIBS +is set to "-lnetcdff -lnetcdf". + +
+If the hdf5 library is required, append "-lhdf5_hl -lhdf5" to the +desired setting. E.g. "-lnetcdff -lnetcdf -lhdf5_hl -lhdf5" +
+ +
+Some file systems, for example Lustre, may need +to have locking attributes enabled when the file system is mounted. + +
+The following environment variables enable and specify the name and +location of the desired Parallel-NetCDF library and associated header files: + +
+
+When defined, enables the use of Parallel-NetCDF. + +
+
+
+
+
+
+Specifies the path where the Parallel-NetCDF header files are located. + +
+
+Specifies the path where the Parallel-NetCDF library file is located. + +
+
+Specifies the linker directives needed to link the Parallel-NetCDF library to the +application. +
+ +
+The PIO code depends on MPI I/O support by the underlying MPI +implementation for parallel I/O. Almost all current MPI +implementations support MPI I/O to the required degree. For NetCDF format +support the integrated PIO code depends on ESMF_NETCDF (see 9.4.2) +being enabled and optionally ESMF_PNETCDF (see 9.4.3) +being enabled. + +
+
+
+
+
+
+
+
+Specifies the path where the PIO header files are located. + +
+
+Specifies the path where the PIO library is located. + +
+
+ +
+The following environment variables enable, and specify the name and location +of the desired accelerator software stacks and associated header files: + +
+
+
+
+
+
+
+
+
+Specifies the path where the header files for the accelerator software +stack is located. If not set, this environment variable is ignored. + +
+
+Specifies the path where the libraries for the accelerator software +stack is located. If not set, this environment variable is ignored. + +
+
+Specifies the linker directives required to link the library with +the accelerator software stack. If not set, this environment variable +is ignored. + +
+
+ +
+
+
+
+
+
+Specifies the path where the XERCES C++ header files are located. + +
+
+Specifies the path where the XERCES C++ library file is located. + +
+
+Specifies the linker directives needed to link the XERCES C++ library to +the application. + +
+The default value depends on the setting of ESMF_XERCES. For the +typical case where ESMF_XERCES is set to "standard", +ESMF_XERCES_LIBS is set to "-lxerces-c". +
+ +
+ESMF includes the option to build the yaml-cpp from sources kept inside the +ESMF source tree, or to link against an external build of the yaml-cpp library. +The following environment variables control the details of how ESMF interacts +with yaml-cpp: + +
+
+
+
+
+
+
+Specifies the path where the yaml-cpp C++ header files are located. + +
+
+Specifies the path where the yaml-cpp C++ library file is located. + +
+
+Specifies the linker directives needed to link the yaml-cpp C++ library to +the application. + +
+The default value depends on the setting of ESMF_YAMLCPP. For the +typical case where ESMF_YAMLCPP is set to "standard", +ESMF_YAMLCPP_LIBS is set to "-lyaml-cpp". +
+ +
+The Mesh Oriented datABase +(MOAB) +can be used to build an ESMF unstructured Mesh as an alternative to the +"native" ESMF Mesh implementation. The decision to use either MOAB or the +native ESMF Mesh implementation is made at run time. This aspect is described +in the Reference Manual, section ESMF_MeshSetMOAB() .The default is to use +the native ESMF Mesh. ESMF will build an internal version of MOAB by default, +but an external MOAB installation can be used if desired. The build parameters +covered in this section are used to determine which version of MOAB is +available to ESMF. + +
+
+
+
+
+
+Specifies the path where the MOAB C++ header files are located. + +
+
+Specifies the path where the MOAB C++ library file is located. + +
+
+Specifies the linker directives needed to link the MOAB C++ library to +the application. + +
+
+ +
+The LibNUMA API for Non Uniform Memory Access +(NUMA) +can be used to discover the NUMA architecture at run-time. + +
+
+
+
+
+Specifies the path where the NUMA header files are located. + +
+
+Specifies the path where the NUMA library file is located. + +
+
+Specifies the linker directives needed to link the NUMA library to +the application. + +
+
+ +
+The NVIDIA Management Library +(NVML) +can be used to discover NVIDIA GPUs that are accessible at run-time. + +
+
+
+
+
+Specifies the path where the NVML header files are located. + +
+
+Specifies the path where the NVML library file is located. + +
+
+Specifies the linker directives needed to link the NVML library to +the application. + +
+
+ +
+The following is a full alphabetical list of all environment variables which +are used by the ESMF build system. The ESMF_DIR must be set in all +circumstances, while most other environment variables have defaults. However, +it is recommended to explicitly set the compiler and MPI flavor using +ESMF_COMPILER and ESMF_COMM, respectively, to ensure the expected +behavior. + +
+
+If a system supports 32-bit and 64-bit (pointer wordsize) application binary +interfaces (ABIs), this variable can be set to select which ABI to use. Valid +values are 32 or 64. By default the most common ABI is chosen. On +x86_64 architectures three additional, more specific ABI settings are available, +x86_64_32, x86_64_small and x86_64_medium. + +
+
+Not normally set by user. ESMF auto-generates subroutine interfaces for a wide +variety of data arrays of different ranks, shapes, and types. Setting this +variable to TRUE instructs ESMF to not generating interfaces for +5D, 6D, and 7D arrays. This shrinks the amount of autogenerated code as well +as the number of overloaded interfaces. + +
+
+This environment variable controls the build option. To make a debuggable +version of the library set ESMF_BOPT to g before building. The +default is O (capital oh) which builds an optimized version of the +library. If ESMF_BOPT is O, ESMF_OPTLEVEL can also be set +to a numeric value between 0 and 4 to select a specific optimization level. + +
+
+This variable can be used to override the default C compiler and linker +front-end executables. The executable may be specified with absolute path +overriding the location determined by default from the user's PATH variable. + +
+
+On systems with a vendor-supplied MPI communications library, the vendor library +is chosen by default for communications. On these systems ESMF_COMM is +set to mpi, signaling to the ESMF build system to use the vendor MPI +implementation. +For other systems (e.g. Linux or Darwin) where a multitude of MPI +implementations are available, ESMF_COMM must be set to indicate which +implementation is used to build the ESMF library. Set ESMF_COMM according +to your situation to: mpt, mpich, mpich1, mpich2, mpich3, mvapich2, lam, openmpi +or intelmpi. ESMF_COMM may also be set to user indicating +that the user will set all the required flags using advanced ESMF environment +variables. Some individual MPI builds may create additional libraries that +need to be linked in, such as the legacy C++ bindings. These may be specified +via the ESMF_CXXLINKLIBS and ESMF_F90LINKLIBS environment +variables. + +
+Alternatively, ESMF comes with a single-processor MPI-bypass library which is +the default for Linux and Darwin systems. To force the use of this bypass +library set ESMF_COMM equal to mpiuni. + +
+
+The ESMF library build requires a working Fortran90 and C++ compiler. On +platforms that don't come with a single vendor supplied compiler suite +(e.g. Linux or Darwin) it is recommended to explicitly set ESMF_COMPILER +to the desired compiler flavor. Notice that setting +the ESMF_COMPILER variable does not affect how the compiler +executables are located on the system. ESMF_COMPILER (together with +ESMF_COMM) affect the name that is expected for the compiler executables. +Furthermore, the ESMF_COMPILER setting is used to select compiler and +linker flags consistent with the compilers indicated. + +
+By default Fortran and C++ compiler executables are expected to be located in +a location contained in the user's PATH environment variable. This means +that if you cannot locate the correct compiler executable via the which +command on the shell prompt the ESMF build system won't find it either! + +
+There are advanced ESMF environment variables that can be used to select +specific compiler executables by specifying the full path. This can be used to +pick specific compiler executables without having to modify the PATH +environment variable. + +
+Use 'make info' to see which compiler executables the ESMF build system will +be using according to your environment variable settings. + +
+To see possible values for ESMF_COMPILER, cd to +$ESMF_DIR/build_config and list the directories there. The first part +of each directory name corresponds to the output of 'uname -s' for this +platform. The second part contains possible values for ESMF_COMPILER. In +some cases multiple combinations of Fortran and C++ compilers are possible, e.g. +there is intel and intelgcc available for Linux. Setting +ESMF_COMPILER to intel indicates that both Intel Fortran and +C++ compilers are used, whereas intelgcc indicates that the Intel Fortran +compiler is used in combination with GCC's C++ compiler. + +
+If you do not find a configuration that matches your situation you will need to +port ESMF. + +
+
+This variable can be used to override the default C++ compiler and linker +front-end executables. The executable may be specified with absolute path +overriding the location determined by default from the user's PATH variable. + +
+
+Prepend compiler flags to the list of flags the ESMF build system determines. + +
+
+Prepend compiler search paths to the list of search paths the ESMF build system +determines. + +
+
+This variable can be used to override the default C++ compiler +front-end executables. The executable may be specified with absolute path +overriding the location determined by default from the user's PATH variable. + +
+
+This variable can be used to override the default C++ linker +front-end executables. The executable may be specified with absolute path +overriding the location determined by default from the user's PATH variable. + +
+
+Prepend libraries to the list of libraries the ESMF build system determines. + +
+
+Prepend linker flags to the list of flags the ESMF build system determines. + +
+
+Prepend linker search paths to the list of search paths the ESMF build system +determines. + +
+
+Prepend linker rpaths to the list of rpaths the ESMF build system determines. + +
+
+This variable can be used to override the default C++ optimization flag. + +
+
+Used to set the C++ language standard. If unset or default, the ESMF default C++ language standard is used: C++11. +If set to an integer, the integer is used to indicate the respective C++ language standard to the compiler. ESMF does not check whether the integer corresponds to an existing language standard. +Setting sysdefault results in usage of the compiler specific default C++ language standard. This can lead to build issue if the compiler default is below the level required by ESMF. + +
+
+This variable can be used to override the deferring of the build of the +ESMF library. By default, the library is built after all of the source +files have been compiled. This speeds up the build process. It also +allows parallel compilation of source code when the -j flag is used with +make. Setting this environment variable to OFF forces the library to +be updated after each individual compilation, thus disabling the ability +to use parallel compilation. + +
+
+The environment variable ESMF_DIR must be set to the full pathname +of the top level ESMF directory before building the framework. This is the +only environment variable which is required to be set on all platforms under +all conditions. + +
+
+This variable can be used to override the default Fortran90 compiler and linker +front-end executables. The executable may be specified with absolute path +overriding the location determined by default from the user's PATH variable. + +
+
+Prepend compiler flags to the list of flags the ESMF build system determines. + +
+
+Prepend compiler search paths to the list of search paths the ESMF build system +determines. + +
+
+This variable can be used to override the default Fortran90 compiler +front-end executables. The executable may be specified with absolute path +overriding the location determined by default from the user's PATH variable. + +
+
+This variable can be used to override the default flag (-I) used to specify a +Fortran module directory. + +
+
+This variable can be used to override the default Fortran90 linker +front-end executables. The executable may be specified with absolute path +overriding the location determined by default from the user's PATH variable. + +
+
+Prepend libraries to the list of libraries the ESMF build system determines. + +
+
+Prepend linker flags to the list of flags the ESMF build system determines. + +
+
+Prepend linker search paths to the list of search paths the ESMF build system +determines. + +
+
+Prepend linker rpaths to the list of rpaths the ESMF build system determines. + +
+
+This variable can be used to override the default Fortran90 optimization flag. + +
+
+Location into which to install the ESMF apps during installation. This +location can be specified as absolute path (starting with "/") or relative to +ESMF_INSTALL_PREFIX. + +
+
+Location into which to install the documentation during installation. This +location can be specified as absolute path (starting with "/") or relative to +ESMF_INSTALL_PREFIX. + +
+
+Location into which to install the header files during installation. This +location can be specified as absolute path (starting with "/") or relative to +ESMF_INSTALL_PREFIX. + +
+
+Location into which to install the library files during installation. This +location can be specified as absolute path (starting with "/") or relative to +ESMF_INSTALL_PREFIX. + +
+
+Location into which to install the F90 module files during installation. This +location can be specified as absolute path (starting with "/") or relative to +ESMF_INSTALL_PREFIX. + +
+
+Location into which to install the CMake module files during installation. This +location can be specified as absolute path (starting with "/") or relative to +ESMF_INSTALL_PREFIX. + +
+
+This variable specifies the prefix of the installation path used during the +installation process accessible thought the install target. Libraries, F90 +module files, header files and documentation all are installed relative to +ESMF_INSTALL_PREFIX by default. The ESMF_INSTALL_PREFIX may be +provided as absolute path (starting with "/") or relative to ESMF_DIR. + +
+
+
+
+
+Not normally set by user. This variable indicates architectural details about +the machine on which the ESMF library is being built. The value of this +variable will affect which ABI settings are available and what they mean. +ESMF_MACHINE is set automatically. + +
+
+Variable used to pass system-specific queue options to the batch system. +Typically the queue, project and limits are set. +See section 11.1.1 for a discussion of this option. + +
+
+Variable used to pass system-specific options to the MPI launch facility. +See section 11.1.1 for a discussion of this option. + +
+
+This variable can be used to override the default utility used to launch +parallel execution of ESMF test applications in MPMD mode. The executable in +ESMF_MPIMPMDRUN may be specified with path. + +
+
+This variable can be used to override the default utility used to launch +parallel ESMF test or example applications. The executable in ESMF_MPIRUN +may be specified with path. +See section 11.1.1 for a discussion of this option. + +
+
+Variable used to pass system-specific options to the first level MPI script +accessed by ESMF. +See section 11.1.1 for a discussion of this option. + +
+
+
+
+
+
+Not normally set by user. Setting this variable to FALSE instructs +ESMF to generating data array interfaces for data types of 1-byte integers. + +
+
+Not normally set by user. Setting this variable to FALSE instructs +ESMF to generating data array interfaces for data types of 2-byte integers. + +
+
+Compiles and links the ESMF library with OpenACC compiler flags. + +
+
+Compiles and links the ESMF library with OpenMP compiler flags. +Both OMP4 and ON enable the ESMF OpenMP features. Only with +OMP4 will those features assume OpenMP 4.0 and higher. + +
+
+See ESMF_BOPT for details. + +
+
+Not normally set by user unless cross-compiling. This variable indicates the +target system for which the ESMF library is being built. Under normal +circumstances, i.e. ESMF is being build on the target system, ESMF_OS is +set automatically. However, when cross-compiling for a different target system +ESMF_OS must be set to the respective target OS. For example, when +compiling for the Cray X1 on an interactive X1 node ESMF_OS will be set +automatically. However, when ESMF is being cross-compiled for the X1 on a Linux +host the user must set ESMF_OS to Unicos manually in order to +indicate the intended target platform. + +
+
+
+
+
+
+This compile-time option controls ESMF's dependency on a functioning +Pthreads library. The default option is set to ON with the exception +of IRIX64 and platforms that don't provide Pthreads. On IRIX64 the use of +Pthreads in ESMF is disabled by default because the Pthreads library conflicts +with the use of OpenMP on this platform. + +
+The user can override the default setting of ESMF_PTHREADS on all +platforms that provide Pthread support. Setting the ESMF_PTHREADS +environment variable to OFF will disable ESMF's Pthreads feature set. +On platforms that don't support Pthreads, e.g. IBM BlueGene/L or Cray XT3, the +default OFF setting cannot be overridden! + +
+
+Build configure file site name or the value default. If not set, then the value +of default is assumed. When including platform-specific files, this value is +used as the third part of the directory name (parts 1 and 2 are the +ESMF_OS value and ESMF_COMPILER value, respectively.) + +
+
+Variable specifying whether the ESMFMKFILE variable is evaluated to +determine which ESMF installation is being tested against. If set to the +value ON, all tests and examples are build against the ESMF installation +referenced by the ESMFMKFILE variable. For OFF, the +ESMFMKFILE variable is ignored and the tests and examples are build +against the ESMF under ESMF_DIR. This is the default. + +
+
+Variable specifying how to compile the unit tests. If set to the value ON, +then all unit tests will be compiled and will be executed when the test is +run. If unset or set to any other value, only a subset of the unit tests +will be included to verify basic functions. Note that this is a compile-time +selection, not a run-time option. + +
+
+The ON setting enforces usage of OpenACC compiler flags when building ESMF test applications. This allows testing of user-level OpenACC usage even with ESMF_OPENACC set to OFF. + +
+
+The ON setting enforces usage of OpenMP compiler flags when building ESMF test applications. This allows testing of user-level OpenMP usage even with ESMF_OPENMP set to OFF. + +
+
+Variable specifying the test harness makefile target for the array class. If this variable is not specified, a default test scenario will be run for the array class. See the ESMF Software Developer's Guide for instructions for selecting other test harness scenarios. + +
+
+Variable specifying the test harness makefile target for the field class. If this variable is not specified, a default test scenario will be run for the field class. See the ESMF Software Developer's Guide for instructions for selecting other test harness scenarios. + +
+
+Variable specifying whether to run MPMD-style tests, i.e. test applications +that start up as multiple separate executables. + +
+
+Variable specifying whether to run shared object tests. This requires that the compute environment supports shared objects, and that the ESMF library is available in form of a shared library. + +
+
+If this environment variable is set to ON before the ESMF system +tests are build they will activate ESMF threading in their code. Specifically +each component will be executed using ESMF single threading instead of the +default non-threaded mode. The difference between non-threaded and ESMF +single threaded execution should be completely transparent. Notice that the +setting of ESMF_TESTWITHTHREADS does not alter ESMF's dependency +on Pthreads but tests ESMF threading features during the system tests. An +ESMF library that was compiled with disabled Pthread features (via the ESMF_PTHREADS variable) will produce ESMF error messages during system test +execution if the system tests were compiled with ESMF_TESTWITHTHREADS +set to ON. + +
+
+This variables determines whether extra libraries are built that are used +to add additional symbols to the ESMF tracing and profiling capability, +such as MPI communication functions. +If set to ON the libraries are built and placed into the +ESMF_INSTALL_LIBDIR alongside the ESMF library itself. + +
+
+
+
+
+
+
+
+
+
+Environment variables must be set in the user's shell or when calling make. It +is not necessary to edit ESMF makefiles or other build system files to set +these variables. Here is an example of setting an environment variable in the +csh/tcsh shell: + +
+
+ setenv ESMF_ABI 32 ++ +
+In bash/ksh shell environment variables are set this way: + +
+
+ export ESMF_ABI=32 ++ +
+Environment variables can also be set from the make command line: + +
+
+ make ESMF_ABI=32 ++ +
+ +
+The platforms that are tested and supported depend on the release +of ESMF. To see the specific list of supported platforms, +click the Supported Platforms link under one of the releases +on the ESMF releases page. + +
+All possible combinations of ESMF_OS, ESMF_COMPILER, ESMF_COMM, +and ESMF_ABI build environment variables are listed in the following table. +Where multiple options exist, the default value is indicated in bold. +An entry of default in the COMPILER column indicates the vendor compiler. +An entry of mpi in the COMM column indicates the vendor MPI implementation. + +
+
ESMF_OS | +ESMF_COMPILER | +ESMF_COMM | +ESMF_ABI | ++ |
AIX | +default | +mpiuni,mpi,user | +32, 64 | ++ |
Cygwin | +g95 | +mpiuni,mpich,mpich1,mpich2,mpich3,lam,openmpi,user | +32, 64 | ++ |
Cygwin | +gfortran | +mpiuni,mpich,mpich1,mpich2,mpich3,lam,msmpi,openmpi,user | +32, 64 | ++ |
Darwin | +absoft | +mpiuni,mpich,mpich1,mpich2,mpich3,mvapich2,lam,openmpi,user | +32, 64 | ++ |
Darwin | +g95 | +mpiuni,mpich,mpich1,mpich2,mpich3,mvapich2,lam,openmpi,user | +32, 64 | ++ |
Darwin | +gfortran | +mpiuni,mpich,mpich1,mpich2,mpich3,mvapich2,lam,openmpi,user | +32, 64 | ++ |
Darwin | +gfortranclang | +mpiuni,mpich,mpich1,mpich2,mpich3,mvapich2,lam,openmpi,user | +32, 64 | ++ |
Darwin | +intel | +mpiuni,mpich,mpich1,mpich2,mpich3,mvapich2,intelmpi,lam, | +32, 64 | ++ |
+ | + | openmpi,user | ++ | + |
Darwin | +intelclang | +mpiuni,mpich,mpich1,mpich2,mpich3,intelmpi,lam,openmpi,user | +32, 64 | ++ |
Darwin | +intelgcc | +mpiuni,mpich,mpich1,mpich2,mpich3,intelmpi,lam,openmpi,user | +32, 64 | ++ |
Darwin | +nag | +mpiuni,mpich,mpich1,mpich2,mpich3,mvapich2,lam,openmpi,user | +32, 64 | ++ |
Darwin | +pgi | +mpiuni,mpich,mpich1,mpich2,mpich3,mvapich,mvapich2,lam, | +32, 64 | ++ |
+ | + | openmpi,user | ++ | + |
Darwin | +xlf | +mpiuni,mpi,mpich,mpich1,mpich2,mpich3,lam,openmpi,user | +32 | ++ |
Darwin | +xlfgcc | +mpiuni,mpi,mpich,mpich1,mpich2,mpich3,lam,openmpi,user | +32 | ++ |
IRIX64 | +default | +mpiuni,mpi,user | +32, 64 | ++ |
Linux | +absoft | +mpiuni,mpich,mpich1,mpich2,mpich3,mvapich2,lam,openmpi,user | +32, 64 | ++ |
Linux | +absoftintel | +mpiuni,mpich,mpich1,mpich2,mpich3,lam,openmpi,user | +32, 64 | ++ |
Linux | +aocc | +mpiuni,mpi,mpt,mpich,mpich1,mpich2,mpich3,mvapich2, | +32, 64, | ++ |
+ | + | intelmpi,lam,openmpi,user | +ia64_64, | ++ |
+ | + | + | x86_64_32, | ++ |
+ | + | + | x86_64_small, | ++ |
+ | + | + | x86_64_medium | ++ |
Linux | +arm | +mpiuni,mpi,mpt,mpich,mpich1,mpich2,mpich3,mvapich2, | +32, 64, | ++ |
+ | + | intelmpi,lam,openmpi,user | +ia64_64, | ++ |
+ | + | + | x86_64_32, | ++ |
+ | + | + | x86_64_small, | ++ |
+ | + | + | x86_64_medium | ++ |
Linux | +fujitsu | +mpiuni,mpi,user | +64 | ++ |
Linux | +g95 | +mpiuni,mpich,mpich1,mpich2,mpich3,mvapich2,lam,openmpi,user | +32, 64, | ++ |
+ | + | + | ia64_64, | ++ |
+ | + | + | x86_64_32, | ++ |
+ | + | + | x86_64_small, | ++ |
+ | + | + | x86_64_medium | ++ |
Linux | +gfortran | +mpiuni,mpi,mpt,mpich,mpich1,mpich2,mpich3,mvapich2, | +32, 64, | ++ |
+ | + | intelmpi,lam,openmpi,user | +ia64_64, | ++ |
+ | + | + | x86_64_32, | ++ |
+ | + | + | x86_64_small, | ++ |
+ | + | + | x86_64_medium | ++ |
Linux | +gfortranclang | +mpiuni,mpi,mpt,mpich,mpich1,mpich2,mpich3,mvapich2, | +32, 64, | ++ |
+ | + | lam,openmpi,user | +ia64_64, | ++ |
+ | + | + | x86_64_32, | ++ |
+ | + | + | x86_64_small, | ++ |
+ | + | + | x86_64_medium | ++ |
Linux | +intel | +mpiuni,mpi,mpt,mpich,mpich1,mpich2,mpich3,mvapich2, | +32, 64, | ++ |
+ | + | intelmpi,scalimpi,lam,openmpi,user | +ia64_64, | ++ |
+ | + | + | x86_64_32, | ++ |
+ | + | + | x86_64_small, | ++ |
+ | + | + | x86_64_medium, | ++ |
+ | + | + | mic | ++ |
Linux | +intelgcc | +mpiuni,mpi,mpt,mpich,mpich1,mpich2,mpich3,mvapich2, | +32, 64, | ++ |
+ | + | intelmpi,lam,openmpi,user | +ia64_64, | ++ |
+ | + | + | x86_64_32, | ++ |
+ | + | + | x86_64_small, | ++ |
+ | + | + | x86_64_medium | ++ |
Linux | +lahey | +mpiuni,mpich,mpich1,mpich2,mpich3,mvapich2,lam, | +32, 64 | ++ |
+ | + | openmpi,user | ++ | + |
Linux | +llvm | +mpiuni,mpi,mpt,mpich,mpich1,mpich2,mpich3,mvapich2, | +32, 64, | ++ |
+ | + | intelmpi,lam,openmpi,user | +ia64_64, | ++ |
+ | + | + | x86_64_32, | ++ |
+ | + | + | x86_64_small, | ++ |
+ | + | + | x86_64_medium | ++ |
Linux | +nag | +mpiuni,mpich,mpich1,mpich2,mpich3,mvapich2,lam, | +32, 64 | ++ |
+ | + | openmpi,user | ++ | + |
Linux | +nagintel | +mpiuni,mpich,mpich1,mpich2,mpich3,lam,openmpi,user | +32, 64 | ++ |
Linux | +nvhpc | +mpiuni,mpi,mpt,mpich,mpich1,mpich2,mpich3,mvapich,mvapich2 | +32, 64, | ++ |
+ | + | intelmpi,openmpi,user | +x86_64_32, | ++ |
+ | + | + | x86_64_small, | ++ |
+ | + | + | x86_64_medium | ++ |
Linux | +pathscale | +mpiuni,mpich,mpich1,mpich2,mpich3,lam,openmpi,user | +32, 64, | ++ |
+ | + | + | x86_64_32, | ++ |
+ | + | + | x86_64_small, | ++ |
+ | + | + | x86_64_medium | ++ |
Linux | +pgi | +mpiuni,mpi,mpt,mpich,mpich1,mpich2,mpich3,mvapich,mvapich2 | +32, 64, | ++ |
+ | + | intelmpi,scalimpi,lam,openmpi,user | +x86_64_32, | ++ |
+ | + | + | x86_64_small, | ++ |
+ | + | + | x86_64_medium | ++ |
Linux | +pgigcc | +mpiuni,mpich,mpich1,mpich2,mpich3,lam,openmpi,user | +32 | ++ |
Linux | +sxcross | +mpiuni,mpi,user | +32 | ++ |
Linux | +xlf | +mpiuni,mpi,user | +32 | ++ |
MinGW | +gfortran | +mpiuni,msmpi,user | +32, 64 | ++ |
MinGW | +intel | +mpiuni,msmpi,user | +32, 64 | ++ |
MinGW | +intelcl | +mpiuni,msmpi,user | +32, 64 | ++ |
OSF1 | +default | +mpiuni,mpi,user | +64 | ++ |
SunOS | +default | +mpiuni,mpi,user | +32, 64 | ++ |
Unicos | +default | +mpiuni,mpi,user | +64 | ++ |
Unicos | +aocc | +mpiuni,mpi,user | +64 | ++ |
Unicos | +cce | +mpiuni,mpi,user | +64 | ++ |
Unicos | +gfortran | +mpiuni,mpi,user | +64 | ++ |
Unicos | +intel | +mpiuni,mpi,user | +64 | ++ |
Unicos | +nvhpc | +mpiuni,mpi,user | +64 | ++ |
Unicos | +pathscale | +mpiuni,mpi,user | +64 | ++ |
Unicos | +pgi | +mpiuni,mpi,user | +64
+
+ + |
++ |
+Building the library for multiple architectures or options at the same +time is supported; building or running the tests or examples is restricted +to one platform/architecture at a time. The output from the test cases +will be stored in a separate directories so the results will be kept +separate for different architectures or options. + +
+ +
+ +
+GNU Make is required to build the ESMF library. On some +systems this will be just the command make. On others +it might be installed as gmake or gnumake. +This document uses make consistently to refer to GNU Make. + +
+Use the --
version option with the locally available make commands
+to determine which variant corresponds to GNU Make on your system. Use the
+respective command when interacting with the ESMF build system, and
+where this documentation uses make.
+
+
+Notice that ESMF does not utilize Autotools (configure or autoconf) or CMake. +Instead, the selection of configuration options is done by setting environment +variables before building the framework. The relevant environment variables +all begin with prefix ESMF_, and are discussed in detail under section +9.5. + +
+Build the library with the command: +
+ make ++ +
+Makefiles throughout the framework are configured to allow users to +compile files only in the directory where make is entered. Shared +libraries are rebuilt only if necessary. In addition the entire ESMF +framework may be built from any directory by entering make all, +assuming that all the environmental variables are set correctly as +described in Section 9.5. + +
+The makefiles are also configured to allow multiple make targets to be +compiled in parallel, via the make -j flag. For example, to use eight +parallel processes to build the library, use -j8: +
+ make -j8 lib ++ +
+The parallel compilation feature depends on ESMF_DEFER_LIB_BUILD=ON +(the default) so that the library build will be deferred until all files +have been compiled. + +
+The -j option should only be used during the creation of the library. +The test base and examples will not work correctly with -j set larger +than 1. + +
+Users may also run examples or execute unit tests of specific classes +by changing directories to the desired class examples or tests +directories and entering make run_examples or +make run_unit_tests, respectively. For non-multiprocessor machines, +uni-processor targets are available as make run_examples_uni or +make run_unit_tests_uni. + +
+ +
+The ESMF source documentation consists of an ESMF User's Guide +and an ESMF Reference Manual for Fortran. + +
+If a user does want to build the documentation, they will need to download the +ESMF code repository (see section 5.1). Latex, latex2html, perl +and csh must also be installed. For example, dependencies may be installed on +Ubuntu Linux using: +
+ [sudo] apt-get install texlive latex2html perl csh ++ +
+To build documentation: +
+ make doc ! Builds the manuals, including pdf and html. ++ +
+The resulting documentation files will be +located in the top level directory $ESMF_DIR/doc + +
+ +
+The ESMF build system offers the standard install target to install all +necessary files created during the build process into user specified locations. +The installation procedure will also install the ESMF documentation if it has +been built successfully following the procedure outlined above. + +
+The installation location can be customized using six ESMF_ environment +variables: + +
+Section 9.5 describes what each of these +environment variables does and how to set them. + +
+Install ESMF with the command: +
+ make install ++ +
+Check the ESMF installation with the command: +
+ make installcheck ++ +
+Advice to installers. To complete the installation of ESMF, a single ESMF specific environment variable should be set. The variable is named ESMFMKFILE, and it must point to the esmf.mk file that was generated during the installation process. Systems that support multiple ESMF installations via management software (e.g. modules, softenv, ...) should set/reset the ESMFMKFILE environment variable as part of the configuration. + +
+Additionally, it is typically convenient to append the user's PATH environment variable to provide access to the ESMF applications that were built during the installation process. The application binaries are located in the directory that was specified as ESMF_INSTALL_BINDIR during the ESMF installation. The location is also stored in variable ESMF_APPSDIR, defined in file esmf.mk. Systems that make ESMF installations available through management software (e.g. modules, softenv, ...) should modify the user's PATH environment variable as part of the configuration. + +
+Hint. By default, file esmf.mk is located next to the ESMF library file in directory ESMF_INSTALL_LIBDIR. Consequently, unless esmf.mk has been moved to a different location after the installation, the correct setting for ESMFMKFILE is $(ESMF_INSTALL_LIBDIR)/esmf.mk. + +
+Rationale. The only piece of information that is needed to use an ESMF installation is the exact location of the associated esmf.mk file. This file contains all of the relevant settings and flags that allow a user to build their application against the ESMF installation. Standardizing the mechanism by which the location of esmf.mk is made available to the user by the system will help users in the design of portable application build systems. (See sections 6 and 8 for details about the usage of esmf.mk.) Further, modifying the user's PATH environment variable is optional, since the location of the ESMF application binaries is available through the esmf.mk file. However, setting the user's PATH variable so that the ESMF applications are directly and conveniently accessible from the command line is recommended, especially if management software (e.g. modules, softenv, ...) is used on the system. + +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node11.html b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node11.html new file mode 100644 index 000000000..1d487dc93 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node11.html @@ -0,0 +1,844 @@ + + + + + ++This section goes into more detail about the ESMF build system and how to +port the ESMF software to new platforms. + +
+ +
+ +
+ +
+The main components of the build system are: + +
+There are two directories containing makefile fragment files used by +the ESMF build system. + +
+The build directory contains the generic makefile fragment file +common.mk that is included by the top level makefile in the source +tree. The common.mk contains generic build system settings and build +rules used across all platforms. A user should have no reason to edit +common.mk. + +
+The build_config directory contains subdirectories with makefile +fragments (build_rules.mk) for each supported platform defining +compilers, compiler flags and the various other definitions that are +necessary to build on each platform. One of the build_rules.mk files +will be included by the build/common.mk file depending on the values of +the environment variables ESMF_OS, ESMF_COMPILER and ESMF_SITE. See below +for more details on environment variables. + +
+
+Environment variables with the prefix ESMF_ are used to pass user +specified information to the ESMF build system. A full list of ESMF_ +environment variables is provided in section 9.5 of this +document. + +
+Most environment variables are optional and the ESMF build system will use +default settings if it finds these variable unset. One piece of information that +must always be provided by setting the respective environment variable is the +root of the ESMF directory. There are three sets of source codes the build +system supports. All need environment variables set to point to their top +level source code directories. + +
+
+To build the ESMF library, ESMF_DIR needs to be set to the top level ESMF +library source code directory. + +
+
+The build system needs ESMF_IMPL_DIR set to the top level source +code directory of the Implementation Report source tree to build the +report and to build and run the examples. + +
+
+An EVA source code tree does not contain a copy of the ESMF build +system. Instead it uses a copy found in an ESMF library source code +tree. Building the EVA applications requires that ESMF_EVA_DIR and +ESMF_DIR be set. ESMF_EVA_DIR has to be set to the top directory +of the EVA source code. ESMF_DIR has to be set to the top directory +of an ESMF source code tree. + +
+
+
+Every source tree contains a makefile in its top level directory. This +makefile includes the common.mk file from the build directory +which in turn includes the platform specific build_rules.mk file from +one of the build_config subdirectories. The top level makefile +contains makefile settings specific for the source code that it is found in. + +
+Each directory in the source tree contains a makefile which includes +the top level makefile. These local makefiles include definitions that +allow the local files and documents to be built. +
+ +
+A single makefile or makefile fragment from the build system never +constitutes a complete set of build rules and settings. Starting from +the local makefile, successive include commands are used to string +together makefiles and makefile fragments to create a complete system +of build rules and settings. Configuration of the build system is +done by including a configuration makefile fragment. A configuration for a +specific machine or compiler is referred to as a site configuration. + +
+The string of files included is fairly short. Makefiles below the top +level makefile include the top level makefile. The top level makefile +includes build/common.mk and then build/common.mk includes a +configuration file from the build_config directory. The configuration +files in the build_config directory contain the platform and site +specific build settings. The os, compiler and site that a file +configures is determined by its name. The configuration makefile +fragments follow the naming convention + +
+
+ build_config/ESMF_OS.ESMF_COMPILER.ESMF_SITE/build_rules.mk ++ +
+where ESMF_OS, ESMF_COMPILER and ESMF_SITE are environment +variables either set by the user or given default values by the build +system. ESMF_OS is the target operating system. If the build is performed +on the target system ESMF_OS will typically have the value +returned by the command uname -s. ESMF_COMPILER is the compiler +name. ESMF_SITE, if set, is generally the current machine name, the +location, or the organization (e.g. mit, cola). If there are no site specific +files for a particular platform, then ESMF_COMPILER and ESMF_SITE +will be set to default. Examples: + +
+
+ ! Default configuration for IBM AIX systems + build_config/AIX.default.default/build_rules.mk + + ! Linux configuration using lahey compilers. + build_config/Linux.lahey.default/build_rules.mk ++ +
+ +
+Some of the ESMF C++ and Fortran source files contain preprocessor directives +to configure the source code for specific platforms. The directives are +included in the source code and are pre-processed before the source code is +compiled. The directives are used to determine among other things, the size +of variable types. + +
+The ESMF build system provides preprocessor directives in +ESMC_Conf.h and ESMF_Conf.inc files +that are included in the source code. These files are located in + +
+
+ build_config/ESMF_OS.ESMF_COMPILER.ESMF_SITE/ESMC_Conf.h + build_config/ESMF_OS.ESMF_COMPILER.ESMF_SITE/ESMF_Conf.inc ++ +
+where ESMF_OS, ESMF_COMPILER and ESMF_SITE are +environment variables set by the user or given default values be the +build system. Based on the settings of these environment variables +the build system provides a path to the correct files during +source code compilation. + +
+ +
+The ESMF build system can be ported to other Unix platforms by adding a new +platform specific makefile fragment and two associated configuration files. +These files (build_rules.mk, ESMC_Conf.h, ESMF_Conf.inc) +must be placed into a new subdirectory of the build_config directory, +following the ESMF_OS.ESMF_COMPILER.ESMF_SITE naming convention. + +
+When porting to a new platform it is often helpful to start with a copy +of the configuration of an existing ESMF port. You may, for example, want to +start with a copy of the build_config/Linux.g95.default directory when +working on a new Linux configuration. + +
+ +
+The purpose of the build_rules.mk makefile fragment is to customize the +build procedure for a specific platform. The customization is done via makefile +variables. The main makefile at the top level of the ESMF directory +structure first includes the common.mk makefile fragment. This common +makefile fragment defines a large number of variables, setting them either to +generally valid default values or to specific values the user has set in their +environment using ESMF_ style environment variables. + +
+The platform specific build_rules.mk makefile fragment is included by +common.mk after the variables have been initialized, but +before any rules are defined in common.mk using these variables. +This gives build_rules.mk a chance to modify these variables as it may +be necessary to accommodate platform specific properties. + +
+Fortunately only a very small subset of variables pre-defined in common.mk +typically need to be modified or overridden in build_rules.mk with +platform specific settings. However, there are some variables that must +be set in every build_rules.mk file. These are variables that are not +pre-set in common.mk. + +
+
+
+The following is a complete alphabetical list of variables that are pre-set +in common.mk before build_rules.mk is included. Some of these +variables correspond to ESMF_ environment variables while others have +a more complicated dependency on the environment variables set by the user. + +
+
+
+ +
+The ESMC_Conf.h file is used to define several settings used +during compilation of ESMF library code written in C++. + +
+
+
+
+
+
+
+The ESMF_Conf.inc file is used to optionally define two +important macros: + +
+
+
+
+ +
+On many platforms, a shared object library is created in addition to the +standard .a archive library. +Shared object libraries are libraries that are pre-linked into an executable. +They can then be linked to an application at run time. There are many advantages +to using shared libraries. These include smaller executable files, and shared +memory usage when multiple executables are running - as is often the case of +programs using MPI. They also allow easier bug fixing and development because +the library can often be upgraded without necessarily re-linking the executables +which call into it. + +
+Shared object libraries can be pre-linked to system libraries and using them +can simplify dealing with ESMF's dependency on Fortran90 and C++ runtime +libraries. + +
+See 9.4 for third party library build requirements. + +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node12.html b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node12.html new file mode 100644 index 000000000..daa36dd6d --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node12.html @@ -0,0 +1,817 @@ + + + + + ++The following subsections go into more detail about how to run the tests and +examples included with the ESMF software. This is the recommended method of +regression testing ESMF, and is routinely used during library code development. +Running the regression tests against an existing ESMF installation is also +supported, and offers a general way to validate a pre-installed ESMF library. + +
+ +
+ +
+Robustness and portability are primary goals of the ESMF development +effort. To ensure that these goals are met, the ESMF includes a +comprehensive suite of tests. They allow testing and validation of +everything from individual functions to complete system tests. These +test suites are used by the ESMF development team as part of their +regular development process. ESMF users can run the testing suites to +verify that the framework software was built and installed properly, +and is running correctly on a particular platform. + +
+ +
+Unless the ESMF library was built in MPI-bypass mode (mpiuni), all applications +compiled and linked against ESMF automatically become MPI applications and must +be executed as such. The ESMF test suite and example applications are no +different in this respect. + +
+Details of how to execute MPI applications vary widely from system to system. +ESMF uses an mpirun script mechanism to abstract away most of these differences. +All ESMF makefile targets that require the execution of applications do this by +launching the application via the executable specified in the +ESMF_MPIRUN variable. ESMF assumes that an MPI applications can be +launched across N processes by calling + +
+
+$(ESMF_MPIRUN) -np N application ++ +
+and that the output of the application arrives at the calling shell via +stdout and stderr. + +
+First, on systems that allow direct launching of MPI application via a suitable +mpirun facility, ESMF can use it directly. This is the ESMF default for +all those configurations that come with a suitable mpirun. In these +cases the ESMF_MPIRUN environment variable does not need to be set by +the user. + +
+There are systems, however, that allow direct launching of MPI application but +provide a launch mechanism that is incompatible with ESMF's assumptions. In +these cases a simple mpirun wrapper is required. The ESMF ./scripts +directory contains wrappers for several cases in this class, e.g. for +interactive POE access on IBM machines and aprun, as well as +yod on Cray machines. The ESMF configurations will access the +appropriate wrapper scripts by default if necessary. + +
+Secondly, there are those systems that utilize batch software to access the +parallel execution environment. One option is to execute the ESMF test targets +from within a batch session, either interactively or from within a script. In +this case the batch software does not add any additional complexity for ESMF. +The same issues discussed above, of how to launch an MPI application, apply +directly. + +
+However, in some cases it is more convenient to execute the ESMF test target +on the front-end machine, and have ESMF access the batch software each time it +needs to launch an application. In fact, on IBM systems this is often the only +working option, because the integrated POE system will execute each application +on the exact same number of processes specified during batch access, regardless +of how many ways in parallel a specific application needs to be run. + +
+Two modes of operation need to be considered in the case of the ESMF batch access. First, +if interactive batch access is available, it is straightforward to write an +mpirun script that fulfills the ESMF requirements outlined above. The +ESMF ./scripts directory contains several scripts that access various +parallel launching facilities though interactive LSF. + +
+Second, if interactive batch access is not available, a more complex scripting +approach is necessary. The basic requirements in this case are that ESMF must +be able to launch MPI applications across N processes by calling + +
+
+$(ESMF_MPIRUN) -np N application , ++ +
+that the output of the application will be available in a file named +application.stdout after the script finishes, and that the +ESMF_MPIRUN script blocks execution until application.stdout +has become accessible. + +
+The ESMF ./scripts directory contains scripts of this flavor for a wide +variety of batch systems. Most of these scripts, when called through ESMF, +will generate a customized, temporary batch script for a specific executable +"on the fly" and submit this batch script to the queuing software. The script +then waits for completion of the submitted job, after which it copies the +output, received through a system specific mechanism, into the prescribed file. + +
+Regardless of whether the batch system access is interactive or not, it is +often necessary to specify various system specific options when calling the +batch submission tool. ESMF utilizes the ESMF_MPIBATCHOPTIONS environment +variable to pass user supplied values to the batch system. + +
+The environment variable ESMF_MPISCRIPTOPTIONS is available to pass +user specified options to the actual script specified by ESMF_MPIRUN. +However, ESMF_MPISCRIPTOPTIONS will only be added automatically to the +ESMF_MPIRUN call if the specified ESMF_MPIRUN can be found in the +ESMF ./scripts directory. + +
+Finally, the value of ESMF_MPILAUNCHOPTIONS is passed to the MPI launch +facility by default, i.e if ESMF_MPIRUN was not specified by the user. +In case the user specifies ESMF_MPIRUN to be anything else but scripts +out of the ESMF ./scripts directory, it is the user's responsibility to +add ESMF_MPISCRIPTOPTIONS to ESMF_MPIRUN and/or to utilize +ESMF_MPILAUNCHOPTIONS within the specified script. + +
+The possibilities covered by the generic scripts provided in the ESMF +./scripts directory, combined with the ESMF_MPISCRIPTOPTIONS, +ESMF_MPIBATCHOPTIONS, and ESMF_MPILAUNCHOPTIONS environment +variables, will satisfy the majority of common situations. There are, however, +circumstances for which a customized, user-provided mpirun script is necessary. +One such situation arises with the LoadLeveler batch software. LoadLeveler +typically requires a list of options specified in the actual batch script. This +is most easily handled by a script that produces such a system and user specific +script "on the fly". Another situation is where certain modules or software +packages need to be made available inside the batch script. Again this is most +easily handled by a customized script the user writes and provides to ESMF via +the ESMF_MPIRUN environment variable. This will override any default +settings for the configuration and rely on the user provided script instead. + +
+Users that face the need to write a customized mpirun script for their +parallel execution environment are encouraged to start with the closest match +from the ESMF ./scripts directory and customize it to their situation. +The best way to see how the existing scripts are used on the supported +platforms is to go to the +http://www.earthsystemmodeling.org/download/platforms/ +web page and follow the link +for the platform of interest. Each test report contains the output of +make info, which lists the settings of the ESMF_MPIxxx +environment variables. + +
+ +
+The unit tests provided with the ESMF library evaluate the following: + +
+Unit tests can be run in either an exhaustive or a non-exhaustive (sanity check) +mode. The exhaustive mode includes the sanity check tests. Typically, sanity +checks for each ESMF capability include creating and destroying an object and +testing its basic function using a valid argument set. In the exhaustive mode, +a wide range of valid and non-valid arguments are evaluated for correct behavior. + +
+The following commands are used to build and run the unit tests provided with +the ESMF: +
+ make [ESMF_TESTEXHAUSTIVE=<ON,OFF>] unit_tests + make [ESMF_TESTEXHAUSTIVE=<ON,OFF>] unit_tests_uni ++ +
+The tests_uni target runs the tests on a single processor. +The tests target runs the test on multiple processors. + +
+The non-exhaustive set of unit tests should all pass. At this point in +development, the exhaustive tests do not all pass. Current problems with +unit tests are being tracked and corrected by the ESMF development team. + +
+The results of running the unit tests can be found in the following location: +
+${ESMF_DIR}/test/test${ESMF_BOPT}/${ESMF_OS}.${ESMF_COMPILER}.${ESMF_ABI}. \ + ${ESMF_SITE} ++ +
+For example, if your esmf source files have been placed in: +
+ /usr/local/esmf ++ +
+If your platform is a Linux uni-processor that has an installed Lahey +Fortran compiler and ESMF_COMPILER has been set to lahey, then the build +system configuration file will be: + +
+
+ build_config/Linux.lahey.default/build_rules.mk ++ +
+If you want to run a debug version of non-exhaustive unit tests, +then you use these commands from /usr/local/esmf: + +
+
+ setenv ESMF_DIR /usr/local/esmf + make ESMF_BOPT=g ESMF_SITE=lahey ESMF_TESTEXHAUSTIVE=OFF tests_uni ++ +
+If you are using ksh, then replace the setenv command with: +
+ export ESMF_DIR=/usr/local/esmf ++ +
+The results of the unit tests will be in: +
+ /usr/local/esmf/test/testg/Linux.lahey.32.default/ ++ +
+At the end of unit test execution a script runs to analyze the results. + +
+The script output indicates whether there are any unit test failures. +If any unit tests fail, please check if the failures are listed as known bugs in the ESMF release +page http://www.earthsystemmodeling.org/download/releases.shtml +for your platform and compiler. +If the failures are not listed please contact ESMF Support at esmf_support@ucar.edu +Please indicate which unit tests are failing, and attach the output of the "make info" command to the email. + +
+The script output indicates whether there are any unit test failures. +The following is a sample from the script output: + +
+
+The unit tests in the following files all pass: + +src/Infrastructure/Array/tests/ESMF_ArrayUTest.F90 +src/Infrastructure/ArrayDataMap/tests/ESMF_ArrayDataMapUTest.F90 +src/Infrastructure/Base/tests/ESMF_BaseUTest.F90 +src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleUTest.F90 +src/Infrastructure/FieldBundleDataMap/tests/ESMF_FieldBundleDataMapUTest.F90 +src/Infrastructure/Config/tests/ESMF_ConfigUTest.F90 +src/Infrastructure/DELayout/tests/ESMF_DELayoutUTest.F90 +src/Infrastructure/Field/tests/ESMF_FRoute4UTest.F90 +src/Infrastructure/Field/tests/ESMF_FieldUTest.F90 +src/Infrastructure/FieldComm/tests/ESMF_FieldGatherUTest.F90 +src/Infrastructure/FieldDataMap/tests/ESMF_FieldDataMapUTest.F90 +src/Infrastructure/Grid/tests/ESMF_GridUTest.F90 +src/Infrastructure/LocalArray/tests/ESMF_ArrayDataUTest.F90 +src/Infrastructure/LocalArray/tests/ESMF_ArrayF90PtrUTest.F90 +src/Infrastructure/LocalArray/tests/ESMF_LocalArrayUTest.F90 +src/Infrastructure/LogErr/tests/ESMF_LogErrUTest.F90 +src/Infrastructure/Regrid/tests/ESMF_Regrid1UTest.F90 +src/Infrastructure/Regrid/tests/ESMF_RegridUTest.F90 +src/Infrastructure/TimeMgr/tests/ESMF_AlarmUTest.F90 +src/Infrastructure/TimeMgr/tests/ESMF_CalRangeUTest.F90 +src/Infrastructure/TimeMgr/tests/ESMF_ClockUTest.F90 +src/Infrastructure/TimeMgr/tests/ESMF_TimeIntervalUTest.F90 +src/Infrastructure/TimeMgr/tests/ESMF_TimeUTest.F90 +src/Infrastructure/VM/tests/ESMF_VMBarrierUTest.F90 +src/Infrastructure/VM/tests/ESMF_VMBroadcastUTest.F90 +src/Infrastructure/VM/tests/ESMF_VMGatherUTest.F90 +src/Infrastructure/VM/tests/ESMF_VMScatterUTest.F90 +src/Infrastructure/VM/tests/ESMF_VMSendVMRecvUTest.F90 +src/Infrastructure/VM/tests/ESMF_VMUTest.F90 +src/Superstructure/Component/tests/ESMF_CplCompCreateUTest.F90 +src/Superstructure/Component/tests/ESMF_GridCompCreateUTest.F90 +src/Superstructure/State/tests/ESMF_StateUTest.F90 + + +The following unit test files failed to build, failed to execute or +crashed during execution: + +src/Infrastructure/TimeMgr/tests/ESMF_CalendarUTest.F90 +src/Infrastructure/VM/tests/ESMF_VMSendRecvUTest.F90 + + +The following unit test files had failed unit tests: + +src/Infrastructure/Field/tests/ESMF_FRoute8UTest.F90 +src/Infrastructure/Grid/tests/ESMF_GridCreateUTest.F90 + + +The following individual unit tests fail: + + FAIL DELayout Get Test, ESMF_FRoute8UTest.F90, line 139 + FAIL Grid Distribute Test, ESMF_GridCreateUTest.F90, line 198 + + +The stdout files for the unit tests can be found at: +/home/bluedawn/svasquez/script_dirs/daily_builds/esmf/test/testO/ \ + AIX.default.64.default + +Found 1224 exhaustive multi processor unit tests, 1220 pass and 4 fail. ++ +
+The following is an example of the output generated when a unit test fails: +
+ESMF_FieldUTest.stdout: FAIL Unique default Field names Test, FLD1.5.1 + & 1.7.1, ESMF_FieldUTest.F90, line 204 Field names + not unique ++ +
+ +
+The system tests provided with the ESMF library evaluate: + +
+The current system test suite includes tests that perform layout +reduction operations, redistribution-transpose, halo operations, +component creation and intra-grid communication. Some of the system +tests are no longer compatible with the current API, but are included +in the release for completeness. A complete description of each +available system test and its current compatibility status can be +found at the ESMF website, +http://www.earthsystemmodeling.org. +The testing +and validation page is accessible from the Development +link on the navigation bar. + +
+The following commands are used to build and run the system tests: + +
+
+ make [SYSTEM_TEST=xxx] system_tests + make [SYSTEM_TEST=xxx] system_tests_uni ++ +
+The system_tests_uni target runs the tests on a single processor. +The system_tests target runs the test on multiple processors. + +
+If a particular SYSTEM_TEST is not specified, then all available system tests +are built and run. + +
+The results of the test can be found in the following location: +
+${ESMF_DIR}/test/test${ESMF_BOPT}/${ESMF_OS}.${ESMF_COMPILER}.${ESMF_ABI}. \ + ${ESMF_SITE} ++ +
+For example, if your ESMF source files have been placed in your home directory: +
+ ~/esmf ++ +
+and your platform and compiler configuration is: +
+ Alpha multi-processor using the native compiler ++ +
+and you want to run an optimized version of system test SimpleCoupling, +then you use these commands from the directory /esmf. +
+ setenv ESMF_PROJECT <project_name> + make ESMF_DIR=`pwd` SYSTEM_TEST=ESMF_SimpleCoupling system_tests ++ +
+If you are using ksh then replace the setenv command with +this: + +
+
+ export ESMF_PROJECT=<project_name> ++ +
+The results will be in: +
+~/esmf/test/testO/OSF1.default.64.default/ESMF_SimpleCouplingSTest.stdout ++ +
+At the end of system test execution a script runs to analyze the results. + +
+The script output indicates whether there are any system test failures. +If any system tests fail, please check if the failures are listed as known bugs in the ESMF release +page http://www.earthsystemmodeling.org/download/releases.shtml +for your platform and compiler. +If the failures are not listed please contact ESMF Support at esmf_support@ucar.edu +Please indicate which system tests are failing, and attach the output of the "make info" command to the email. + +
+The script output indicates whether there are any system test failures. +The following is a sample from the script output: + +
+
+The following system tests passed: + + +src/system_tests/ESMF_CompCreate/ESMF_CompCreateSTest.F90 +src/system_tests/ESMF_FieldExcl/ESMF_FieldExclSTest.F90 +src/system_tests/ESMF_FieldHalo/ESMF_FieldHaloSTest.F90 +src/system_tests/ESMF_FieldHaloPer/ESMF_FieldHaloPerSTest.F90 +src/system_tests/ESMF_FieldRedist/ESMF_FieldRedistSTest.F90 +src/system_tests/ESMF_FieldRegrid/ESMF_FieldRegridSTest.F90 +src/system_tests/ESMF_FieldRegridMulti/ESMF_FieldRegridMultiSTest.F90 +src/system_tests/ESMF_FieldRegridOrder/ESMF_FieldRegridOrderSTest.F90 +src/system_tests/ESMF_FlowComp/ESMF_FlowCompSTest.F90 +src/system_tests/ESMF_FlowWithCoupling/ESMF_FlowWithCouplingSTest.F90 +src/system_tests/ESMF_SimpleCoupling/ESMF_SimpleCouplingSTest.F90 +src/system_tests/ESMF_VectorStorage/ESMF_VectorStorageSTest.F90 + + +The following system tests failed, did not build, or did not execute: + + +src/system_tests/ESMF_FieldRegridConserv/ESMF_FieldRegridConsrvSTest.F90 +src/system_tests/ESMF_RowReduce/ESMF_RowReduceSTest.F90 + + + + +The stdout files for the system_tests can be found at: +/home/bluedawn/svasquez/script_dirs/daily_builds/esmf/test/testO/ \ + AIX.default.64.default + +Found 14 system tests, 12 passed and 2 failed. ++ +
+ +
+ +
+Example source code for each class is found in the class's example +directory. For example, source code for the Time Manager class examples +are found in this directory: + +
+
+ ESMF_DIR/src/Infrastructure/TimeMgr/examples/ ++ +
+While the example code is formatted to be included in the documentation, +it also runs and compiles to ensure accuracy. Examples generally +contain simple usage of the basic methods for the class. + +
+ +
+The GNU makefile targets examples and examples_uni build +and run programs found in a class's examples directory. After the +examples are built, the examples target runs the examples using +multiple processors, while examples_uni runs the examples on +a single processor. + +
+These targets first build the ESMF library. + +
+Run from ESMF_DIR, this command will build and run all examples on +multiple processors: + +
+
+ make examples ++ +
+If the command is run in an example source code directory, then only +the example from that directory will be built and run. The examples +and output files are created in this directory: + +
+
+ESMF_DIR/examples/examples$ESMF_BOPT/$ESMF_OS.$ESMF_COMPILER.$ESMF_ABI. \ + $ESMF_SITE/ ++ +
+The name of an output file will begin with the name of the example +that created it followed by .stdout. + +
+At the end of examples execution a script runs to analyze the results. + +
+The script output indicates whether there are any example failures. +If any examples fail, please check if the failures are listed as known bugs in the ESMF release +page http://www.earthsystemmodeling.org/download/releases.shtml +for your platform and compiler. +If the failures are not listed please contact ESMF Support at esmf_support@ucar.edu +Please indicate which examples are failing, and attach the output of the "make info" command to the email. + +
+The following is a sample from the script output: + +
+
+The following examples passed: + + +src/Infrastructure/Array/examples/ESMF_ArrayCreateEx.F90 +src/Infrastructure/Array/examples/ESMF_ArrayGetEx.F90 +src/Infrastructure/ArrayComm/examples/ESMF_ArrayCommEx.F90 +src/Infrastructure/ArrayDataMap/examples/ESMF_ArrayDataMapEx.F90 +src/Infrastructure/ArraySpec/examples/ESMF_ArraySpecEx.F90 +src/Infrastructure/FieldBundle/examples/ESMF_FieldBundleCreateEx.F90 +src/Infrastructure/FieldBundleDataMap/examples/ESMF_FieldBundleDataMapEx.F90 +src/Infrastructure/DELayout/examples/ESMF_DELayoutEx.F90 +src/Infrastructure/Field/examples/ESMF_FieldCreateEx.F90 +src/Infrastructure/Field/examples/ESMF_FieldFromUserEx.F90 +src/Infrastructure/Field/examples/ESMF_FieldGlobalEx.F90 +src/Infrastructure/Field/examples/ESMF_FieldWriteEx.F90 +src/Infrastructure/FieldComm/examples/ESMF_FieldCommEx.F90 +src/Infrastructure/FieldDataMap/examples/ESMF_FieldDataMapEx.F90 +src/Infrastructure/LogErr/examples/ESMF_LogErrEx.F90 +src/Infrastructure/Regrid/examples/ESMF_RegridEx.F90 +src/Infrastructure/Route/examples/ESMF_RouteEx.F90 +src/Infrastructure/TimeMgr/examples/ESMF_AlarmEx.F90 +src/Infrastructure/TimeMgr/examples/ESMF_CalendarEx.F90 +src/Infrastructure/TimeMgr/examples/ESMF_ClockEx.F90 +src/Infrastructure/TimeMgr/examples/ESMF_TimeEx.F90 +src/Infrastructure/VM/examples/ESMF_VMAllFullReduceEx.F90 +src/Infrastructure/VM/examples/ESMF_VMComponentEx.F90 +src/Infrastructure/VM/examples/ESMF_VMDefaultBasicsEx.F90 +src/Infrastructure/VM/examples/ESMF_VMGetMPICommunicatorEx.F90 +src/Infrastructure/VM/examples/ESMF_VMScatterVMGatherEx.F90 +src/Infrastructure/VM/examples/ESMF_VMSendVMRecvEx.F90 +src/Superstructure/Component/examples/ESMF_AppMainEx.F90 +src/Superstructure/Component/examples/ESMF_CplEx.F90 +src/Superstructure/Component/examples/ESMF_GCompEx.F90 +src/Superstructure/State/examples/ESMF_StateEx.F90 +src/Superstructure/State/examples/ESMF_StateReconcileEx.F90 + + +The following examples failed, did not build, or did not execute: + + +src/Infrastructure/Grid/examples/ESMF_GridCreateEx.F90 +src/Infrastructure/TimeMgr/examples/ESMF_TimeIntervalEx.F90 + + +The stdout files for the examples can be found at: +/home/bluedawn/svasquez/script_dirs/daily_builds/esmf/examples/ +examplesO/AIX.default.64.default + + +Found 34 examples, 32 passed and 2 failed. ++ +
+ +
+It is becoming increasingly common to find pre-installed ESMF libraries on +professionally maintained HPC systems. Often multiple versions of ESMF are +available via environment modules. Before using such a third-party ESMF +installation, a user may want ot validate that it is working correctly. System +administrators also often need a simple method to re-validate an existing +ESMF installation, e.g. after a system update. ESMF offers a simple way to +build and run the full regression suite against an existing installation. + +
+A second ESMF source tree is used to run full regression tests against an +existing ESMF installation. To support this, the second source tree must be +of the exact same version as the ESMF installation to be tested. The two +critical environment variables used are ESMF_TESTESMFMKFILE, and +ESMFMKFILE. The following bullets outline the procedure: + +
+ +
+
+
+
+
+
+
+At this point all of the test targets discussed in sections 11.1 and +11.2 are available. The build targets use the test +and example sources under the local (secondary) source tree, but compile and +link against the ESMF library pointed to by ESMFMKFILE. A fully +functional installation is expected to pass all regression tests. + +
+ + +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node13.html b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node13.html new file mode 100644 index 000000000..926d07ab6 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node13.html @@ -0,0 +1,583 @@ + + + + + ++ +
+The ESMF architecture and programming paradigm are based upon +five key concepts: modularity, flexibility, hierarchical +organization, communication within components, and a uniform +communication API. + +
+ +
+The ESMF design is based upon modular Components. There +are two types of Components, one of which represents models +(Gridded Components) and one which represents couplers (Coupler Components). +Data are always passed between Components using a data structure +called a State, which can store Fields, FieldBundles of Fields, +Arrays, and other States. A Gridded Component stores no information about +the internals of the Gridded Components that it interacts with; this information +is passed in through the argument lists of the initialize, run, +and finalize methods. The information that is +passed in through the argument list can be a State from +another Gridded Component, or it can be a function pointer that performs +a computation or communication on a State. These function +pointers are called Transforms, and they are available as AttachableMethods +created by Coupler Components. They are called inside the +Gridded Component they are passed into. Although Transforms add +some complexity to the framework (and their use is not required), they are what +will enable ESMF to accommodate virtually any model of communication +between Components. + +
+Modularity means that an ESMF component stores nothing about +the internals of other components. This allows components to be +used more easily in multiple contexts. + +
+ +
+The ESMF does not impose restrictions on how data flows through +an application. This accommodates scientific innovation - if you +want your atmospheric model to communicate with your sea ice model +mid-timestep, ESMF will not stop you. + +
+ +
+The data structure that enables scalability in ESMF is the +derived type Gridded Component. Fortran alone does not allow you to create +generic components - you'd have to create derived types for +PhysComp, and DynComp, and PhysDynCouplerComp, and AtmComp. In +ESMF, these are always of type GridComp or CplComp, so they +can be called by the same drivers (whether that driver is a +standard ESMF driver or another model), and use the same methods +without having to overload them with many specific derived +types. It is the same idea when you want to support different +implementations of the same component, like multiple dynamics. + +
+The ESMF defines a hierarchical, scalable architecture +that is natural for organizing very complex applications, and +for allowing exchangeable Components. + +
+ +
+ |
+ +
+The point is that although the ESMF defines some simple rules +for communication, the communication mechanism that the +framework uses is not hardwired into its architecture - +the sends and receives or puts and gets are enclosed within +Gridded Components, Coupler Components and Transforms. The intent +is to accommodate multiple models of communication and technical +innovations. + +
+ +
+The goal is to create a programming paradigm +that is performance sensitive to the architecture beneath it +without being discouragingly complicated. + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ |
+ +
+ |
+The set of superstructure abstractions allows flexible data flow and control +between components. However, components will often use different discrete grids, +and time-stepping components may march forward with different time intervals. +In a parallel compute environment different components may be distributed in a +different manner on the underlying compute resources. The ESMF infrastructure +layer provides elements to manage this complexity. + +
+ +
+ +
+ |
+ +
+ +
+The Grid class is also used to represent the decomposition of a data structure into subdomains, typically for +parallel processing purposes. The class is designed to support a +generalized “ghosting” for tiled +decompositions of finite difference, finite volume and finite element codes. + +
+ +
+ +
+ +
+ +
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node14.html b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node14.html new file mode 100644 index 000000000..c469b3460 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node14.html @@ -0,0 +1,325 @@ + + + + + ++In this section we describe how to bring existing applications +into the framework. + +
+ +
+ +
+A Gridded Component is a self-contained +piece of code which will be initialized, will be called once or many times +to run, and then will be finalized. It will be expected to either take in +data from other components/models, produce data, or both. + +
+Generally a computational model like an ocean or atmosphere model will +map either to a single component or to a set of multiple nested +components. + +
+
+A component provides data to other components using an ESMF State +object. A component should fill the State object with a description of +all possible values that it can export. Generally, a piece of code +external to the component (the AppDriver, or a parent component) will +be responsible for marking which of these items are actually going to +be needed. Then the component can choose to either produce all possible +data items (simpler but less efficient) or only produce the data items +marked as being needed. The component should consult the CF data naming conventions +when it is listing +what data it can produce. + +
+
+A component gets data from other components using an ESMF State object. +The application developer must figure out how to get any required +fields from other components in the application. + +
+
+A component should communicate to other components only through the +framework. All global data items should be private to Fortran modules, +and ideally should be isolated to a single derived type which is allocated +at run time. + +
+
+A component needs to provide 3 routines which handle +initialization, running, and finalization. (For codes which have +multiple phases of initialize, run, and finalize it is possible to have +multiple initialize, run, and finalize routines.) + +
+The initialize routine needs to allocate space, initialize +data items, boundary conditions, and do whatever else is necessary in +order to prepare the component to run. + +
+For a sequential application in which all components are on the same +set of processors, the run phase will +be called multiple times. Each time the model is expected to take in +any new data from other models, do its computation, and produce data +needed by other components. A concurrent model, in which different +components are run on different processors, may execute the same +way. Alternatively, it may have its run routine called +only once and may use different parts of the framework to arrange +data exchange with other models. This feature is not yet implemented +in ESMF. + +
+The finalize routine needs to release space, write out results, +close open files, and generally close down the computation gracefully. + +
+
+Components need to provide only a single externally visible entry point. +It will be called at start time, and its job is to register with the +framework which routines satisfy the initialize, run, and finalize +requirements. If it has a single derived type that holds its private data, +that can be registered too. + +
+
+An ESMF State object is fundamentally an annotated list of other +ESMF items, most often expected to be ESMF FieldBundles (groups of +Fields on the same grid). Other things which can be placed in a +State object are Fields, Arrays (raw data with no gridding/coordinate +information) +and other States (generally used by coupling code). Any data which is +going to be received from other components or sent to other components +needs to be represented as an ESMF object. + +
+To create an ESMF Field the code must create an ESMF Array object to +contain the data values, and usually an ESMF Grid object to describe the +computational grid where the values are located. If this is an +observational data stream the locations of the data values will be held in +an ESMF Location Stream object instead of a Grid. + +
+
+During the execution of the run routine, information about time +is transferred between components through ESMF Clocks. The +component needs to be able to at least query a Clock for the +current time using framework methods. + +
+
+The ESMF framework provides a rich set of time management functions, +data management and query functions, and other utility +routines which help to insulate the user's code from the differences +in hardware architectures, system software, and runtime environments. +It is up to the user to select which parts of these functions they +choose to use. + +
+
+ +
+ +
+Select from the set of ESMF components available. + +
+
+Examine what data is produced by each component and what data is +needed by each component. The role of Coupler Components in the +ESMF is to set up any necessary regridding and data conversions +to match output data from one component to input data in another. + +
+
+Decide on a strategy for how to do the coupling. There can be a single +coupler for the application or multiple couplers. +Single couplers follow a "hub and +spoke" model. +Multiple couplers can couple between subsets of the components, and +can be written to couple either only one-way +(e.g. output of component A into input of component B), or two-way +(both A to B and B to A). + +
+The coupler must understand States, Fields, FieldBundles, +Grids, and Arrays and ESMF execution/environment objects +such as DELayouts. + +
+
+The main program can be a copy of a driver found in any of the +system_tests sub-directories. The customization needed is to +use the correct Component module files, to gain access to the +SetServices routines. + +
+Although ESMF provides example source code for the main program, it is +not considered part of the framework and can be changed by +the user as needed. + +
+The final thing the main program must do is call ESMF_Finalize(). +This will close down the framework and release any associated resources. + +
+The main program is responsible for creating a top-level +Gridded Component, which in turn creates other Gridded and Coupler +Components. We encourage this hierarchical design because it +aids in extensibility - the top level Gridded Component can be +nested in another larger application. +The top-level component contains the main time loop and is +responsible for calling the +SetServices entry point for each child component it creates. + +
+
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node15.html b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node15.html new file mode 100644 index 000000000..f399cd9ee --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node15.html @@ -0,0 +1,1012 @@ + + + + + ++This glossary defines terms used in Earth system modeling to describe +parallel computer architectures, grids and grid decompositions, and +numerical and computational methods. + +
+
+
date | +day of year | +
10 January 2000, 6Z | +10.25 | +
31 December 2000, 18Z | +366.75 | +
+
+ Some grids used in Earth system modeling, such as cubed sphere grids, are + most naturally represented + as a set of logically rectangular grids that are connected at their + edges. Following V. Balaji [2006] we refer to each of the + logically rectangular grids in a composite grid, or mosaic grid, as a + Tile. See also mosaic grid, + LocalTile. + +
+ A logically rectangular grid in which the coordinates in physical + space can be completely specified by the two sets of coordinates + that define the opposing corner points of the physical span. The coordinates + of each point in physical space can be obtained by interpolating from + the corner points, using the evenly spaced logical grid to specify + evenly spaced grid point locations. See also + logically rectangular grid, + Rectilinear grid, Curvilinear grid. + +
+
+This document was generated using the +LaTeX2HTML translator Version 2018 (Released Feb 1, 2018) +
+Copyright © 1993, 1994, 1995, 1996,
+Nikos Drakos,
+Computer Based Learning Unit, University of Leeds.
+
+Copyright © 1997, 1998, 1999,
+Ross Moore,
+Mathematics Department, Macquarie University, Sydney.
+
+The command line arguments were:
+ latex2html -white -toc_depth 5 -split +1 -show_section_numbers -local_icons -address 'esmf_support@ucar.edu' ESMF_usrdoc.tex
+
+The translation was initiated on 2024-12-03
+
+The Earth System Modeling Framework (ESMF) is a suite of software +tools for developing high-performance, multi-component Earth science +modeling applications. Such applications may include a few or dozens +of components representing atmospheric, oceanic, terrestrial, or +other physical domains, and their constituent processes (dynamical, chemical, +biological, etc.). Often these components are developed by different +groups independently, and must be “coupled” together using software +that transfers and transforms data among the components in order to form +functional simulations. + +
+ESMF supports the development of these complex applications in a number +of ways. It introduces a set of simple, consistent component interfaces +that apply to all types of components, including couplers themselves. These +interfaces expose in an obvious way the inputs and outputs of each component. +It offers a variety of data structures for transferring data between components, +and libraries for regridding, time advancement, and other common modeling +functions. Finally, it provides a growing set of tools for using metadata +to describe components and their input and output fields. This capability +is important because components that are self-describing +can be integrated more easily into automated workflows, model and dataset +distribution and analysis portals, and other emerging “semantically enabled” +computational environments. + +
+ESMF is not a single Earth system model into which all components +must fit, and its distribution doesn't contain any scientific code. +Rather it provides a way of structuring components so that they can be used +in many different user-written applications and contexts with minimal code +modification, and so they can be coupled together in new configurations +with relative ease. The idea is to create many components across a +broad community, and so to encourage new collaborations and combinations. + +
+ESMF offers the flexibility needed by this diverse user base. It is tested +nightly on more than two dozen platform/compiler combinations; can be +run on one processor or thousands; supports shared and distributed memory +programming models and a hybrid model; can run components +sequentially (on all the same processors) or concurrently (on mutually +exclusive processors); and supports single executable or multiple +executable modes. + +
+ESMF's generality and breadth of function can make it daunting for the +novice user. To help users navigate the software, we try to apply +consistent names and behavior throughout and to provide many examples. +The large-scale structure of the software is straightforward. +The utilities and data structures for building modeling components +are called the ESMF infrastructure. The coupling interfaces and +drivers are called the superstructure. User code sits between +these two layers, making calls to the infrastructure +libraries underneath and being scheduled and synchronized by the +superstructure above. The configuration resembles a sandwich, as +shown in Figure 1. + +
+ESMF users may choose to extensively rewrite their codes +to take advantage of the ESMF infrastructure, or they may decide to +simply wrap their components in the ESMF superstructure in order to +utilize framework coupling services. Either way, we encourage users +to contact our +support team +if questions arise about how to best +use the software, or how to structure their application. ESMF is +more than software; it's a group of people dedicated to realizing +the vision of a collaborative model development community that spans +institutional and national bounds. + +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node3.html b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node3.html new file mode 100644 index 000000000..d2efe66a0 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node3.html @@ -0,0 +1,131 @@ + + + + + ++This ESMF User's Guide is mainly an installation and build guide for +the new ESMF user and a build reference for the experienced user. +New users are strongly encouraged to download the ESMF software and try +running the system tests and examples that illustrate both ESMF utilities and +coupling services. + +
+The User's Guide is organized as follows. The next two sections, +3 and 4, +concern user support and how to submit comments on the ESMF system +to our development team. +Sections 5 through 11 contain a +Quick Start guide that explains how to install the ESMF software +and run the self-tests, +followed by more detail on ESMF structure and operation, +such as a description of the directory structure and how to build and +run the ESMF example programs. +Section 12 is an architectural overview that describes the +framework's basic goals and features. +Section 13 details the steps required to adapt a component +for use with ESMF. Finally, to help you become familiar with ESMF +terminology, the last section in the User's Guide is a glossary. + +
+
+ |
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node4.html b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node4.html new file mode 100644 index 000000000..885a13829 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node4.html @@ -0,0 +1,82 @@ + + + + + ++More information on the ESMF project as a whole is available on the +ESMF website, http://www.earthsystemmodeling.org. +The website includes release notes and known bugs for each version of the +framework, supported platforms, project history, values, and metrics, related projects, +the ESMF management structure, and much more. Those curious about specific +interfaces should refer to the ESMF Reference Manual for Fortran, which contains a detailed listing and description of +the ESMF API (this version of the document corresponds to the last public version of the framework). Also available on the ESMF website is the +ESMF Developer's Guide +that details our project procedures and conventions. + +
+
+
+
+This section gives a brief description of how to get the ESMF software, build +it, and run the self-tests to verify the installation was successful. There is +also a short guide for using the bundled ESMF command line tools. More detailed +information on each of these steps is provided in sections 9, + 11 and 8, respectively. + +
+With a growing user community requiring access to ESMF, central computing +resources have started providing system wide ESMF installations. The availablity +of center-managed ESMF installations dramatically increases the ease of use of +ESMF. Practically it means that if you are working on a system (such as +Jaguar) that offers a standard ESMF installation, you do not have to +download, build and validate your own ESMF installation from source! Instead you +can proceed directly to using ESMF as a programming library or through access to +the bundled command line tools as described in sections 6 and +8, respectively. + +
+ +
+ http://www.earthsystemmodeling.org -> Download ++ +
+ +
+The build_config directory contains subdirectories for +different operating system and compiler combinations. This is +a useful area to examine if porting ESMF to a new platform. + +
+ +
+After downloading and unpacking the ESMF tar file, the build procedure is: + +
+ +
+The syntax for setting environment variables depends on which shell +you are running. Examples of the two most common ways to set +an environment variable are: +
+The shell environment variables listed below are the ones most +frequently used. There are others which address needs on specific +platforms or are needed under more unusual circumstances; +see section 9 for the full list. +
+
+
+Alternatively, ESMF comes with a single-processor MPI-bypass library which is +the default for Linux and Darwin systems. To force the use of this bypass +library set ESMF_COMM equal to mpiuni. + +
+
+By default Fortran and C++ compiler executables are expected to be located in +a location contained in the user's PATH environment variable. This means +that if you cannot locate the correct compiler executable via the which +command on the shell prompt the ESMF build system won't find it either! + +
+There are advanced ESMF environment variables that can be used to select +specific compiler executables by specifying the full path. This can be used to +pick specific compiler executables without having to modify the PATH +environment variable. + +
+Use 'make info' to see which compiler executables the ESMF build system will +be using according to your environment variable settings. + +
+To see possible values for ESMF_COMPILER, cd to +$ESMF_DIR/build_config and list the directories there. The first part +of each directory name corresponds to the output of 'uname -s' for this +platform. The second part contains possible values for ESMF_COMPILER. In +some cases multiple combinations of Fortran and C++ compilers are possible, e.g. +there is intel and intelgcc available for Linux. Setting +ESMF_COMPILER to intel indicates that both Intel Fortran and +C++ compilers are used, whereas intelgcc indicates that the Intel Fortran +compiler is used in combination with GCC's C++ compiler. + +
+If you do not find a configuration that matches your situation you will need to +port ESMF. + +
+
+
+
+
+
+ +
+GNU Make is required to build the ESMF library. On some +systems this will be just the command make. On others +it might be installed as gmake or gnumake. +This document uses make consistently to refer to GNU Make. + +
+Use the --
version option with the locally available make commands
+to determine which variant corresponds to GNU Make on your system. Use the
+respective command when interacting with the ESMF build system, and
+where this documentation uses make.
+
+
+Notice that ESMF does not utilize Autotools (configure or autoconf) or CMake. +Instead, the selection of configuration options is done by setting environment +variables before building the framework. The relevant environment variables +all begin with prefix ESMF_, and are discussed in detail under section +9.5. + +
+ +
+
+-------------------------------------------------------------- +Make version: +GNU Make 3.80 +Copyright (C) 2002 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. + +-------------------------------------------------------------- +Fortran Compiler version: +Intel(R) Fortran Compiler for applications running on Intel(R) 64, \ + Version 10.1 +Build 20081024 Package ID: l_fc_p_10.1.021 +Copyright (C) 1985-2008 Intel Corporation. All rights reserved. + +Version 10.1 + +-------------------------------------------------------------- +C++ Compiler version: +Intel(R) C++ Compiler for applications running on Intel(R) 64, Version 10.1 +Build 20081024 Package ID: l_cc_p_10.1.021 +Copyright (C) 1985-2008 Intel Corporation. All rights reserved. + +Version 10.1 + +-------------------------------------------------------------- +Preprocessor version: +gcc (GCC) 4.1.2 20070115 (SUSE Linux) +Copyright (C) 2006 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + +-------------------------------------------------------------- +ESMF_VERSION_STRING: 5.1.0 +-------------------------------------------------------------- + +-------------------------------------------------------------- + * User set ESMF environment variables * +ESMF_OS=Linux +ESMF_TESTMPMD=ON +ESMF_TESTHARNESS_ARRAY=RUN_ESMF_TestHarnessArrayUNI_2 +ESMF_DIR=/nobackupp10/scvasque/daily_builds/intel/esmf +ESMF_TESTHARNESS_FIELD=RUN_ESMF_TestHarnessFieldUNI_1 +ESMF_TESTWITHTHREADS=OFF +ESMF_COMM=mpiuni +ESMF_INSTALL_PREFIX= /nobackupp10/scvasque/daily_builds/intel/esmf/.. \ + /install_dir +ESMF_TESTEXHAUSTIVE=ON +ESMF_BOPT=g +ESMF_SITE=default +ESMF_ABI=64 +ESMF_COMPILER=intel + +-------------------------------------------------------------- + * ESMF environment variables * +ESMF_DIR: /nobackupp10/scvasque/daily_builds/intel/esmf +ESMF_OS: Linux +ESMF_MACHINE: x86_64 +ESMF_ABI: 64 +ESMF_COMPILER: intel +ESMF_BOPT: g +ESMF_COMM: mpiuni +ESMF_SITE: default +ESMF_PTHREADS: ON +ESMF_OPENMP: ON +ESMF_ARRAY_LITE: FALSE +ESMF_NO_INTEGER_1_BYTE: FALSE +ESMF_NO_INTEGER_2_BYTE: FALSE +ESMF_FORTRANSYMBOLS: default +ESMF_DEFER_LIB_BUILD: ON +ESMF_TESTEXHAUSTIVE: ON +ESMF_TESTWITHTHREADS: OFF +ESMF_TESTMPMD: ON +ESMF_TESTSHAREDOBJ: OFF +ESMF_TESTFORCEOPENMP: OFF +ESMF_TESTHARNESS_ARRAY: RUN_ESMF_TestHarnessArrayUNI_2 +ESMF_TESTHARNESS_FIELD: RUN_ESMF_TestHarnessFieldUNI_1 +ESMF_MPIRUN: /nobackupp10/scvasque/daily_builds/intel/esmf/src/ \ + Infrastructure/stubs/mpiuni/mpirun + +-------------------------------------------------------------- + * ESMF environment variables pointing to 3rd party software * + +-------------------------------------------------------------- + * ESMF environment variables for final installation * +ESMF_INSTALL_PREFIX: /nobackupp10/scvasque/daily_builds/intel/esmf/../ \ + install_dir +ESMF_INSTALL_HEADERDIR: include +ESMF_INSTALL_MODDIR: mod/modg/Linux.intel.64.mpiuni.default +ESMF_INSTALL_LIBDIR: lib/libg/Linux.intel.64.mpiuni.default +ESMF_INSTALL_BINDIR: bin/bing/Linux.intel.64.mpiuni.default +ESMF_INSTALL_DOCDIR: doc +ESMF_INSTALL_CMAKEDIR: cmake + + +-------------------------------------------------------------- + * Compilers, Linkers, Flags, and Libraries * +Location of the preprocessor: /usr/bin/gcc +Location of the Fortran compiler: /nasa/intel/fce/10.1.021/bin/ifort +Location of the Fortran linker: /nasa/intel/fce/10.1.021/bin/ifort +Location of the C++ compiler: /nasa/intel/cce/10.1.021/bin/icpc +Location of the C++ linker: /nasa/intel/cce/10.1.021/bin/icpc + +Fortran compiler flags: +ESMF_F90COMPILEOPTS: -g -fPIC -m64 -mcmodel=small -threads -openmp +ESMF_F90COMPILEPATHS: -I/nobackupp10/scvasque/daily_builds/intel/esmf/mod/ \ + modg/Linux.intel.64.mpiuni.default -I/nobackupp10/scvasque/daily_builds \ + /intel/esmf/src/include +ESMF_F90COMPILECPPFLAGS: -DESMF_TESTEXHAUSTIVE -DSx86_64_small=1 \ + -DESMF_OS_Linux=1 -DESMF_MPIUNI +ESMF_F90COMPILEFREECPP: +ESMF_F90COMPILEFREENOCPP: +ESMF_F90COMPILEFIXCPP: +ESMF_F90COMPILEFIXNOCPP: + +Fortran linker flags: +ESMF_F90LINKOPTS: -m64 -mcmodel=small -threads -openmp +ESMF_F90LINKPATHS: -L/nobackupp10/scvasque/daily_builds/intel/esmf/lib/libg/ \ + Linux.intel.64.mpiuni.default -L/nasa/sgi/mpt/1.25/lib -L/nasa/intel/ \ + cce/10.1.021/lib/shared -L/nasa/intel/fce/10.1.021/lib/shared -L/nasa/ \ + intel/cce/10.1.021/lib -L/nasa/intel/fce/10.1.021/lib -L/nasa/intel/cce/ \ + 10.1.021/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/ -L/usr/lib64/gcc/ \ + x86_64-suse-linux/4.1.2/../../../../lib64 +ESMF_F90LINKRPATHS: + -Wl,-rpath,/nobackupp10/scvasque/daily_builds/intel/esmf/lib/libg/ \ + Linux.intel.64.mpiuni.default +ESMF_F90LINKLIBS: -limf -lsvml -lm -lipgo -lguide -lstdc++ -lirc -lgcc_s \ + -lgcc -lirc -lpthread -lgcc_s -lgcc -lirc_s -ldl -lrt -ldl +ESMF_F90ESMFLINKLIBS: -lesmf -limf -lsvml -lm -lipgo -lguide -lstdc++ -lirc \ + -lgcc_s -lgcc -lirc -lpthread -lgcc_s -lgcc -lirc_s -ldl -lrt -ldl + +C++ compiler flags: +ESMF_CXXCOMPILEOPTS: -g -fPIC -m64 -mcmodel=small -pthread -openmp +ESMF_CXXCOMPILEPATHS: -I/nobackupp10/scvasque/daily_builds/intel/ esmf/src/ \ + include -I/nobackupp10/scvasque/daily_builds/intel/esmf/src/Infrastructure \ + /stubs/mpiuni +ESMF_CXXCOMPILECPPFLAGS: -DESMF_TESTEXHAUSTIVE -DSx86_64_small=1 \ + -DESMF_OS_Linux=1 -D__SDIR__=” -DESMF_MPIUNI + +C++ linker flags: +ESMF_CXXLINKOPTS: -m64 -mcmodel=small -pthread -openmp +ESMF_CXXLINKPATHS: -L/nobackupp10/scvasque/daily_builds/intel/esmf/lib/libg/ \ + Linux.intel.64.mpiuni.default -L/nasa/intel/fce/10.1.021/lib/ +ESMF_CXXLINKRPATHS: -Wl,-rpath,/nobackupp10/scvasque/daily_builds/intel/esmf/ \ + lib/libg/Linux.intel.64.mpiuni.default -Wl,-rpath,/nasa/intel/fce/ \ + 10.1.021/lib/ +ESMF_CXXLINKLIBS: -lifport -lifcoremt -limf -lsvml -lm -lipgo -lguide -lirc \ + -lpthread -lgcc_s -lgcc -lirc_s -ldl -lrt -ldl +ESMF_CXXESMFLINKLIBS: -lesmf -lifport -lifcoremt -limf -lsvml -lm -lipgo \ + -lguide -lirc -lpthread -lgcc_s -lgcc -lirc_s -ldl -lrt -ldl + + +-------------------------------------------------------------- +Compiling on Thu Oct 21 02:15:56 PDT 2010 on r75i0n8 +Machine characteristics: Linux r75i0n8 2.6.16.60-0.68.1.20100916-nasa \ + #1 SMP Fri +Sep 17 17:49:05 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux +============================================================== ++ +
+ +
+The makefiles follow the GNU target standards where possible. +The most frequently used targets for building are listed below: +
+ +
+To build and run the unit and system tests, type: +
+make check ++A summary report of success and failures will be printed out at the end. + +
+See section 11.1.1 on how to set up ESMF to be able to launch +the bundled test and example applications. + +
+Other test-related targets are: +
+For all the targets listed above, the string all_tests can be +replaced with one of the strings listed below to select a +specific type of test: +
+For the unit tests only, there is an additional environment variable +which affects how the tests are built: +
+ +
+This section describes how the bundled ESMF command line tools can be built +and used from inside the ESMF source tree. Notice that this is sort of a quick +and dirty way of accessing the ESMF applications. It is supported as +convenience to those users interested in quickly gaining access to the bundled +ESMF command line tools, and do not mind the shortcomings of this approach. +Users interested in maximum portability should instead follow the instructions +provided in section 8. + +
+To build the bundled ESMF command line tools, type: +
+make build_apps ++This will build the command line tools and place the executables under the +$ESMF_DIR/apps directory inside the ESMF source tree. The +command line tools can be directly executed from within the +$ESMF_DIR/apps directory following the system specific rules for +execution. The details will depend on whether ESMF was built with or without +MPI dependency. In the latter case the system specific rules for launching +parallel applications must be followed. System specific execution details on +this level are outside of ESMF's scope. + +
+For most systems, the MPI version of the ESMF bundled command line tools can be +executed by a command equivalent to: + +
+
+mpirun -np X $(ESMF_DIR)/apps/..../<cli-name> ++ +
+where X specifies the total number of PETs and cli-name is the +name of the specific ESMF command line tool to be executed. The .... in +the path indicates the precise subdirectory structure under ./apps which +follows the standard ESMF pattern also used for the ./tests and +./examples subdirectories. + +
+All bundled ESMF command line tool support the standard '--help'
command
+line option that prints out information on its proper use. More detailed
+instructions of the individual tools are available in the "Command Line Tools"
+section of the ESMF Reference Manual.
+
+
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node7.html b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node7.html new file mode 100644 index 000000000..b1114d8ef --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node7.html @@ -0,0 +1,288 @@ + + + + + ++Building user applications against an ESMF installation requires that the +compiler and linker be able to find the appropriate ESMF header, module and +library files. If this procedure has been documented by the installer of the +ESMF library on your system then follow the directions provided. + +
+In the absence of installation specific instructions there are two standard +methods supported by ESMF to build user code against the installation. The +first method is based on a GNU makefile fragment that can be included by the +user code build infrastructure. This method requires that the user application +also uses the +GNU Make +system. The second method is based on +CMake. + +
+ +
+Every ESMF installation provides a file named esmf.mk that contains the +information needed to build a user application gainst the installation. The +location of the esmf.mk file should be documented by the party that +installed ESMF on the system. We recommend that a single ESMF specific +environment variable, ESMFMKFILE, be provided by the system that points to +the esmf.mk file. See section 9.9 for the related discussion +aimed at the person that installs ESMF on a system. + +
+The information in esmf.mk is defined in form of variables. In fact, +syntactically esmf.mk is a makefile fragment and can be imported by an +application specific makefile via the include command. All the variables +in esmf.mk start with the "ESMF_" prefix to prevent conflicts. The +information in esmf.mk is fully specified and is not affected by any +variables set in the user's environment. + +
+The information defined in esmf.mk includes Fortran compiler and linker, +as well as C++ compiler and linker. It further includes the recommended Fortran +and C++ specific compiler and linker flags for building ESMF applications. One +way of using the esmf.mk is to glean the necessary information from it. +This information can then be used either directly on the command line when +compiling a user application, or to hardwire the settings into the application +specific build system. However, the recommended use of esmf.mk is to +include this file in the application specific makefile directly via the +include command. + +
+The Makefile template below demonstrates how a user build system can be +constructed to leverage the esmf.mk file. In practice, most user build +systems will be more complex. However, this template does show that the added +complexity introduced by using esmf.mk is minimal. Examples of how to use +this build system in realistic user scenarios can be found in the +external demos. + +
+The advantages of using esmf.mk, over hard coding suitable compiler and +linker flags into the user build system directly, are robustness and portability. +Robustness is a consequence of the fact that everything defined in esmf.mk +corresponds to the exact settings used during the ESMF library build +(consistency) and during the ESMF test suite build. Using esmf.mk thus +guarantees that the user application is build in the exact same manner as the +ESMF test suite applications that undergo strict regression testing before every +ESMF release. Portability means that a user build system, which uses +esmf.mk in the way the template Makefile demonstrates, will function +as expected on any system where ESMF was successfully installed and tested, +without the need of modifying anything. Every esmf.mk is generated during +a specific ESMF installation using the ESMF tested settings for the host +platform. + +
+
+################################################################################ +### Makefile template for user ESMF application, leveraging esmf.mk mechanism ## +################################################################################ + +################################################################################ +### Finding and including esmf.mk ############################################## + +# Note: This fully portable Makefile template depends on finding environment +# variable "ESMFMKFILE" set to point to the appropriate "esmf.mk" file, +# as is discussed in the User's Guide. +# However, you can still use this Makefile template even if the person +# that installed ESMF on your system did not provide for a mechanism to +# automatically set the environment variable "ESMFMKFILE". In this case +# either manually set "ESMFMKFILE" in your environment or hard code the +# location of "esmf.mk" into the include statement below. +# Notice that the latter approach has negative impact on portability. + +ifneq ($(origin ESMFMKFILE), environment) +$(error Environment variable ESMFMKFILE was not set.) +endif + +include $(ESMFMKFILE) + +################################################################################ +### Compiler and linker rules using ESMF_ variables supplied by esmf.mk ######## + +.SUFFIXES: .f90 .F90 .c .C + +.f90: + $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) \ + $(ESMF_F90COMPILEFREENOCPP) $< + $(ESMF_F90LINKER) $(ESMF_F90LINKOPTS) $(ESMF_F90LINKPATHS) \ + $(ESMF_F90LINKRPATHS) -o $@ $*.o $(ESMF_F90ESMFLINKLIBS) + +.F90: + $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) \ + $(ESMF_F90COMPILEFREECPP) $(ESMF_F90COMPILECPPFLAGS) $< + $(ESMF_F90LINKER) $(ESMF_F90LINKOPTS) $(ESMF_F90LINKPATHS) \ + $(ESMF_F90LINKRPATHS) -o $@ $*.o $(ESMF_F90ESMFLINKLIBS) + +.c: + $(ESMF_CXXCOMPILER) -c $(ESMF_CXXCOMPILEOPTS) \ + $(ESMF_CXXCOMPILEPATHSLOCAL) $(ESMF_CXXCOMPILEPATHS) \ + $(ESMF_CXXCOMPILECPPFLAGS) $< + $(ESMF_CXXLINKER) $(ESMF_CXXLINKOPTS) $(ESMF_CXXLINKPATHS) \ + $(ESMF_CXXLINKRPATHS) -o $@ $*.o $(ESMF_CXXESMFLINKLIBS) + +.C: + $(ESMF_CXXCOMPILER) -c $(ESMF_CXXCOMPILEOPTS) \ + $(ESMF_CXXCOMPILEPATHSLOCAL) $(ESMF_CXXCOMPILEPATHS) \ + $(ESMF_CXXCOMPILECPPFLAGS) $< + $(ESMF_CXXLINKER) $(ESMF_CXXLINKOPTS) $(ESMF_CXXLINKPATHS) \ + $(ESMF_CXXLINKRPATHS) -o $@ $*.o $(ESMF_CXXESMFLINKLIBS) + +################################################################################ +### Sample targets for user ESMF applications ################################## + +all: esmf_UserApplication esmc_UserApplication + +esmf_UserApplication: + +esmc_UserApplication: + +################################################################################ ++ +
+Notice that the ESMF_F90LINKPATHS, ESMF_F90LINKRPATHS, +ESMF_CXXLINKPATHS, and ESMF_CXXLINKRPATHS variables used in the +linking targets might contain paths to the specific compiler version, MPI +implementation, and 3rd party libraries (see section 9.4) +used when building ESMF. The paths are explicitly included in order to +simplify the process of writing an application build system that is consistent +with the ESMF library that is used. + +
+There are, however, situations where it is +desirable to let the application decide what compiler version, MPI version, +and/or 3rd party library verson (e.g. NetCDF) to use. To this end, esmf.mk +defines an alternative set of variables: ESMF_F90ESMFLINKPATHS, +ESMF_F90ESMFLINKRPATHS, ESMF_CXXESMFLINKPATHS, and +ESMF_CXXESMFLINKRPATHS. These variables only encode the precise path to +the ESMF library, and do not specify where to find the compiler, MPI, and/or +3rd party libraries. When using this alternative set of variables, it becomes +the responsibility of the application build system to ensure the required +libraries can be found by the linker, and are compatible with the ESMF +installation. + +
+ +
+An ESMF CMake find file is located at: <ESMF source directory>/cmake/FindESMF.cmake + +
+The find file will parse the esmf.mk file created following a successful
+ESMF build. (See 6.1 for a description of the esmf.mk file.)
+The CMake module sets esmf.mk variables as global CMake variables. When
+using the find file, ESMFMKFILE must be set to the filepath of esmf.mk.
+If this is NOT set, then ESMF_FOUND will always be FALSE. If ESMFMKFILE
+exists, then ESMF_FOUND=TRUE and all ESMF makefile variables will be set
+in the global scope. Optionally, set ESMF_MKGLOBALS to a string list to
+filter makefile variables. For example, to globally scope only ESMF_LIBSDIR
+and ESMF_APPSDIR variables, use this CMake command in CMakeLists.txt: set(ESMF_MKGLOBALS "LIBSDIR" "APPSDIR")
+
+
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node8.html b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node8.html new file mode 100644 index 000000000..654350f21 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node8.html @@ -0,0 +1,260 @@ + + + + + ++Debugging failing applications is often a challenging task. Massive +parallelism, issues with compute node access, and large data volumes (just to +name a few typical HPC aspects) add to the difficulties. For coupled +applications, built from many individual components and libraries, additional +complexity is introduced by the many layers of software. + +
+For applications utilizing ESMF, the ESMF library is one of those software +layers. Due to the "framework" nature of ESMF, the situation can be +more subtle than for "simple" libraries. This is because ESMF code +is called from user code (as for "simple" libraries), as well as calling +back into registered user code (the "framework" aspect of ESMF). The +consequences of this fact relating to debugging of applications are discussed +in this section. + +
+One consequence of the "framework" nature is that ESMF code is executing between +major portions of user code. For instance, when one ESMF component calls into +another ESMF component, the control flow goes through the ESMF software layer. +This provides ESMF with a chance to write messages into an application wide +log file. In particular, for user code that has implemented standard return +code handling, ESMF can log an error trace in the event of detecting an +error condition. The ESMF Reference Manual discusses standard "Return Code +Handling" under a section of the same name. + +
+By default, the application wide ESMF log output is written to files that are +named PET<nnn>.ESMF_LogFile, where <nnn> is the number of the +persistent execution thread (PET) that is writing. Several characteristics of +the default log can be changed during the call to ESMF_Initialize(). In +order to take advantage of the ESMF log output, it is important +to ensure that the logkindflag is set to ESMF_LOGKIND_MULTI, which +is the default, or ESMF_LOGKIND_MULTI_ON_ERROR. The latter is +recommended for production runs where extra log output is minimized, and the ESMF +log is only activated when an error is encountered. + +
+Assuming that the ESMF log is active for a failing application, and the user +code follows the documented return code handling, the ESMF log files are among +the first files that should be inspected. The log files are written into the +working directory that was active during the application execution. Assuming +default log file naming, we recommend the following grep command to scan for +errors. + +
+
+grep ERROR PET*.ESMF_LogFile ++ +
+A typical error trace looks similar to the following output. Here is an example +error trace for an application using the NUOPC layer. + +
+
+20210317 150338.047 ERROR PET0 atm.F90:113 Invalid argument - \ + Passing error in return code +20210317 150338.047 ERROR PET0 ATM:src/addon/NUOPC/src/NUOPC_ModelBase.F90:865 +20210317 150338.047 ERROR PET0 esm:src/addon/NUOPC/src/NUOPC_Driver.F90:2570 +20210317 150338.047 ERROR PET0 esm:src/addon/NUOPC/src/NUOPC_Driver.F90:1287 +20210317 150338.047 ERROR PET0 esm:src/addon/NUOPC/src/NUOPC_Driver.F90:466 +20210317 150338.047 ERROR PET0 esmApp.F90:64 Invalid argument - \ + Passing error in return code ++ +
+The first two columns contain the wall clock information of when each individual +log message was written. The third and forth column indicate the type of the log +message, here ERROR, and the PET number, respectively, The sixth column +contains information about the source file and line number. Finally the seventh +column and beyond contain information about the error. + +
+Notice that error traces are logged in backward order. The first ERROR +entry corresponds to the lowest level, where the error condition was first +detected. Here the error was first detected in file atm.F90, at line 113. +The error is then propagated back up to the highest application level, +here ending up in file esmApp.F90, line 64. Due to the framework nature +of ESMF discussed earlier, it is very common to see several layers of ESMF +library code in an error trace, as is the case in this example. Notice however, +that the error was first caught in "user code" atm.F90. + +
+Even if the lowest level indicated (i.e. the start of an error trace) is inside +the ESMF library, it does not immediately indicate an issue with ESMF code. In +such cases it is good to follow the error trace to the first user code entry, +and investigate what ESMF call is made just before that location. +Then consider looking at the specific information passed into the ESMF method +and ensure correctness. + +
+There are situations where an application experiences a hard crash, either +triggered by the runtime library, or the operating system itself. In these cases +the ESMF log files are typically not as helpful, and might even be missing. A +hard crash that produces a code dump, a backtrace to stderr, or is caught under +a debugger, can still be a good source of information to track down the +problematic issue. + +
+An example backtrace for a hard crash is shown below. + +
+
+Program received signal SIGFPE: Floating-point exception - erroneous arithmetic operation. + +Backtrace for this error: +#0 0x7f9e45bed49f in ??? +#1 0x40430e in realize + at /tmp/AtmOcnProto/ocn.F90:149 +#2 0x7f9e49568f8b in _ZNK5ESMCI13MethodElement7executeEPvPi + at /tmp/esmf/src/Superstructure/Component/src/ESMCI_MethodTable.C:333 +#3 0x7f9e49569e74 in _ZN5ESMCI11MethodTable7executeENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPvPiPb + at /tmp/esmf/src/Superstructure/Component/src/ESMCI_MethodTable.C:519 +#4 0x7f9e49568dea in c_esmc_methodtableexecuteef_ + at /tmp/esmf/src/Superstructure/Component/src/ESMCI_MethodTable.C:303 +#5 0x7f9e4982d8da in __esmf_attachmethodsmod_MOD_esmf_methodgridcompexecute + at /tmp/esmf/src/Superstructure/AttachMethods/src/ESMF_AttachMethods.F90:1278 +#6 0x7f9e4a69fcd0 in initializeipdvxp04 + at /tmp/esmf/src/addon/NUOPC/src/NUOPC_ModelBase.F90:1263 +#7 0x7f9e492b8d1a in _ZN5ESMCI6FTable12callVFuncPtrEPKcPNS_2VMEPi + at /tmp/esmf/src/Superstructure/Component/src/ESMCI_FTable.C:2036 +#8 0x7f9e492b605a in ESMCI_FTableCallEntryPointVMHop + at /tmp/esmf/src/Superstructure/Component/src/ESMCI_FTable.C:765 +#9 0x7f9e49654bc3 in _ZN5ESMCI3VMK5enterEPNS_7VMKPlanEPvS3_ + at /tmp/esmf/src/Infrastructure/VM/src/ESMCI_VMKernel.C:2195 +#10 0x7f9e49668136 in _ZN5ESMCI2VM5enterEPNS_6VMPlanEPvS3_ + at /tmp/esmf/src/Infrastructure/VM/src/ESMCI_VM.C:1211 +#11 0x7f9e492b64f0 in c_esmc_ftablecallentrypointvm_ + at /tmp/esmf/src/Superstructure/Component/src/ESMCI_FTable.C:922 +#12 0x7f9e499f8678 in __esmf_compmod_MOD_esmf_compexecute + at /tmp/esmf/src/Superstructure/Component/src/ESMF_Comp.F90:1216 +#13 0x7f9e49e5e19b in __esmf_gridcompmod_MOD_esmf_gridcompinitialize + at /tmp/esmf/src/Superstructure/Component/src/ESMF_GridComp.F90:1408 +#14 0x7f9e4a63740e in loopmodelcompss + at /tmp/esmf/src/addon/NUOPC/src/NUOPC_Driver.F90:2534 +#15 0x7f9e4a641e92 in initializeipdv02p3 + at /tmp/esmf/src/addon/NUOPC/src/NUOPC_Driver.F90:1833 +#16 0x7f9e4a6650c9 in initializep1 + at /tmp/esmf/src/addon/NUOPC/src/NUOPC_Driver.F90:467 +#17 0x7f9e492b8d1a in _ZN5ESMCI6FTable12callVFuncPtrEPKcPNS_2VMEPi + at /tmp/esmf/src/Superstructure/Component/src/ESMCI_FTable.C:2036 +#18 0x7f9e492b605a in ESMCI_FTableCallEntryPointVMHop + at /tmp/esmf/src/Superstructure/Component/src/ESMCI_FTable.C:765 +#19 0x7f9e49654bc3 in _ZN5ESMCI3VMK5enterEPNS_7VMKPlanEPvS3_ + at /tmp/esmf/src/Infrastructure/VM/src/ESMCI_VMKernel.C:2195 +#20 0x7f9e49668136 in _ZN5ESMCI2VM5enterEPNS_6VMPlanEPvS3_ + at /tmp/esmf/src/Infrastructure/VM/src/ESMCI_VM.C:1211 +#21 0x7f9e492b64f0 in c_esmc_ftablecallentrypointvm_ + at /tmp/esmf/src/Superstructure/Component/src/ESMCI_FTable.C:922 +#22 0x7f9e499f8678 in __esmf_compmod_MOD_esmf_compexecute + at /tmp/esmf/src/Superstructure/Component/src/ESMF_Comp.F90:1216 +#23 0x7f9e49e5e19b in __esmf_gridcompmod_MOD_esmf_gridcompinitialize + at /tmp/esmf/src/Superstructure/Component/src/ESMF_GridComp.F90:1408 +#24 0x401aaf in esmapp + at /tmp/AtmOcnProto/esmApp.F90:58 +#25 0x401ee4 in main + at /tmp/AtmOcnProto/esmApp.F90:17 +Floating exception (core dumped) ++ +
+Just as for the ESMF log, the backtrace is produced in reverse order, starting +at the lowest level where the problem was encountered, tracing all the way up +the call stack to main. As expected, the backtrace contains many +layers of ESMF library code. Again this does not immediately indicate that there +is a problem in the library code. In this example user code is visible at the +very top of the stack esmApp.F90, and at the very bottom ocn.F90. +In fact the location of the division by zero is correctly identified by the +runtime library at line 149 in file ocn.F90. + +
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node9.html b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node9.html new file mode 100644 index 000000000..248cc07f0 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/node9.html @@ -0,0 +1,166 @@ + + + + + ++ESMF comes with a set of bundled command line tools (CLT). +These applications include convenient access to general information +about an ESMF installation, and regrid weight file generation (sometimes +referred to as "offline" regridding). This section provides assistance with +respect to building and running the bundled CLTs. If you are using a +pre-installed ESMF on your system, follow the local instructions provided by +the installer or system admin of how to access and run the ESMF CLTs. +Often access is as simple as loading a configuration module to have the +correct path to the ESMF CLT binaries added to your PATH +environment variable. + +
+There are two ways a user may choose to build and access the bundled ESMF +CLTs. Users that prefer not to go through the full ESMF installation +process have the option to build the bundled CLTs inside of the ESMF +source tree, very similar to how the unit tests, system tests and examples are +built. This option is outlined in section 5.3.6 and should only be +considered by users that want quick access to the CLTs and are not +interested in a sharable installation or the development of portable scripts and +makefiles that use the CLTs. Users interested in the latter should +consider the more standard second option outlined below. + +
+The bundled ESMF CLTs are built automatically in the process of +installing ESMF following the instructions given in section 9.9. +On systems that offer system-wide ESMF installations (e.g. via modules or +similar mechanisms) the user need not worry about the build and installation +details. Once installed, the CLTs are accessible through their precise +location on the system. For this purpose every ESMF installation provides a file +named esmf.mk that contains the variable ESMF_APPSDIR which +specifies the precise CLT path. + +
+The esmf.mk mechanism used for CLT access is the same as the one +described in section 6 for writing robust and portable user +makefiles for building and linking user CLTs against an ESMF +installation. One feature of the esmf.mk mechanism is that only one single +piece of information must be known about an ESMF installation to use it, and +that is the location of file esmf.mk itself. The location of this file +should be documented by the party that installed ESMF on the system. We +recommend that a single ESMF specific environment variable ESMFMKFILE be +provided by the system that points to the esmf.mk file. See section +9.9 for the related discussion aimed at the person that installs +ESMF on a system. + +
+Once the exact location of the bundled ESMF CLT files has been +determined, either by inspecting the associated esmf.mk file, or by using +the ESMF_APPSDIR makefile variable directly in the user script or +makefile, the CLTs can be executed following the system specific rules +for execution. The details will depend on whether ESMF was built with or without +MPI dependency. In the latter case the system specific rules for launching +parallel CLTs must be followed. System specific execution details on +this level are outside of ESMF's scope. However, ESMF does offer specific +CLT use examples as part of the external_demos module described +online at the +External Demos webpage. +For most systems, the MPI version of the ESMF bundled CLTs can be +executed by a command equivalent to: + +
+
+mpirun -np X $(ESMF_APPSDIR)/<clt-name> ++ +
+where X specifies the total number of PETs and clt-name is the +name of the specific ESMF command line tool to be executed. + +
+All bundled ESMF CLTs support the standard '--help'
command line
+option that prints out information on its proper use. More detailed
+instructions of the individual CLTs are available in the "Command Line Tools"
+section of the ESMF Reference Manual.
+
+
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/prev.png b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/prev.png new file mode 100644 index 000000000..e60b8b407 Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/prev.png differ diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/prev_g.png b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/prev_g.png new file mode 100644 index 000000000..ac6f0bceb Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/prev_g.png differ diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/up.png b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/up.png new file mode 100644 index 000000000..3937e168f Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/up.png differ diff --git a/docs/nightly/fix/reconcile-info/ESMF_usrdoc/up_g.png b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/up_g.png new file mode 100644 index 000000000..fb36cf765 Binary files /dev/null and b/docs/nightly/fix/reconcile-info/ESMF_usrdoc/up_g.png differ diff --git a/docs/nightly/fix/reconcile-info/NUOPC_howtodoc.pdf b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc.pdf new file mode 100644 index 000000000..816672172 Binary files /dev/null and b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc.pdf differ diff --git a/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/NUOPC_howtodoc.css b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/NUOPC_howtodoc.css new file mode 100644 index 000000000..a97b6ae70 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/NUOPC_howtodoc.css @@ -0,0 +1,37 @@ +/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ +.MATH { font-family: "Century Schoolbook", serif; } +.MATH I { font-family: "Century Schoolbook", serif; font-style: italic } +.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold } + +/* implement both fixed-size and relative sizes */ +SMALL.XTINY { font-size : xx-small } +SMALL.TINY { font-size : x-small } +SMALL.SCRIPTSIZE { font-size : smaller } +SMALL.FOOTNOTESIZE { font-size : small } +SMALL.SMALL { } +BIG.LARGE { } +BIG.XLARGE { font-size : large } +BIG.XXLARGE { font-size : x-large } +BIG.HUGE { font-size : larger } +BIG.XHUGE { font-size : xx-large } + +/* heading styles */ +H1 { } +H2 { } +H3 { } +H4 { } +H5 { } + +/* mathematics styles */ +DIV.displaymath { } /* math displays */ +TD.eqno { } /* equation-number cells */ + + +/* document-specific styles come next */ +DIV.center { } +DIV.navigation { } +PRE.preform { } +DIV.quote { } +SPAN.arabic { } +SPAN.textbf { font-weight: bold } +SPAN.textit { font-style: italic } diff --git a/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/NUOPC_howtodoc.html b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/NUOPC_howtodoc.html new file mode 100644 index 000000000..7c6ffde75 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/NUOPC_howtodoc.html @@ -0,0 +1,170 @@ + + + + + ++ +
+ +
+ +
+ +
+ + +
+ +
+
+ +
+
+
+ +
+ +
+ +
+ +
+ + +
+ +
+
+ +
+
+
+The National Unified Operational Prediction Capability +(NUOPC) is a strategic initiative to fundamentally advance the nation's computational +weather prediction systems and improve forecast models used by National Weather Service, +Air Force and Navy meteorologists, mission planners, and decision makers. The +NUOPC Layer +is +a software layer built on top of the +Earth System Modeling Framework +(ESMF). +ESMF is a high-performance modeling framework that provides +data structures, interfaces, and operations suited for building coupled models +from a set of components. NUOPC refines the capabilities of +ESMF by providing a more precise definition of what it means for a model +to be a component and how components should interact and share data +in a coupled system. The NUOPC Layer software is designed to work +with typical high-performance models in the Earth sciences domain, most +of which are written in Fortran and are based on a distributed memory +model of parallelism (MPI). + +
+The NUOPC Layer implements a set of generic components that +serve as building blocks that can be assembled together in different ways +to build up a coupled modeling application. In some cases, a generic +component can be used as is, and in other cases the generic component +must be specialized (customized) for a particular model or application. +Additionally, the NUOPC Layer defines a set of technical rules for how components +should behave and interact with each other. These technical rules form the +backbone of component interoperability. NUOPC defines this effective interoperability +as the ability of a model component to execute without code changes in a driver that +provides the fields that it requires, and to return with informative messages if its +input requirements are not met. A component that follows the NUOPC Layer technical +rules is considered to be NUOPC Layer compliant. + +
+For brevity, throughout this document we will often use the +term “NUOPC” to refer to the “NUOPC Layer software” that is +the current technical implementation of the NUOPC specification. +Also, the term “NUOPC component” is shorthand for a component +that is NUOPC Layer compliant and can be used in NUOPC-based +systems. + +
+ +
+This document is a starting point for model developers +and technical managers who are new to the NUOPC Layer software +and need to understand the steps involved in making an existing +model codebase NUOPC Layer compliant. + +
+The document is divided into the following sections: + +
+
+
+
+ +
+
+
+
+
+
+This section should help you understand key aspects of the NUOPC Layer +design that are critical for writing the code to make your model +NUOPC Layer compliant. The NUOPC Layer includes four kinds of +generic components, each with a different purpose in a +coupled application. One kind of generic component is the +NUOPC Model, a component that wraps a model +code (such as an atmosphere, ocean, or ice model) such that it +exposes the set of interfaces defined by the NUOPC specification. +You will work primarily with the NUOPC Model generic component +in order to make your model NUOPC Layer compliant. + +
+This documentation focuses primarily on the NUOPC Model Component. +However, you should be aware that there are four kinds of generic +components implemented in the NUOPC Layer: + +
+
+
+
+
+ +
+A key design idea behind NUOPC is that a lot of code (and therefore +behavior) is provided for you. This code is provided via the +four generic components included with the NUOPC library, plus +some additional utility routines. +The NUOPC Model generic component +implements most of the initialization and run behavior for you, but you +have to supply some key parts of the implementation that are specific +to your model. The process of supplying your custom code that completes +the generic NUOPC Model component is called specialization. In other +words, you are specializing the generic component to work for your +particular model. Any parts of the code that you do not specialize are +inherited from the generic component. + +
+Those familiar with object-oriented programming will recognize +the ideas of specialization and inheritance. Since the NUOPC Layer +is written in Fortran 90, which has limited support for +object-oriented programming, your specialization code is +provided in Fortran subroutines which are registered with +NUOPC using function pointers. NUOPC makes callbacks into +your code when required to execute the specialization code. + +
+ +
+ +
+However, as detailed in the section 3.2, +if your model is currently embedded as a subsystem in a larger +application and cannot be built independently, you must first take +steps to modularize the code and remove dependencies to other +models before beginning the NUOPC implementation. + +
+The creation of a NUOPC cap does not mean that your +model must always be run as a NUOPC component. Existing models can +retain their native modes of operation, and running your model in +NUOPC mode becomes a configuration option. + +
+The NUOPC cap becomes a new locus of control for your model when +your model is run in NUOPC mode. In other words, it will make calls into your +model code to initialize your model and step it forward in time. +One result of this is that the very top level main program of +your model may not be used at all when your model is run in +NUOPC mode. This is because all models participating in a coupled +NUOPC application will be controlled by a separate generic component: +the NUOPC Driver. + +
+Putting control into a separate driver enables synchronization +of all models participating in a coupled application, allows NUOPC +to control when each model component runs (and for how long), and allows +NUOPC to intercept and inject variables produced and required +by your model at key parts during execution. Once you have a working +NUOPC cap (you only need to implement it once), you have an interoperable +component that can be used in systems with other NUOPC components. + +
+ +
+We also provide tools to help you check whether your cap is NUOPC-compliant. +NUOPC Compliance can be evaluated using a combination of two tools, the Component +Explorer and the Compliance Checker, included in the ESMF/NUOPC software distribution. +More information is provided in sections 3.8 and +3.10. + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/node4.html b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/node4.html new file mode 100644 index 000000000..0dadb0e76 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/node4.html @@ -0,0 +1,739 @@ + + + + + ++While there is no one right way to write the NUOPC Model cap code, the following +recommended steps represent an incremental approach to developing the cap. + +
+ +
+The primary prerequisite software is the NUOPC library, which is +included with the ESMF distribution, and your model, including +any of its dependencies. + +
+Acquire the latest ESMF release from GitHub: + +
+
+$ git clone https://github.com/esmf-org/esmf.git --branch main --depth 1 ++ +
+Compile and install ESMF. Full installation details can be found in the ESMF User Guide. An example of the basic procedure +for one particular system is outlined below. + +
+
+ # set environment variables for build + # the actual settings depend on your platform + # and the compilation options you select + $ export ESMF_DIR=/path/to/esmf + $ export ESMF_COMPILER=gfortran + $ export ESMF_COMM=openmpi + $ export ESMF_PIO=internal + $ export ESMF_NETCDF=split + $ export ESMF_NETCDF_INCLUDE=/usr/include + $ export ESMF_NETCDF_LIBS="-lnetcdff -lnetcdf" + $ export ESMF_NETCDF_LIBPATH=/usr/lib + $ export ESMF_INSTALL_PREFIX=/path/to/install + + # build + $ cd /path/to/esmf + $ gmake + $ gmake check + $ gmake install ++ +
+ +
+The model also needs to be roughly divided into several execution +methods: initialize, run, and finalize. Each of these methods may +contain several phases. The run method should allow the model to +execute a single timestep, or accept a parameter defining the number of +timesteps or a “run until” time. + +
+Your NUOPC cap code will be cleanest if your model exposes data +structures for input and output variables with clear, well-documented +naming conventions. This will simplify the process of hooking up fields +in the NUOPC cap to your model's data structures. The NUOPC Field +Dictionary uses the Climate and Forecast conventions +for defining field standard names, but can support field name aliases. + +
+Finally, the model should not use the global MPI_COMM_WORLD communicator +explicitly, but should accept a communicator at some point during +startup. A global search and replace can be used to replace +all uses of MPI_COMM_WORLD with a different communicator defined +as a global variable in your model. + +
+ +
+You should choose a configuration of your model that is +simple and stable. Many models have regression test configurations +that can be run quickly and have small output files. These configurations +are typically low resolution, have short execution times, and sometimes +have idealized initial conditions. Some models can also be configured +with some of the physics options turned off to reduce the total amount +of computation. More scientifically interesting or higher resolution configurations +can be used after ensuring that the NUOPC cap is working for the +basic case. + +
+Compile your model on the target system and generate baseline output for the +selected configuration. This will typically be a small set of history or restart +files. We'll use these files later to ensure that your model is reproducing the +expected output when executed through the NUOPC cap. In most cases, when +your model is executed through its NUOPC cap, the output should be bit-for-bit +identical with non-NUOPC runs. (The one caveat to this is that when your +model is used in a coupled system, roundoff error may occur due to slight +differences introduced when grid interpolation is used between models.) + +
+If your model is already using ESMF, you will need to +update your build to link against ESMF version 7 or later. Instructions for checking out this version of ESMF +appear in section 3.1. + +
+ +
+Including the cap code in your model's codebase does not imply that your +model must always be run in NUOPC mode. Instead, when the cap is complete, +the NUOPC mode can be viewed as a configuration option of your model. + +
+You need not start from scratch. Instead start with a NUOPC cap template. +To acquire a cap template you can: + +
+
+
+
+Put the initial cap code into your model source tree. Then, modify +your Makefile or build scripts so that the cap is compiled with the +rest of your model code. Unless your model is already using ESMF, +you'll need to add ESMF compile and linking flags in order to build +the cap. When ESMF is installed, a Makefile fragment named esmf.mk +is generated that contains variables that can be appended to your compile and +link flags. The ESMF User Guide +explains how to use these variables in your Makefile. + +
+ +
+In either case, to simplify the process of compiling and linking against +your model, your model's build process should produce a Makefile fragment file +that defines the following six variables:
+
+
+
+
+
+
+An example makefile fragment useful for statically linking against your model looks like this: + +
+
+ #file: abc.mk + + ESMF_DEP_FRONT = ABC + ESMF_DEP_INCPATH = <absolute path to associated ABC module file> + ESMF_DEP_CMPL_OBJS = <absolute path>/abc.o + ESMF_DEP_LINK_OBJS = <absolute path>/abc.o <absolute path>/xyz.o + ESMF_DEP_SHRD_PATH = + ESMF_DEP_SHRD_LIBS = ++ +
+The variables in the makefile fragment expose a set of dependencies that the +higher-level build system can use to compile and link against your model. +An easy way to generate the makefile fragment is to modify your model's +Makefile to include a new target: + +
+
+ .PRECIOUS: %.o + + %.mk: %.o + @echo "# ESMF self-describing build dependency makefile fragment" > $@ + @echo >> $@ + @echo "ESMF_DEP_FRONT = ABC" >> $@ + @echo "ESMF_DEP_INCPATH = `pwd`" >> $@ + @echo "ESMF_DEP_CMPL_OBJS = `pwd`/"$< >> $@ + @echo "ESMF_DEP_LINK_OBJS = "$(addprefix `pwd`/, $(OBJS)) >> $@ + @echo "ESMF_DEP_SHRD_PATH = " >> $@ + @echo "ESMF_DEP_SHRD_LIBS = " >> $@ + + abc.mk: $(OBJS) ++ +
+The Standardized Component Dependencies +section of the NUOPC Reference Manual contains more details on setting up NUOPC makefile fragments. + +
+Finally, if your build procedure typically produces an executable, it is +recommended that you add a Makefile target (or similar build option) +that produces a library instead of an executable. When used in a NUOPC +system, your model's main program will not be used-instead, a NUOPC_Driver +will be linked to your cap and it will be the locus of control +(i.e., the main program). + +
+Makefile Target Conventions + +
+If your model is built using Make, a common convention is to add +two special targets that build your model and also compile the NUOPC +code you will write. + +
+
+ # this target builds your model and your NUOPC cap + $ make nuopc + # this target installs your NUOPC-compliant model to a particular directory + $ make nuopcinstall DESTDIR=/path/to/install ++ +
+ +
+NUOPC defines a precise initialization sequence-i.e., a series of +steps that all NUOPC components are expected to take when starting +up. A user component cap interacts with the NUOPC initialization +sequence through specific specialization points. Specifically this means +using the NUOPC_CompSpecialize() method during the component's +SetServices method for each of the required specializations, and providing the +necessary implementation. The NUOPC_CompSpecialize() method takes a +specLabel argument to indicate the targeted specialization. All available +specialization labels for model components are listed in the NUOPC +reference manual under the NUOPC_Model API section. + +
+Instead of tackling the full NUOPC initialization sequence at this point in +developing your cap, we recommend that you start by adding calls in your cap's +first initialization phase to your model's existing initialization subroutine(s). +A good place to do this is within the Advertise Fields initialization phase. +This is the phase where each component “advertises” the fields it +requires and can potentially provide. + +
+You will need to add use statements at the top if your cap to import the relevant +initialization subroutines from your model into the NUOPC cap module. +The example code in section 3.11 shows where to add the +call to your model's initialization subroutine(s). + +
+In the next section you will add another call into your model code +before attempting to execute your NUOPC cap. + +
+ +
+This call should only move the model forward a single timestep, +not the full run length. If the subroutine requires a parameter +such as the timestep length or the time to stop, then these +parameters can be retrieved from the cap's ESMF_Clock object. + +
+If your model does not have a subroutine that takes a single timestep, +you will need to create one now. + +
+ +
+One option for testing the cap is to run it using the NUOPC Component Explorer, a specialized NUOPC_Driver designed to execute any NUOPC_Model. +Complete instructions +for acquiring +the Component Explorer and linking it to your NUOPC cap are available. + +
+The instructions above also describe how to turn on the NUOPC Compliance Checker +while running the Component Explorer. The +Compliance Checker produces additional output in the ESMF log +files that is useful for debugging. It also produces WARNINGS +in the logs if a compliance issue is identified. When running with +the basic cap, you should not necessarily expect to have all compliance issues +resolved. + +
+ +
+ +
+To validate that the NUOPC cap is faithfully reproducing your model's +behavior when run in non-NUOPC mode, you should compare your model's +output when run with the NUOPC cap against a baseline run. +This is the best test to ensure that the cap is working correctly. +If the NUOPC cap reproduces your baseline run, you are ready to integrate +your NUOPC Model cap into a coupled system with other NUOPC components. + +
+ +
+ +
+ +
+The following code is a starting point for creating a basic NUOPC + Model cap. + +
+
+module MYMODEL + + !----------------------------------------------------------------------------- + ! Basic NUOPC Model cap + !----------------------------------------------------------------------------- + + use ESMF + use NUOPC + use NUOPC_Model, & + modelSS => SetServices + + ! add use statements for your model's initialization + ! and run subroutines + + implicit none + + private + + public :: SetServices + + !----------------------------------------------------------------------------- + contains + !----------------------------------------------------------------------------- + + subroutine SetServices(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc + + rc = ESMF_SUCCESS + + ! derive from NUOPC_Model + call NUOPC_CompDerive(model, modelSS, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! specialize model + call NUOPC_CompSpecialize(model, specLabel=label_Advertise, & + specRoutine=Advertise, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call NUOPC_CompSpecialize(model, specLabel=label_RealizeProvided, & + specRoutine=Realize, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call NUOPC_CompSpecialize(model, specLabel=label_Advance, & + specRoutine=Advance, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end subroutine + + !----------------------------------------------------------------------------- + + subroutine Advertise(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc + + rc = ESMF_SUCCESS + + ! Eventually, you will advertise your model's import and + ! export fields in this phase. For now, however, call + ! your model's initialization routine(s). + + ! call my_model_init() + + end subroutine + + !----------------------------------------------------------------------------- + + subroutine Realize(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc + + rc = ESMF_SUCCESS + + ! Eventually, you will realize your model's fields here, + ! but leave empty for now. + + end subroutine + + !----------------------------------------------------------------------------- + + subroutine Advance(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc + + ! local variables + type(ESMF_Clock) :: clock + type(ESMF_State) :: importState, exportState + + rc = ESMF_SUCCESS + + ! query the Component for its clock, importState and exportState + call NUOPC_ModelGet(model, modelClock=clock, importState=importState, & + exportState=exportState, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! HERE THE MODEL ADVANCES: currTime -> currTime + timeStep + + ! Because of the way that the internal Clock was set by default, + ! its timeStep is equal to the parent timeStep. As a consequence the + ! currTime + timeStep is equal to the stopTime of the internal Clock + ! for this call of the Advance() routine. + + call ESMF_ClockPrint(clock, options="currTime", & + preString="------>Advancing MODEL from: ", rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + call ESMF_ClockPrint(clock, options="stopTime", & + preString="--------------------------------> to: ", rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! Call your model's timestep routine here + + ! call my_model_update() + + end subroutine + +end module ++ +
+ + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/node5.html b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/node5.html new file mode 100644 index 000000000..82f80c486 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/node5.html @@ -0,0 +1,642 @@ + + + + + ++ +
+ +
+In this section we'll look at code for an example NUOPC Model cap. + The example shows the basic structure of a NUOPC Model cap for a fictitious + atmosphere model called ATM. It is slightly simpler than a “real” cap, + but has enough detail to show the basic coding structures. + Each section of the example cap code will be broken down and described separately. + +
+Finding More NUOPC Code Examples
+
+
+In addition to the example code in this section, the
+ NUOPC Prototypes
+repository contains many small example applications that are helpful
+ for understanding the architecture of NUOPC applications and showing
+ example uses of the NUOPC API. These example applications can be
+ compiled and executed on your system.
+
+
+A good starting point is the + SingleModelProto application, + +which includes a single Model with a Driver and the + AtmOcnProto application +which includes two Models, a Connector, and a Driver. + +
+ +
+
+module ATM + + !----------------------------------------------------------------------------- + ! Basic NUOPC Model cap for ATM component (a fictitious atmosphere model). + !----------------------------------------------------------------------------- + + use ESMF + use NUOPC + use NUOPC_Model, & + modelSS => SetServices + + implicit none + + private + + public :: SetServices + + !----------------------------------------------------------------------------- + contains + !----------------------------------------------------------------------------- ++ +
+ +
+In the example code, the call to NUOPC_CompDerive() indicates that + this component derives from (and specializes) the generic NUOPC_Model + component. In other words, this is a NUOPC_Model component customized + for a specific model. + +
+The calls to NUOPC_CompSpecialize() register + subroutines that are implemented in the cap. + The specLabel argument specifies NUOPC-defined specialization labels. + NUOPC defines explicitly what happens during each phase of the + initialization and these labels uniquely define any specialization that might + be supplied by the user. For example, + label_Advertise is responsible for advertising field in the import- and + exportState of the component. The NUOPC_CompSpecialize() also takes + the specRoutine argument to indicate what routine provides the actual + specialization. This subroutine appears later on in the cap and the name of + the registered subroutine is entirely up to you. + +
+The same specialization approach is used to specialize the generic Run method. + Here label_Advance is specialized by subroutine Advance. + The Advance specialization point is called by NUOPC whenever it needs + your model to take a single timestep forward. Basically, this means + you'll need to add a call inside the specialization subroutine to your + model's timestepping subroutine. +
+
+ subroutine SetServices(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc + + rc = ESMF_SUCCESS + + ! the NUOPC model component will register the generic methods + call NUOPC_CompDerive(model, modelSS, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! specialize model + call NUOPC_CompSpecialize(model, specLabel=label_Advertise, & + specRoutine=Advertise, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call NUOPC_CompSpecialize(model, specLabel=label_RealizeProvided, & + specRoutine=Realize, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call NUOPC_CompSpecialize(model, specLabel=label_Advance, & + specRoutine=Advance, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end subroutine ++ +
+ +
+ +
+For now you should notice a few things: + +
+The purpose of this phase is for your model to advertise its import and + export fields. This means that your model announces which model variables + it is capable of exporting (e.g., an atmosphere might export air pressure at sea level) + and which model variables it requires (e.g., an atmosphere might require + sea surface temperature as a boundary condition). The reason there is an + explicit advertise phase is because NUOPC dynamically matches fields among + all the models participating in a coupled simulation during runtime. So, we + need to collect the list of possible input and output fields from all the + models during their initialization. + +
+As shown in the code below, to advertise a field you call + NUOPC_Advertise with the following parameters: + +
+The example code below advertises one import field with the standard + name "sea_surface_temperature", and two export fields with standard + names "air_pressure_at_sea_level" and "surface_net_downward_shortwave_flux". + +
+Advertising a Field does NOT allocate memory
+
+
+Note that NUOPC does not allocate memory for fields during the
+ advertise phase or when NUOPC_Advertise is called.
+ Instead, this is simply a way for models to communicate the
+ standard names of fields. During a later phase, only those fields that
+ are connected (e.g., a field exported from one model that is
+ imported by another) need to have memory allocated.
+ Also, since ESMF will accept pointers to pre-allocated memory, it is usually not
+ necessary to change how memory is allocated for your model's variables.
+
+
+
+ + !----------------------------------------------------------------------------- + + subroutine Advertise(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc + + ! local variables + type(ESMF_State) :: importState, exportState + + rc = ESMF_SUCCESS + + ! query for importState and exportState + call NUOPC_ModelGet(model, importState=importState, & + exportState=exportState, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! importable field: sea_surface_temperature + call NUOPC_Advertise(importState, & + StandardName="sea_surface_temperature", name="sst", & + TransferOfferGeomObject="will provide", rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! exportable field: air_pressure_at_sea_level + call NUOPC_Advertise(exportState, & + StandardName="air_pressure_at_sea_level", name="pmsl", & + TransferOfferGeomObject="will provide", rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! exportable field: surface_net_downward_shortwave_flux + call NUOPC_Advertise(exportState, & + StandardName="surface_net_downward_shortwave_flux", name="rsns", & + TransferOfferGeomObject="will provide", rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end subroutine ++ +
+ +
+The following code fragment shows the Realize subroutine, which + specializes label_RealizeProvided. During this phase, fields that + were previously advertised should now be realized. Realizing a field + means that an ESMF_Field object is created and it is added to the appropriate + ESMF_State, either import or export. + +
+In order to create an ESMF_Field, you'll first need to create one of the + ESMF geometric types, ESMF_Grid, ESMF_Mesh, or ESMF_LocStream. + For 2D and 3D logically rectangular grids (such as a lat-lon grid), the + typical choice is ESMF_Grid. For unstructured grids, use an ESMF_Mesh. + +
+Describing your model's grid (physical discretization) in the + ESMF representation is one of the most important parts of creating + a NUOPC cap. The ESMF geometric types are described in detail in the ESMF Reference Manual: + +
+For the sake a simplicity, a 10x100 Cartesian grid is created in the code below + and assigned to the variable gridIn. + +
+An ESMF_Field is created by by passing in the field + name (should be the same as advertised), the grid, and the data type of the + field to ESMF_FieldCreate. + +
+Fields are put into import or export States by calling NUOPC_Realize. + The example code realizes three fields in total, one import and two export, + and all three share the same grid. + +
+
+ subroutine Realize(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc + + ! local variables + type(ESMF_State) :: importState, exportState + type(ESMF_Field) :: field + type(ESMF_Grid) :: gridIn + type(ESMF_Grid) :: gridOut + + rc = ESMF_SUCCESS + + ! query for importState and exportState + call NUOPC_ModelGet(model, importState=importState, & + exportState=exportState, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! create a Grid object for Fields + gridIn = ESMF_GridCreateNoPeriDimUfrm(maxIndex=(/10, 100/), & + minCornerCoord=(/10._ESMF_KIND_R8, 20._ESMF_KIND_R8/), & + maxCornerCoord=(/100._ESMF_KIND_R8, 200._ESMF_KIND_R8/), & + coordSys=ESMF_COORDSYS_CART, staggerLocList=(/ESMF_STAGGERLOC_CENTER/), & + rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + gridOut = gridIn ! for now out same as in + + ! importable field: sea_surface_temperature + field = ESMF_FieldCreate(name="sst", grid=gridIn, & + typekind=ESMF_TYPEKIND_R8, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call NUOPC_Realize(importState, field=field, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! exportable field: air_pressure_at_sea_level + field = ESMF_FieldCreate(name="pmsl", grid=gridOut, & + typekind=ESMF_TYPEKIND_R8, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call NUOPC_Realize(exportState, field=field, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! exportable field: surface_net_downward_shortwave_flux + field = ESMF_FieldCreate(name="rsns", grid=gridOut, & + typekind=ESMF_TYPEKIND_R8, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call NUOPC_Realize(exportState, field=field, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end subroutine ++ +
+ +
+As described in the section 4.2, + the subroutine Advance (shown below) has been + registered to the specialization point with the label + model_label_Advance in the SetServices subroutine. This + specialization point subroutine is called within the generic NUOPC_Model + run phase in order to request that your model take a timestep + forward. The code to do this is model dependent, so it does not appear + in the subroutine below. + +
+Each NUOPC component maintains its own clock (an ESMF_Clock object). + The clock is used here to indicate the current model time and the + timestep size. When the subroutine finishes, your model should be + moved ahead in time from the current time by one timestep. NUOPC will + automatically advance the clock for you, so there is no explicit call + to do that here. + +
+Since there is no actual model for us to advance in this example, + the code below simply prints the current time and stop time (current time + timestep) + to standard out. + +
+With respect to specialization point subroutines in general, note that: + +
+
+ subroutine Advance(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc + + ! local variables + type(ESMF_Clock) :: clock + type(ESMF_State) :: importState, exportState + + rc = ESMF_SUCCESS + + ! query the Component for its clock, importState and exportState + call NUOPC_ModelGet(model, modelClock=clock, importState=importState, & + exportState=exportState, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! HERE THE MODEL ADVANCES: currTime -> currTime + timeStep + + ! Because of the way that the internal Clock was set by default, + ! its timeStep is equal to the parent timeStep. As a consequence the + ! currTime + timeStep is equal to the stopTime of the internal Clock + ! for this call of the Advance() routine. + + call ESMF_ClockPrint(clock, options="currTime", & + preString="------>Advancing ATM from: ", rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + call ESMF_ClockPrint(clock, options="stopTime", & + preString="--------------------------------> to: ", rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end subroutine + +end module ++ +
+ + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/node6.html b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/node6.html new file mode 100644 index 000000000..4ada80eaa --- /dev/null +++ b/docs/nightly/fix/reconcile-info/NUOPC_howtodoc/node6.html @@ -0,0 +1,69 @@ + + + + + ++This document was generated using the +LaTeX2HTML translator Version 2018 (Released Feb 1, 2018) +
+Copyright © 1993, 1994, 1995, 1996,
+Nikos Drakos,
+Computer Based Learning Unit, University of Leeds.
+
+Copyright © 1997, 1998, 1999,
+Ross Moore,
+Mathematics Department, Macquarie University, Sydney.
+
+The command line arguments were:
+ latex2html -white -toc_depth 5 -split +1 -show_section_numbers -local_icons -address 'esmf_support@ucar.edu' NUOPC_howtodoc.tex
+
+The translation was initiated on 2024-12-03
+
+ +
+ +
+ +
+ +
+ + +
+ +
+
+ +
+
+
+ +
+ +
+ +
+ +
+ + +
+ +
+
+ +
+
+
+The utility routines are subroutines and functions that package frequently used calling sequences of ESMF methods into single calls. Unlike the pure ESMF API, which is very class centric, the utility routines of the NUOPC Layer often implement tasks that involve several ESMF classes. + +
+The generic components are provided in form of Fortran modules that implement GridComp and CplComp specific methods. Generic components are useful when implementing NUOPC compliant driver, model, mediator, or connector components. The provided generic components form a hierarchy that allows the developer to pick and choose the appropriate level of specification for a certain application. Depending on how specific the chosen level, generic components require more or less specialization to result in fully implemented components.
+
+The NUOPC Layer is implemented in Fortran on top of the public ESMF Fortran API. + +
+The NUOPC utility routines form a very straightforward Fortran API, accessible through the NUOPC Fortran module. The interfaces only use native Fortran types and public ESMF derived types. In order to access the utility API of the NUOPC Layer, user code must include the following two use lines: + +
+
+ use ESMF + use NUOPC ++ +
+The NUOPC generic components are implemented as a collection of Fortran modules. Each module implements a single, well specified set of standard ESMF_GridComp or ESMF_CplComp methods. The nomenclature of the generic component modules starts with the NUOPC_ prefix and continues with the kind: Driver, Model, Mediator, or Connector. The four kinds of generic components implemented by the NUOPC Layer are: + +
+ +
+
+
+
+
+The user code accesses the desired generic component(s) by including a use line for each one. Each generic component defines a small set of public names that are made available to the user code through the use statement. At a minimum the SetServices method is made public. Some of the generic components define additional public routines and labels as part of their user interface. It is recommended to rename entries of an imported generic component module, such as SetServices, in the local scope as part of the use association to prevent potential name clashes. + +
+
+ use NUOPC_<GenericComp>, & + <GenericComp>SS => SetServices ++ +
+A generic component is used by user code to implement a specialized version of the generic component. The user component derives from the generic component code by implementing its own public SetServices routine that calls into the generic SetServices routine via the NUOPC_CompDerive() method. +Typically this should be the first call made before doing anything else. It is through this mechanism that the deriving component inherits functionality that is implemented in the generic component. The example below shows how a specific model component is implemented, deriving from the generic NUOPC_Model: + +
+
+ use NUOPC_Model, & + modelSS => SetServices + + subroutine SetServices(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc + + ! derive from NUOPC_Model + call NUOPC_CompDerive(model, modelSS, rc=rc) + + ! specialize model + !... calls to NUOPC_CompSpecialize() here + + end subroutine ++ +
+ +
+After the call to NUOPC_CompDerive() in a component's SetServices() method, the component is connected to all of the generic code provided by NUOPC for the respective component kind. In order to function properly, e.g. as an atmosphere model, ocean model, driver, etc., the component must be specialized. + +
+The NUOPC_CompSpecialize() method is used to link specific user provided routines to pre-defined NUOPC specialization points. The labels of the pre-defined specialization points are use associated named constants made available by the respective generic component module. The naming of all pre-defined specialization labels starts with the label_ prefix, and is followed by a short intent of the specialization. E.g. label_Advertise refers to the specialization point responsible for advertising Fields in the import- and exportStates of the component. + +
+There are pre-defined specialization labels for Initialize, Run, and Finalize phases. Section 2.4.1 discusses the semantic labeling of specializations in greater detail. Lists of all pre-defined specialization labels for Initialize, Run, and Finalize, for each of the generic NUOPC component kinds, are provided at the beginning of the respective API sections. (Driver: 3.1, Model: 3.3, Mediator: 3.4, Connector: 3.5) + +
+The following code snippet shows a full specialization of NUOPC_Model, using three specialization labels: + +
+
+ use NUOPC_Model, & + modelSS => SetServices + + subroutine SetServices(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc + + rc = ESMF_SUCCESS + + ! derive from NUOPC_Model + call NUOPC_CompDerive(model, modelSS, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + ! specialize model + call NUOPC_CompSpecialize(model, specLabel=label_Advertise, & + specRoutine=Advertise, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call NUOPC_CompSpecialize(model, specLabel=label_RealizeProvided, & + specRoutine=Realize, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + call NUOPC_CompSpecialize(model, specLabel=label_Advance, & + specRoutine=Advance, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & + line=__LINE__, & + file=__FILE__)) & + return ! bail out + + end subroutine ++ +
+The user implemented specialization routines must follow the NUOPC interface definition. + +
+
+ subroutine SpecRoutine(comp, rc) + type(ESMF_*Comp) :: comp + integer, intent(out) :: rc + end subroutine ++ +
+Here type(ESMF_*Comp) either corresponds to type(ESMF_GridComp) for Models, Mediators, and Drivers, or type(ESMF_CplComp) for Connectors. + +
+ +
+Components that are derived from a generic component may choose to only specialize certain aspects, leaving other aspects unspecified. This allows a hierarchy of generic components to be implemented with a high degree of code re-use. The variable level of specialization supports the very differing user needs. Figure 1 depicts the inheritance structure of the standard generic components implemented by the NUOPC Layer. There are two trees, one is rooted in ESMF_GridComp, while the other is rooted in ESMF_CplComp. + +
+ +
+
+ + + + + + + |
+ +
+The NUOPC Layer uses standard metadata on Fields to guide the decision making process that is implemented in generic code. The generic NUOPC_Connector component, for instance, uses the StandardName Attribute to construct a list of matching Fields between the import and export States. The NUOPC Field Dictionary provides a software implementation of a controlled vocabulary for the StandardName Field Attribute. It also associates each registered StandardName with CanonicalUnits. Currently the NUOPC Layer uses the CanonicalUnits entry to verify that Fields are provided in their canonical units. In the future, this entry may help support automatic unit conversion among exchanged fields. + +
+The NUOPC Field Dictionary is set up by loading its content from a YAML 1.2 +file. See section 2.2.1 for details. + +
+Users can extend the dictionary by adding entries (field definitions or synonyms) to the YAML file, or by calling the NUOPC_FieldDictionaryAddEntry() interface. + +
+ +
+In a given NUOPC application, the NUOPC Field Dictionary can be set up by calling the NUOPC_FieldDictionarySetup() method to read in a properly-formatted YAML file. This feature is intended to improve the interoperability of codes that use the NUOPC Layer, as it allows a broader scientific community to contribute to the growth and upkeep of a common NUOPC Field Dictionary file shared among different Earth System Models. At this time, an initial version of the NUOPC Field Dictionary file is available through the dedicated GitHub repository: https://github.com/ESCOMP/NUOPCFieldDictionary, hosted within the Earth System Community Modeling Portal (ESCOMP). + +
+A NUOPC Field Dictionary YAML file is codified as a YAML map (an unordered association of unique keys to values) with only one key: field_dictionary. The value associated with this key is itself a YAML map that should include the mandatory key entries (pointing to the complete set of dictionary entries), and may include the optional keys: version_number, last_modified, institution, contact, source, and description. These optional keys are intended to hold information about the file itself and are currently ignored by the NUOPC Layer. + +
+Entries in the NUOPC Field dictionary are organized as YAML lists of maps. List items under the entries keyword must be indented and preceded with a hyphen (-). + +
+A dictionary entry fully defines a Field if it includes both the standard_name and canonical_units keys and their associated values. This entry may also include a brief narrative describing the Field, stored as the value of the optional key description. + +
+Synonyms can be defined by adding separate entries that include both the alias key, associated with either a single synonym (YAML scalar, e.g. alias: <name>) or a comma-separated list of synonyms within square brackets (YAML flow sequence, e.g. alias: [<name1>, <name2>, ...]), and the standard_name key associated with the original Field name to be substituted. The original Field name must be fully defined in the dictionary file. While adding one alias keyword to a Field definition dictionary entry is allowed and will be parsed by the NUOPC Layer, it is recommended that all synonyms be included as separate entries. + +
+A NUOPC Field dictionary sample file is included below. + +
+
+field_dictionary: + version_number: 0.0.1 + last_modified: 2018-03-14T11:01:19Z + institution: National ESPC, CSC & MCL Working Groups + contact: esmf_support@ucar.edu + + source: https://github.com/ESCOMP/NUOPCFieldDictionary + description: Community-based dictionary for shared coupling fields + + entries: + - standard_name: air_pressure + canonical_units: Pa + description: Air pressure + - standard_name: air_temperature + canonical_units: K + description: + Bulk temperature of the air, + not the surface (skin) temperature + - alias: p + standard_name: air_pressure + - alias: [ t, temp ] + standard_name: air_temperature ++ +
+ +
+A version of the NUOPC Field Dictionary is preloaded by the NUOPC Layer at start-up, and, at this time, consists of the entries show in the table below. The value of the StandardName Attribute in each of these entries complies with the Climate and Forecast (CF) conventions guidelines. + +
+ +
+ +
+ +
+
StandardName | +CanonicalUnits | +
air_pressure_at_sea_level | +Pa | +
magnitude_of_surface_downward_stress | +Pa | +
precipitation_flux | +kg m-2 s-1 | +
sea_surface_height_above_sea_level | +m | +
sea_surface_salinity | +1e-3 | +
sea_surface_temperature | +K | +
surface_downward_eastward_stress | +Pa | +
surface_downward_heat_flux_in_air | +W m-2 | +
surface_downward_northward_stress | +Pa | +
surface_downward_water_flux | +kg m-2 s-1 | +
surface_eastward_sea_water_velocity | +m s-1 | +
surface_net_downward_longwave_flux | +W m-2 | +
surface_net_downward_shortwave_flux | +W m-2 | +
surface_northward_sea_water_velocity | +m s-1 | +
+ + +
+The NUOPC Layer makes extensive use of the ESMF Attribute class to implement metadata on Components, States, and Fields. ESMF Attribute Packages (or AttPacks for short) are used to build an Attribute hierarchy for each object. + +
+In some cases the lowest level NUOPC AttPack contains a nested AttPack defined by ESMF. For all objects, the highest level of the NUOPC AttPack hierarchy is implemented with convention="NUOPC", purpose="Instance". The public NUOPC Layer API allows a user to add Attributes to the highest AttPack hierarchy level. + +
+Note that some of the Attribute names in the following table are longer than the table column width. In these cases the +Attribute name had to be broken into multiple lines. When that happens, a hyphen shows up to indicate the line break. The hyphen +is not part of the Attribute name! + +
+
Attribute name | +Definition | +Controlled vocabulary | +
Kind | +String value indicating component kind. | +Driver | +
Verbosity | +String value, converted into an integer, and interpreted as a bit field. The lower 16 bits (0-15) are reserved to control verbosity of the generic component implementation. Higher bits are available for user level verbosity control. + bit 0: Intro/Extro of methods with indentation. + + bit 1: Intro/Extro with memory info. + + bit 2: Intro/Extro with garbage collection info. + + bit 3: Intro/Extro with local VM info. + + bit 4: Intro/Extro with ImportState info. + + bit 5: Intro/Extro with ExportState info. + + bit 6: Log hierarchy protocol details. + + bit 8: Log Initialize phase with , , and currTime. + + bit 9: Log Run phase with , , and currTime. + + bit 10: Log Finalize phase with , , and currTime. + + bit 11: Log info about data dependency during initialize resolution. + + bit 12: Log run sequence execution. + + bit 13: Log Component creation and destruction. + + bit 14: Log State creation and destruction. |
+0, 1, 2, ... + "off" = 0 (default), + "low": some verbosity, bits: 0, 8, 9, 10, 13 + + "high": more verbosity, bits: 0, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14 + + "max": all lower 16 bits |
+
Profiling | +String value, converted into an integer, and interpreted as a bit field. The lower 16 bits (0-15) are reserved to control profiling of the generic component implementation. Higher bits are available for user level profiling control. + bit 0: Top level profiling of Initialize phases. + + bit 1: Specialization point profiling of Initialize phases. + + bit 2: Additional profiling of internals of Initialize phases. + + bit 3: Top level profiling of Run phases. + + bit 4: Specialization point profiling of Run phases. + + bit 5: Additional profiling of internals of Run phases. + + bit 6: Top level profiling of Finalize phases. + + bit 7: Specialization point profiling of Finalize phases. + + bit 8: Additional profiling of internals of Finalize phases. + + bit 9: Leading barrier for Initialize phases. + + bit 10: Leading barrier for Run phases. + + bit 11: Leading barrier for Finalize phases. + + bit 12: Run sequence iteration events. + |
+0, 1, 2, ... + "off" = 0 (default), + "low": Top level profiling. + "high": Top level, specialization point profiling, and additional profiling of internals. + "max": All lower 16 bits set. |
+
CompLabel | +String value holding the label under which the component was added to its parent driver. | +no restriction | +
InitializePhaseMap | +List of string values, mapping the logical NUOPC initialize phases, of a specific Initialize Phase Definition (IPD) version, to the actual ESMF initialize phase number under which the entry point is registered. | +IPDvXXpY=Z, where XX = two-digit revision number, e.g. 01, Y = logical NUOPC phase number, Z = actual ESMF phase number, with Y, Z > 0 and Y, Z < 10 | +
RunPhaseMap | +List of string values, mapping the logical NUOPC run phases to the actual ESMF run phase number under which the entry point is registered. | +label-string=Z, where label-string can be chosen freely, and Z = actual ESMF phase number. | +
FinalizePhaseMap | +List of string values, mapping the logical NUOPC finalize phases to the actual ESMF finalize phase number under which the entry point is registered. | +label-string=Z, where label-string can be chosen freely, and Z = actual ESMF phase number. | +
InternalInitializePhaseMap | +List of string values, mapping the logical NUOPC initialize phases, of a specific Initialize Phase Definition (IPD) version, to the actual ESMF initialize phase number under which the entry point is registered. | +IPDvXXpY=Z, where XX = two-digit revision number, e.g. 01, Y = logical NUOPC phase number, Z = actual ESMF phase number, with Y, Z > 0 and Y, Z < 10 | +
NestingGeneration | +Integer value enumerating nesting level. | +0, 1, 2, ... | +
Nestling | +Integer value enumerating siblings within the same generation. | +0, 1, 2, ... | +
InitializeDataResolution | +String value indicating whether the resolution loop is disabled or enabled. | +false, true | +
InitializeDataComplete | +String value indicating whether all initialize data dependencies have been satisfied. | +false, true | +
InitializeDataProgress | +String value indicating whether progress is being made resolving initialize data dependencies. | +false, true | +
HierarchyProtocol | +String value specifying the hierarchy protocol. | +"PushUpAllExportsAndUnsatisfiedImports" - activates field mirroring of all exports and unsatisfied imports. By default use reference sharing for the mirrored fields and geom objects. This is the default behavior without having HierarchyProtocol set. "ConnectProvidedFields"- no field mirroring, only connect to externally provided fields in the import- and exportStates. "Explorer" - like the default, but do not use reference sharing. All other values currently disable the hierarchy protocol. | +
+Note that some of the Attribute names in the following table are longer than the table column width. In these cases the +Attribute name had to be broken into multiple lines. When that happens, a hyphen shows up to indicate the line break. The hyphen +is not part of the Attribute name! + +
+
Attribute name | +Definition | +Controlled vocabulary | +
Kind | +String value indicating component kind. | +Model | +
Verbosity | +String value, converted into an integer, and interpreted as a bit field. The lower 16 bits (0-15) are reserved to control verbosity of the generic component implementation. Higher bits are available for user level verbosity control. + bit 0: Intro/Extro of methods with indentation. + + bit 1: Intro/Extro with memory info. + + bit 2: Intro/Extro with garbage collection info. + + bit 3: Intro/Extro with local VM info. + + bit 4: Intro/Extro with ImportState info. + + bit 5: Intro/Extro with ExportState info. + + bit 8: Log Initialize phase with , , and currTime. + + bit 9: Log Run phase with , , and currTime. + + bit 10: Log Finalize phase with , , and currTime. + + bit 11: Log info about data dependency during initialize resolution. + + bit 12: Log run sequence execution. |
+0, 1, 2, ... + "off" = 0 (default), + "low": some verbosity, bits: 0, 8, 9, 10, 13 + + "high": more verbosity, bits: 0, 4, 5, 8, 9, 10, 11, 12, 13, 14 + + "max": all lower 16 bits |
+
Profiling | +String value, converted into an integer, and interpreted as a bit field. The lower 16 bits (0-15) are reserved to control profiling of the generic component implementation. Higher bits are available for user level profiling control. + bit 0: Top level profiling of Initialize phases. + + bit 1: Specialization point profiling of Initialize phases. + + bit 2: Additional profiling of internals of Initialize phases. + + bit 3: Top level profiling of Run phases. + + bit 4: Specialization point profiling of Run phases. + + bit 5: Additional profiling of internals of Run phases. + + bit 6: Top level profiling of Finalize phases. + + bit 7: Specialization point profiling of Finalize phases. + + bit 8: Additional profiling of internals of Finalize phases. + + bit 9: Leading barrier for Initialize phases. + + bit 10: Leading barrier for Run phases. + + bit 11: Leading barrier for Finalize phases. + |
+0, 1, 2, ... + "off" = 0 (default), + "low": Top level profiling. + "high": Top level, specialization point profiling, and additional profiling of internals. + "max": All lower 16 bits set. |
+
Diagnostic | +String value, converted into an integer, and interpreted as a bit field. The lower 16 bits (0-15) are reserved to control diagnostic of the generic component implementation. Higher bits are available for user level diagnostic control. + bit 0: Dump fields of the importState on entering Initialize phases. + + bit 1: Dump fields of the exportState on entering Initialize phases. + + bit 2: Dump fields of the importState on exiting Initialize phases. + + bit 3: Dump fields of the exportState on exiting Initialize phases. + + bit 4: Dump fields of the importState on entering Run phases. + + bit 5: Dump fields of the exportState on entering Run phases. + + bit 6: Dump fields of the importState on exiting Run phases. + + bit 7: Dump fields of the exportState on exiting Run phases. + + bit 8: Dump fields of the importState on entering Finalize phases. + + bit 9: Dump fields of the exportState on entering Finalize phases. + + bit 10: Dump fields of the importState on exiting Finalize phases. + + bit 11: Dump fields of the exportState on exiting Finalize phases. |
+0, 1, 2, ... + "off" = 0 (default), + "max": All lower 16 bits set. |
+
CompLabel | +String value holding the label under which the component was added to its parent driver. | +no restriction | +
InitializePhaseMap | +List of string values, mapping the logical NUOPC initialize phases, of a specific Initialize Phase Definition (IPD) version, to the actual ESMF initialize phase number under which the entry point is registered. | +IPDvXXpY=Z, where XX = two-digit revision number, e.g. 01, Y = logical NUOPC phase number, Z = actual ESMF phase number, with Y, Z > 0 and Y, Z < 10 | +
RunPhaseMap | +List of string values, mapping the logical NUOPC run phases to the actual ESMF run phase number under which the entry point is registered. | +label-string=Z, where label-string can be chosen freely, and Z = actual ESMF phase number. | +
FinalizePhaseMap | +List of string values, mapping the logical NUOPC finalize phases to the actual ESMF finalize phase number under which the entry point is registered. | +label-string=Z, where label-string can be chosen freely, and Z = actual ESMF phase number. | +
InternalInitializePhaseMap | +List of string values, mapping the logical NUOPC initialize phases, of a specific Initialize Phase Definition (IPD) version, to the actual ESMF initialize phase number under which the entry point is registered. | +IPDvXXpY=Z, where XX = two-digit revision number, e.g. 01, Y = logical NUOPC phase number, Z = actual ESMF phase number, with Y, Z > 0 and Y, Z < 10 | +
NestingGeneration | +Integer value enumerating nesting level. | +0, 1, 2, ... | +
Nestling | +Integer value enumerating siblings within the same generation. | +0, 1, 2, ... | +
InitializeDataComplete | +String value indicating whether all initialize data dependencies have been satisfied. | +false, true | +
InitializeDataProgress | +String value indicating whether progress is being made resolving initialize data dependencies. | +false, true | +
HierarchyProtocol | +String value specifying the hierarchy protocol. | +"PushUpAllExportsAndUnsatisfiedImports" for field mirroring and connecting, "ConnectProvidedFields" to only connect provided fields (no mirroring), All other values currently disable the hierarchy protocol. | +
+Note that some of the Attribute names in the following table are longer than the table column width. In these cases the +Attribute name had to be broken into multiple lines. When that happens, a hyphen shows up to indicate the line break. The hyphen +is not part of the Attribute name! + +
+
Attribute name | +Definition | +Controlled vocabulary | +
Kind | +String value indicating component kind. | +Mediator | +
Verbosity | +String value, converted into an integer, and interpreted as a bit field. The lower 16 bits (0-15) are reserved to control verbosity of the generic component implementation. Higher bits are available for user level verbosity control. + bit 0: Intro/Extro of methods with indentation. + + bit 1: Intro/Extro with memory info. + + bit 2: Intro/Extro with garbage collection info. + + bit 3: Intro/Extro with local VM info. + + bit 4: Intro/Extro with ImportState info. + + bit 5: Intro/Extro with ExportState info. + + bit 8: Log Initialize phase with , , and currTime. + + bit 9: Log Run phase with , , and currTime. + + bit 10: Log Finalize phase with , , and currTime. + + bit 11: Log info about data dependency during initialize resolution. + + bit 12: Log run sequence execution. |
+0, 1, 2, ... + "off" = 0 (default), + "low": some verbosity, bits: 0, 8, 9, 10, 13 + + "high": more verbosity, bits: 0, 4, 5, 8, 9, 10, 11, 12, 13, 14 + + "max": all lower 16 bits |
+
Profiling | +String value, converted into an integer, and interpreted as a bit field. The lower 16 bits (0-15) are reserved to control profiling of the generic component implementation. Higher bits are available for user level profiling control. + bit 0: Top level profiling of Initialize phases. + + bit 1: Specialization point profiling of Initialize phases. + + bit 2: Additional profiling of internals of Initialize phases. + + bit 3: Top level profiling of Run phases. + + bit 4: Specialization point profiling of Run phases. + + bit 5: Additional profiling of internals of Run phases. + + bit 6: Top level profiling of Finalize phases. + + bit 7: Specialization point profiling of Finalize phases. + + bit 8: Additional profiling of internals of Finalize phases. + + bit 9: Leading barrier for Initialize phases. + + bit 10: Leading barrier for Run phases. + + bit 11: Leading barrier for Finalize phases. + |
+0, 1, 2, ... + "off" = 0 (default), + "low": Top level profiling. + "high": Top level, specialization point profiling, and additional profiling of internals. + "max": All lower 16 bits set. |
+
Diagnostic | +String value, converted into an integer, and interpreted as a bit field. The lower 16 bits (0-15) are reserved to control diagnostic of the generic component implementation. Higher bits are available for user level diagnostic control. + bit 0: Dump fields of the importState on entering Initialize phases. + + bit 1: Dump fields of the exportState on entering Initialize phases. + + bit 2: Dump fields of the importState on exiting Initialize phases. + + bit 3: Dump fields of the exportState on exiting Initialize phases. + + bit 4: Dump fields of the importState on entering Run phases. + + bit 5: Dump fields of the exportState on entering Run phases. + + bit 6: Dump fields of the importState on exiting Run phases. + + bit 7: Dump fields of the exportState on exiting Run phases. + + bit 8: Dump fields of the importState on entering Finalize phases. + + bit 9: Dump fields of the exportState on entering Finalize phases. + + bit 10: Dump fields of the importState on exiting Finalize phases. + + bit 11: Dump fields of the exportState on exiting Finalize phases. |
+0, 1, 2, ... + "off" = 0 (default), + "max": All lower 16 bits set. |
+
CompLabel | +String value holding the label under which the component was added to its parent driver. | +no restriction | +
InitializePhaseMap | +List of string values, mapping the logical NUOPC initialize phases, of a specific Initialize Phase Definition (IPD) version, to the actual ESMF initialize phase number under which the entry point is registered. | +IPDvXXpY=Z, where XX = two-digit revision number, e.g. 01, Y = logical NUOPC phase number, Z = actual ESMF phase number, with Y, Z > 0 and Y, Z < 10 | +
RunPhaseMap | +List of string values, mapping the logical NUOPC run phases to the actual ESMF run phase number under which the entry point is registered. | +label-string=Z, where label-string can be chosen freely, and Z = actual ESMF phase number. | +
FinalizePhaseMap | +List of string values, mapping the logical NUOPC finalize phases to the actual ESMF finalize phase number under which the entry point is registered. | +label-string=Z, where label-string can be chosen freely, and Z = actual ESMF phase number. | +
InternalInitializePhaseMap | +List of string values, mapping the logical NUOPC initialize phases, of a specific Initialize Phase Definition (IPD) version, to the actual ESMF initialize phase number under which the entry point is registered. | +IPDvXXpY=Z, where XX = two-digit revision number, e.g. 01, Y = logical NUOPC phase number, Z = actual ESMF phase number, with Y, Z > 0 and Y, Z < 10 | +
NestingGeneration | +Integer value enumerating nesting level. | +0, 1, 2, ... | +
Nestling | +Integer value enumerating siblings within the same generation. | +0, 1, 2, ... | +
InitializeDataComplete | +String value indicating whether all initialize data dependencies have been satisfied. | +false, true | +
InitializeDataProgress | +String value indicating whether progress is being made resolving initialize data dependencies. | +false, true | +
HierarchyProtocol | +String value specifying the hierarchy protocol. | +"PushUpAllExportsAndUnsatisfiedImports" for field mirroring and connecting, "ConnectProvidedFields" to only connect provided fields (no mirroring), All other values currently disable the hierarchy protocol. | +
+
Attribute name | +Definition | +Controlled vocabulary | +
Kind | +String value indicating component kind. | +Connector | +
Verbosity | +String value, converted into an integer, and interpreted as a bit field. The lower 16 bits (0-15) are reserved to control verbosity of the generic component implementation. Higher bits are available for user level verbosity control. + bit 0: Intro/Extro of methods with indentation. + + bit 1: Intro/Extro with memory info. + + bit 2: Intro/Extro with garbage collection info. + + bit 3: Intro/Extro with local VM info. + + bit 4: Intro/Extro with ImportState info. + + bit 5: Intro/Extro with ExportState info. + + bit 8: Log FieldTransferPolicy. + + bit 9: Log bond level info. + + bit 10: Log CplList construction. + + bit 11: Log GeomObject Transfer. + + bit 12: Log looping over all elements in CplList for RouteHandle computation, FieldSharing, and Timestamp propagation. + + bit 13: Log Run phase with , , and currTime. + + bit 14: Log info about RouteHandle execution. + + bit 15: Log info about RouteHandle release. |
+0, 1, 2, ... + "off" = 0 (default), + "low": some verbosity, bits: 0, 13 + + "high": more verbosity, bits: 0, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15 + + "max": all lower 16 bits |
+
Profiling | +String value, converted into an integer, and interpreted as a bit field. The lower 16 bits (0-15) are reserved to control profiling of the generic component implementation. Higher bits are available for user level profiling control. + bit 0: Top level profiling of Initialize phases. + + bit 1: Specialization point profiling of Initialize phases. + + bit 2: Additional profiling of internals of Initialize phases. + + bit 3: Top level profiling of Run phases. + + bit 4: Specialization point profiling of Run phases. + + bit 5: Additional profiling of internals of Run phases. + + bit 6: Top level profiling of Finalize phases. + + bit 7: Specialization point profiling of Finalize phases. + + bit 8: Additional profiling of internals of Finalize phases. + + bit 9: Leading barrier for Initialize phases. + + bit 10: Leading barrier for Run phases. + + bit 11: Leading barrier for Finalize phases. + |
+0, 1, 2, ... + "off" = 0 (default), + "low": Top level profiling. + "high": Top level, specialization point profiling, and additional profiling of internals. + "max": All lower 16 bits set. |
+
Diagnostic | +String value, converted into an integer, and interpreted as a bit field. The lower 16 bits (0-15) are reserved to control diagnostic of the generic component implementation. Higher bits are available for user level diagnostic control. + bit 0: Dump fields of the importState on entering Initialize phases. + + bit 1: Dump fields of the exportState on entering Initialize phases. + + bit 2: Dump fields of the importState on exiting Initialize phases. + + bit 3: Dump fields of the exportState on exiting Initialize phases. + + bit 4: Dump fields of the importState on entering Run phases. + + bit 5: Dump fields of the exportState on entering Run phases. + + bit 6: Dump fields of the importState on exiting Run phases. + + bit 7: Dump fields of the exportState on exiting Run phases. + + bit 8: Dump fields of the importState on entering Finalize phases. + + bit 9: Dump fields of the exportState on entering Finalize phases. + + bit 10: Dump fields of the importState on exiting Finalize phases. + + bit 11: Dump fields of the exportState on exiting Finalize phases. |
+0, 1, 2, ... + "off" = 0 (default), + "max": All lower 16 bits set. |
+
CompLabel | +String value holding the label under which the component was added to its parent driver. | +no restriction | +
InitializePhaseMap | +List of string values, mapping the logical NUOPC initialize phases, of a specific Initialize Phase Definition (IPD) version, to the actual ESMF initialize phase number under which the entry point is registered. | +IPDvXXpY=Z, where XX = two-digit revision number, e.g. 01, Y = logical NUOPC phase number, Z = actual ESMF phase number, with Y, Z > 0 and Y, Z < 10 | +
RunPhaseMap | +List of string values, mapping the logical NUOPC run phases to the actual ESMF run phase number under which the entry point is registered. | +label-string=Z, where label-string can be chosen freely, and Z = actual ESMF phase number. | +
FinalizePhaseMap | +List of string values, mapping the logical NUOPC finalize phases to the actual ESMF finalize phase number under which the entry point is registered. | +label-string=Z, where label-string can be chosen freely, and Z = actual ESMF phase number. | +
CplList | +List of StandardNames of the connected Fields. Each StandardName entry may be followed by a colon separated list of connection options. The details are discussed in section 2.4.5 | +Standard names as per field dictionary, followed by connection options defined in section 2.4.5. | +
CplSetList | +List of coupling sets. Each coupling set is identified by a string value. | +no restriction | +
ConnectionOptions | +String value specifying the connection options to be applied to all the fields in the CplList by default. | +Connection options defined in section 2.4.5. | +
EpochThrottle | +Integer specifying the maximum number of outstanding EPOCH messages between any two PETs. The ESMF level default is 10. | +Any positive integer. | +
+
Attribute name | +Definition | +Controlled vocabulary | +
Namespace | +String value holding the namespace of all the objects contained in the State. | +no restriction | +
FieldTransferPolicy | +String value indicating to Connector to transfer/mirror Fields. | +transferNone,
+ +transferAll |
+
+
Attribute name | +Definition | +Controlled vocabulary | +
StandardName | +String value | +no restriction | +
Units | +String value | +no restriction | +
LongName | +String value | +no restriction | +
ShortName | +String value | +no restriction | +
Connected | +Connected status. | +false, true | +
ProducerConnection | +String value indicating whether the Field has been connected with a producer. | +open, targeted,
+ +connected |
+
ConsumerConnection | +String value indicating whether the Field has been connected with a consumer. | +open, targeted,
+ +connected |
+
Updated | +String value indicating updated status during initialization. | +false, true | +
ProducerTransferOffer | +String value indicating a producer component's ability to transfer information about the advertised Field, including its GeomObject. | +will provide,
+ +can provide, + +cannot provide |
+
ProducerTransferAction | +String value indicating the action a producer component is supposed to take with respect to transferring Field information, including its GeomObject. | +provide, accept | +
ConsumerTransferOffer | +String value indicating a consumer component's ability to transfer information about the advertised Field, including its GeomObject. | +will provide,
+ +can provide, + +cannot provide |
+
ConsumerTransferAction | +String value indicating the action a consumer component is supposed to take with respect to transferring Field information, including its GeomObject. | +provide, accept | +
SharePolicyField | +String value indicating a component's policy with respect to sharing the Field data allocation. | +share,
+ +not share |
+
ShareStatusField | +String value indicating the status with respect to sharing the underlying Field data allocation that was negotiated. | +shared,
+ +not shared |
+
SharePolicyGeomObject | +String value indicating a component's policy with respect to sharing the Grid or Mesh on which the advertised Field object is defined. | +share,
+ +not share |
+
ShareStatusGeomObject | +String value indicating the status with respect to sharing the underlying GeomObject that was negotiated. | +shared,
+ +not shared |
+
UngriddedLBound | +Integer value list. If present equals the ungriddedLBound of the provider field during a GeomObject transfer. | +no restriction | +
UngriddedUBound | +Integer value list. If present equals the ungriddedUBound of the provider field.during a GeomObject transfer. | +no restriction | +
GridToFieldMap | +Integer value list. If present equals the gridToFieldMap of the provider field.during a GeomObject transfer. | +no restriction | +
ArbDimCount | +Integer value. If present equals the arbDimCount of the provider field.during a GeomObject transfer. | +no restriction | +
MinIndex | +Integer value list. If present equals the minIndex (of tile 1) of the provider field.during a GeomObject transfer. | +no restriction | +
MaxIndex | +Integer value list. If present equals the maxIndex (of tile 1) of the provider field.during a GeomObject transfer. | +no restriction | +
TypeKind | +Integer value. If present equals the integer representation of typekind of the provider field.during a GeomObject transfer. | +implementation dependent range | +
GeomLoc | +Integer value. If present equals the integer representation of staggerloc (for Grid) or meshloc (for Mesh) of the provider field.during a GeomObject transfer. | +implementation dependent range | +
+The NUOPC layer adds an abstraction on top of the ESMF phase index. ESMF introduces the concept of standard component methods: Initialize, Run, and Finalize. ESMF further recognizes the need for being able to split each of the standard methods into multiple phases. On the ESMF level, phases are implemented by a simple integer phase index. With NUOPC, logical phase labels are introduced that are mapped to the ESMF phase indices. + +
+The NUOPC Layer introducing three component level attributes: InitializePhaseMap, RunPhaseMap, and FinalizePhaseMap. These attributes map logical NUOPC phase labels to integer ESMF phase indices. A NUOPC compliant component fully documents its available phases through the phase maps. + +
+The generic NUOPC_Driver uses the InitializePhaseMap on each of its child component during the initialization stage to correctly interact with each component. The RunPhaseMap is used when setting up run sequences in the Driver. The NUOPC_DriverAddRunElement() takes the phaseLabel argument, and uses the RunPhaseMap attribute internally to translates the label into the corresponding ESMF phase index. The FinalizePhaseMap is currently not used by the NUOPC Layer + +
+Appendix B, section 7, lists the supported logical phase labels for reference. User code very rare needs to interact with the InitializePhaseMap or its entries directly. Instead, user code specializes the initialization behavior of a component through the semantic specialization labels discussed below. + +
+NUOPC implements a very powerful initialization procedure. This procedure is, among other functions, capable of handling component hierarchies, transfer of geometries, reference sharing, and resolving data dependencies during initialization. The initialization features are discussed in detail in their respective sections of this document. + +
+From the user level, specialization of the initialization is accessbile through the semantic specialization labels. These labels are predefined named constants that are passed into the NUOPC_CompSpecialize() method, together with the user provided routine, implementing the required actions. On a technical level, the user routine must follow the standard interface defined by NUOPC. Semantically, the purpose of each specialization point is indicated by the name of the predefined specialization label. For a definition of the labels, and the ascribed purpose, see the SEMANTIC SPECIALIZATION LABELS section under each of the generic component kinds. (Driver: 3.1, Model: 3.3, Mediator: 3.4, Connector: 3.5) + +
+Finally, under NUOPC, each component is associated with a label when it is added to a driver through the NUOPC_DriverAddComp() call. Multiple instances of the same component can be added to a driver, provided each instance is given a unique label. Connectors between components are identified by providing the label of the source component and destination component. + +
+The NUOPC Model and Mediator components are required to advertise their import and export Fields with a standard set of Field metadata. This set includes the StandardName attribute. The NUOPC Layer implements a strategy of pairing advertised Fields that is based primarily on the StandardName of the Fields, and in more complex situations further utilizes the Namespace attribute on States. + +
+Field pairing is accomplished as part of the initialization procedure and is a collective effort of the Driver and its child components: Models, Mediator, Connectors. The Connectors are the most active players when it comes to Field pairing. The end result of the process is where each Connector has a list of Fields that it connects between its importState and its exportState. Each connector keeps this list in its component level metadata as CplList attribute. + +
+During the first stage of Field pairing, each Connector matches all of the Fields in its importState to all of the Fields in its exportState by looking at their StandardName attribute. For every match a bondLevel is calculated and stored in the Field on the export side, i.e. on the consumer side of the connection, in the Field's ConsumerConnection attribute. The larges found bondLevel is kept for each Field on the export side. + +
+The bondLevel is a measure of how strong the pairing is considering the namespace rules explained in section 2.4.3. Without the use of namespaces the bondLevel for all Field pairs that match by their StandardName is equal to 1. + +
+After the first stage, there may be umbiguous Field pairs present. Ambiguous Field pairs are those that map different producer Fields (i.e. Fields in the importState of a Connector) to the same consumer Field (i.e. a Field in the exportState of a Connector). While the NUOPC Layer support having multiple consumer Fields connected to a single producer Field, it does not support the opposite condition. The second stage of Field pairing is responsible for disambiguating Field pairs with the same consumer Field. + +
+Field pair disambiguation is based on the bondLevel that was calculated and stored on the consumer side Field for each pair during the first stage. The disambiguation rule simply selects the connection with the highest bondLevel and discards all lesser connection to the same consumer side Field. However, if the highest bondLevel is not unique, i.e. there are multiple pairs with the same bondLevel, disambiguation is not possible and an error is returned to the Driver by the Connector that finds the ambiguity first. + +
+Assuming that the disambiguation step was successful, each Connector holds a valid CplList attribute with entries that correspond to the Field pairs that it is responsible for. At this stage the Driver can still overwrite this attribute and implement custom pairs if that is desired. + +
+Namespaces are used to control and fine-tune the disambiguation of Field pairs during the initialization. The general procedure of Field pairing and disambiguation is outlined in section 2.4.2, here the use of namespaces is described. + +
+The NUOPC Layer implements namespaces through the Namespace attribute on ESMF_State objects. The value of this attribute is a simple character string. The NUOPC Layer automatically creates the import and export States of every Model and Mediator component that is added to a Driver. The Namespace attribute of these States is automatically set to the compLabel string that was provided during NUOPC_DriverAdd(). Doing this places every Field that is advertised through these States inside the component's unique namespace. + +
+A secondary namespace can be added to a State using the NUOPC_StateNamespaceAdd() method. This creates a new State that is nested inside of an existing State, and sets the Namespace attribute of the new State. Fields that are advertised inside of such a nested State are in a namespace with two parts: NS1:NS2. Here NS1 is the preset namespace of the import or export State (equal to the compLabel), and NS2 is a freely chosen namespace string. + +
+During Field pairing the namespace on each side of the connection is considered in the two part format NS1:NS2. The first part is equal to the compLabel of the corresponding component, and NS2 is either the namespace of a nested State, or empty if the Field is not inside a nested State. Using this format, the calculation of the bondLevel during Field pairing is governed by the following rules: + +
+ +
+In practice then, a component that targets a specific other component with its advertised Fields would add a secondary namespace to its import or export State, and set that namespace to the compLabel of the targeted component. This increases the bondLevel for each pair from 1 to 2. An even higher bondLevel of 3 is achieved when both sides target each other by specifying the other component's compLabel through a secondary namespace. + +
+In conclusion, namespaces can affect the bondLevel calculation for each pair, but they do not affect how pairs are constructed and disambiguated. In particular, the requirement for unambiguous Field pairs for each consumer Field remains unchanged, and it is an error condition if the highest bondLevel for a consumer Field does not correspond to a unique Field pair. + +
+The NUOPC Layer can couple multiple data sets by adding nested states to the import and export states of a NUOPC_Model. Each nested state is given a couple set identifier at the time it is added to the parent state. This identifier guarantees a NUOPC_Connector will only pair fields within this nested state to fields in a connected state with an identical identifier. + +
+During label_Advertise, before calling NUOPC_Advertise (using methods 3.9.3 or 3.9.4), add nested states to import and export states using NUOPC_AddNestedState. Each nested state is given a couple set identifier using the CplSet argument, see 3.9.2. The nested states can then be used to advertise and realize fields. Each nested state may contain fields with identical standard names or unique standard names. Fields in each nested state will only connect to fields in another state if that state has an identical couple set identifier. + +
+For a complete example of how to couple sets using the NUOPC API, see https://github.com/esmf-org/nuopc-app-prototypes/tree/develop/AtmOcnCplSetProto. The following code snippets demonstrates the critical pieces of code used to add a nested state with a couple set identifier. + +
+
+ subroutine Advertise(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc + + ! local variables + type(ESMF_State) :: importState, exportState + type(ESMF_State) :: NStateImp1, NStateImp2 + type(ESMF_State) :: NStateExp1, NStateExp2 + + rc = ESMF_SUCCESS + + ! query model for importState and exportState + call NUOPC_ModelGet(model, importState=importState, & + exportState=exportState, rc=rc) + ! check rc + + ! add nested import states with couple set identifier + call NUOPC_AddNestedState(importState, & + CplSet="Nest1", nestedStateName="NestedStateImp_N1", & + nestedState=NStateImp1, rc=rc) + ! check rc + call NUOPC_AddNestedState(importState, & + CplSet="Nest2", nestedStateName="NestedStateImp_N2", & + nestedState=NStateImp2, rc=rc) + ! check rc + + ! add nested export states with couple set identifier + call NUOPC_AddNestedState(exportState, & + CplSet="Nest1", nestedStateName="NestedStateExp_N1", & + nestedState=NStateExp1, rc=rc) + ! check rc + call NUOPC_AddNestedState(exportState, & + CplSet="Nest2", nestedStateName="NestedStateExp_N2", & + nestedState=NStateExp2, rc=rc) + ! check rc + + ! importable field: sea_surface_temperature + call NUOPC_Advertise(NStateImp1, & + StandardName="sea_surface_temperature", name="sst", rc=rc) + ! check rc + call NUOPC_Advertise(NStateImp2, & + StandardName="sea_surface_temperature", name="sst", rc=rc) + ! check rc + + ! exportable field: air_pressure_at_sea_level + call NUOPC_Advertise(NStateExp1, & + StandardName="air_pressure_at_sea_level", name="pmsl", rc=rc) + ! check rc + call NUOPC_Advertise(NStateExp2, & + StandardName="air_pressure_at_sea_level", name="pmsl", rc=rc) + ! check rc + + ! exportable field: surface_net_downward_shortwave_flux + call NUOPC_Advertise(NStateExp1, & + StandardName="surface_net_downward_shortwave_flux", name="rsns", rc=rc) + ! check rc + call NUOPC_Advertise(NStateExp2, & + StandardName="surface_net_downward_shortwave_flux", name="rsns", rc=rc) + ! check rc + + end subroutine ++ +
+Once the field pairing discussed in the previous sections is completed, each Connector component holds an attribute by the name of CplList. The CplList is a list type attribute with as many entries as there are fields for which the Connector component is responsible for connecting. The first part of each of these entries is always the StandardName of the associated field. See section 2.2 for a discussion of the NUOPC field dictionary and standard names. + +
+After the StandardName part, each CplList entry may optionally contain a string of connection options. Each Driver component has the chance as part of the label_ModifyInitializePhaseMap specialization, to modify the CplList attribute of all the Connectors that it drives. + +
+The individual connection options are colon separated, leading to the following format for each CplList entry: + +
+
+StandardName[:option1[:option2[: ...]] ++ +
+The format of the options is: + +
+
+OptionName=value1[=spec1][,value2[=spec2][, ...]] ++ +
+OptionName and the value strings are case insensitive. There are single and multi-valued options as indicated in the table below. For single valued options only value1 is relevant. If the same option is listed multiple times, only the first occurrence will be used. If an option has a default value, it is indicated in the table. If a value requires additional specification via =spec then the specifications are listed in the table. + +
+
OptionName | +Definition | +Type | +Values | +
dstMaskValues | +List of integer values that defines the mask values. | +multi | +List of integers. | +
dumpWeights | +Enable or disable dumping of the interpolation weights into a file. | +single | +true, false(default) | +
extrapDistExponent | +The exponent to raise the distance to when calculating weights for the nearest_idavg extrapolation method. | +single | +real(default 2.0) | +
extrapMethod | +Fill in points not mapped by the regrid method. | +single | +none(default), nearest_idavg, nearest_stod, nearest_d, creep, creep_nrst_d | +
extrapNumLevels | +The number of levels to output for the extrapolation methods that fill levels. When a method is used that requires this, then an error will be returned, if it is not specified. | +single | +integer | +
extrapNumSrcPnts | +The number of source points to use for the extrapolation methods that use more than one source point. | +single | +integer(default 8) | +
ignoreDegenerate | +Ignore degenerate cells when checking the input Grids or Meshes for errors. | +single | +true, false(default) | +
ignoreUnmatchedIndices | +Ignore unmatched sequence indices when redistributing between source and destination index space. | +single | +true, false(default) | +
pipelineDepth | +Maximum number of outstanding non-blocking communication calls during the parallel interpolation. Only relevant for cases where the automatic tuning procedure fails to find a setting that works well on a given hardware. | +single | +integer | +
poleMethod | +Extrapolation method around the pole(s). | +single | +none(default), allavg, npntavg="integer indicating number of points", teeth | +
remapMethod | +Redistribution or interpolation to compute the regridding weights. | +single | +redist, bilinear(default), patch, nearest_stod, nearest_dtos, conserve, conserve_2nd | +
srcMaskValues | +List of integer values that defines the mask values. | +multi | +List of integers. | +
srcTermProcessing | +Number of terms in each partial sum of the interpolation to process on the source side. This setting impacts the bit-for-bit reproducibility of the parallel interpolation results between runs. The strictest bit-for-bit setting is achieved by setting the value to 1. | +single | +integer | +
termOrder | +Order of the terms in each partial sum of the interpolation. This setting impacts the bit-for-bit reproducibility of the parallel interpolation results between runs. The strictest bit-for-bit setting is achieved by setting the value to srcseq. | +single | +free(default), srcseq, srcpet | +
unmappedAction | +The action to take when unmapped destination elements are encountered. | +single | +ignore(default), error | +
zeroRegion | +The region of destination elements set to zero before adding the result of the sparse matrix multiplication. The available options support total, selective, or no zeroing of destination elements. | +single | +total(default), select, empty | +
+For multi-model applications it is not uncommon that during start-up one or more components depends on data from one or more other components. These types of data-dependencies during initialize can become very complex very quickly. Finding the "correct" sequence to initialize all components for a complex dependency graph is not trivial. The NUOPC Layer deals with this issue by repeatedly looping over all components that indicate that their initialization has data dependencies on other components. The loop is finally exited when either all components have indicated completion of their initialization, or a dead-lock situation is being detected by the NUOPC Layer. + +
+The data-dependency resolution loop considers all components that have specialized label_DataInitialize. Participating components communicate their current status to the NUOPC Layer via Field and Component metadata. Every time a component's label_DataInitialize specialization routine is called, it is responsible for checking the Fields in the importState and for initializing any internal data structures and Fields in the exportState. Fields that are fully initialized in the exportState must be indicated by setting their Updated Attribute to "true". This is used by the NUOPC Layer to ensure that there is continued progress during the resolution loop iterations. Once the component is fully initialized it must further set its InitializeDataComplete Attribute to "true" before returning. + +
+During the execution of the data-dependency resolution loop the NUOPC Layer calls all of the Connectors to a Model/Mediator component before calling the component's label_DataInitialize. Doing so ensures that all the currently available Fields are passed to the component before it tries to access them. Once a component has set its InitializeDataComplete Attribute to "true", it, and the Connectors to it, will no longer be called during the remainder of the resolution loop. + +
+When all of the components that participate in the data-dependency resolution loop have set their InitializeDataComplete Attribute to "true", the NUOPC Layer successfully exits the data-dependency resolution loop. The loop is also interrupted before all InitializeDataComplete Attributes are set to "true" if a full cycle completes without any indicated progress. The NUOPC Layer flags this situation as a potential dead-lock and returns with error. + +
+There are modeling scenarios where the need arises to transfer physical grid information from one component to another. One common situation is that of modeling systems that utilize Mediator components to implement the interactions between Model components. In these cases the Mediator often carries out computations on a Model's native grid and performs regridding to the grid of other Model components. It is both cumbersome and error prone to recreate the Model grid in the Mediator. To solve this problem, NUOPC implements a transfer protocol for ESMF_Grid, ESMF_Mesh, and ESMF_LocStream objects (generally referred to as GeomObjects) between Model and/or Mediator components during initialization. + +
+The NUOPC Layer transfer protocol for GeomObjects is based on two Field attributes: TransferOfferGeomObject and TransferActionGeomObject. The TransferOfferGeomObject attribute is used by the Model and/or Mediator components to indicate for each Field their intent for the associated GeomObject. The predefined values of this attribute are: "will provide", "can provide", and "cannot provide". The TransferOfferGeomObject attribute must be set during label_Advertise. + +
+The generic Connector uses the intents from both sides and constructs a response according to the table below. The Connector's response is available during label_RealizeProvided. It sets the value of the TransferActionGeomObject attribute to either "provide" or "accept" on each Field. Fields indicating TransferActionGeomObject equal to "provide" must be realized on a Grid, Mesh, or LocStream object in the Model/Mediator before returning from label_RealizeProvided. + +
+Fields that hold "accept" for the value of the TransferActionGeomObject attribute require two additional negotiation steps. During label_AcceptTransfer the Model/Mediator component can access the transferred Grid/Mesh/LocStream on the Fields that have the "accept" value. However, only the DistGrid, i.e. the decomposition and distribution information of the Grid/Mesh/LocStream is available at this stage, not the full physical grid information such as the coordinates. At this stage the Model/Mediator may modify this information by replacing the DistGrid object in the Grid/Mesh/LocStream. The DistGrid that is set on the Grid/Mesh/LocStream objects when leaving the Model/Mediator phase label_AcceptTransfer will consequently be used by the generic Connector to fully transfer the Grid/Mesh/LocStream object. The fully transferred objects are available on the Fields with "accept" during Model/Mediator phase label_RealizeAccepted, where they are used to realize the respective Field objects. At this point all Field objects are fully realized and the initialization process can proceed as usual. + +
+The following table shows how the generic Connector sets the TransferActionGeomObject attribute on the Fields according to the incoming value of TransferOfferGeomObject. + +
+
TransferOfferGeomObject Incoming side A | +TransferOfferGeomObject Incoming side B | +Outgoing setting by generic Connector | +
"will provide" | +"will provide" | +A:TransferActionGeomObject="provide" B:TransferActionGeomObject="provide" | +
"will provide" | +"can provide" | +A:TransferActionGeomObject="provide" B:TransferActionGeomObject="accept" | +
"will provide" | +"cannot provide" | +A:TransferActionGeomObject="provide" B:TransferActionGeomObject="accept" | +
"can provide" | +"will provide" | +A:TransferActionGeomObject="accept" B:TransferActionGeomObject="provide" | +
"can provide" | +"can provide" | +if (A is import side) then
+ +A:TransferActionGeomObject="provide" B:TransferActionGeomObject="accept" + if (B is import side) then + +A:TransferActionGeomObject="accept" B:TransferActionGeomObject="provide" |
+
"can provide" | +"cannot provide" | +A:TransferActionGeomObject="provide" B:TransferActionGeomObject="accept" | +
"cannot provide" | +"will provide" | +A:TransferActionGeomObject="accept" B:TransferActionGeomObject="provide" | +
"cannot provide" | +"can provide" | +A:TransferActionGeomObject="accept" B:TransferActionGeomObject="provide" | +
"cannot provide" | +"cannot provide" | +Flagged as error! | +
+For coupling scenarios with a very high coupling frequency, or for situations where large data volumes are exchanged (e.g. 3D volumetric fields), it can be necessary for fields and geom objects (Grid, Mesh, and LocStreams) to share their data via references. Reference sharing greatly reduces the coupling cost compared to local or remote copies. + +
+In the current implementation, in order for NUOPC components to be coupled via reference sharing, they must only have data defined (i.e. have DEs) on PETs that are part of both components. Further, the distribution of data across the PETs must be identical for both components. If these conditions are met, and both sides of the connection indicate that they are willing to participate in reference sharing, the NUOPC Connector will handle technical details. The Connector will provide fields to the components that reference the exact same data allocations in memory. Notice however that once reference sharing is active, the NUOPC Layer cannot protect against components violating the data access conventions. Specifically fields in the importState are not to be modified by the component. Reference sharing requires a higher level of "trust" between the components. NUOPC therefore requires that both sides of a connection agree to reference sharing. + +
+A component uses the SharePolicyField and SharePolicyGeomObject attributes on each field to indicate whether it is willing to reference share the data of a field, and/or the geom object on which the field is built. A setting of share indicates a component's willingness to share, while not share indicates the opposite. The share policy attributes are automatically set when a field is advertised via the NUOPC_Advertise() method. By default this method sets both share policies to not share. + +
+When a Connector negotiates the connections between two components, it first considers the transfer offer attributes (i.e. TransferOfferGeomObject) on both sides for each field to determine the TransferActionGeomObject attribute for both side. The details of this protocol are outline in section 2.4.7. There are two cases to consider for each field that are relevant for reference sharing: + +
+The simple case is where the Connector determines that for a specific field both sides must provide the field and geom object. This is indicated by TransferActionGeomObject being set to provide on both sides. For this case the ShareStatusField and ShareStatusGeomObject attributes are automatically set to not shared for all the fields, preventing any reference sharing. + +
+The more interesting case is where one side of the connection receives the TransferActionGeomObject on a field set to provide, while the other side receives accept. In this case, the next step is for the Connector to take the SharePolicyField and SharePolicyGeomObject attributes on both sides into consideration. For each of the two attributes separately, if one side indicates not share, both sides will receive the associated ShareStatus set to not shared. However, if both sides of the connection indicate a SharePolicy of share, the Connector must further inspect the petLists to see if reference sharing is possible for the specific field. Under the current implementation a field is sharable with another component if all the PETs on which the field holds DEs are also in the other component's petList. If this condition is not met for the specific field, then the associated ShareStatus is set to not shared. Otherwise the ShareStatus is set to shared + +
+During later phases of the Initialization protocol the Connector performs different operations, depending on how the TransferActionGeomObject, ShareStatusField, and ShareStatusGeomObject attributes were set as per the above protocol: + +
+In some cases it is helpful for a NUOPC component to automatically mirror or match the set of fields advertised by another component. One purpose of this is to automatically resolve the import data dependencies of a component, by setting up a component that exactly provides all of the needed fields. This is currently used in the NUOPC Component Explorer: when driving a child NUOPC Model with required import fields, the Component Explorer uses the field mirroring capability to advertise in the driver-self export State the exact set of fields advertised in the child NUOPC Model. This ensures that the entire Initialize Phase Sequence will complete (because all dependencies are satisfied) and all phases can be exercised by the Component Explorer. + +
+The field mirror capability is also useful with NUOPC Mediators since these components often exactly reflect, in separate States, the sets of fields of each of the connected components. The field mirroring capability, therefore, can be used to ensure that a Mediator is always capable of accepting fields from connected components, and removes the need to specify field lists in multiple places, i.e., both within a set of Model components connected to a Mediator and within the Mediator itself. + +
+To access the field mirror capability, a component sets the FieldTransferPolicy attribute during label_Advertise. The attribute is set on the Import- and/or Export- States to trigger field mirroring for each state, respectively. The default value of "TransferNone" indicates that no fields should be mirrored. The other option, "TransferAll", indicates that fields should be mirrored in the State of a connected component. + +
+Each Connector consider the FieldTransferPolicy Attribute on both its import and export States. If both States have a FieldTransferPolicy of "TransferAll", then fields are transferred between the States in both directions (i.e., import to export and export to import). The transfer process works as follows: First, the TransferOfferGoemObject attribute is reversed between the providing side and accepting side. Intuitively, if a field from the providing component is to be mirrored and it can provide its own geometric object, then the mirrored field on the accepting side should be set to accept a geometric object. Then, the field to be mirrored is advertised in the accepting State using a call to NUOPC_Advertise() such that the mirrored field shares the same Standard Name. + +
+Components have the opportunity, using specialiozation point label_ModifyAdvertised, to modify any of the mirrored Fields in their Import/ExportState. After this the initialization sequence continues as usual. Since fields to be mirrored have been advertised with matching Standard Names, the field pairing algorithm will now match them in the usual way thereby establishing a connection between the original and mirrored fields. + +
+The NUOPC Layer associates an internal clock with three of its four generic component kinds: NUOPC_Driver, NUOPC_Model, and NUOPC_Mediator. The NUOPC_Connector is the only NUOPC component kind that does not have an internal clock object that is managed by NUOPC. + +
+The component internal clocks are implemented as ESMF_Clock objects. The interaction beween these clock objects between a parent component (driver) and its child components (models, mediators, and drivers) is defined by the NUOPC timekeeping behavior described below. + +
+For a simple run sequence with only a single coupling time-step, the driver clock sets the startTime, stopTime, and timeStep to be the beginning, the end, and the coupling period of the run, respectively. At the beginning of executing the run sequence, the driver clock currTime is set to its startTime. As the driver component executes the run sequence, it passes its clock to each child component that it executes. At the end of each full sweep through the run sequence the driver currTime is incremented by timeStep (i.e. the coupling period). This continues until the driver clock stopTime has been reached, and the run is complete. + +
+When a child component is being called during the execution of the driver run sequence, it receives the driver/parent clock. This access is read-only, and the child component is only allowed to inspect but not modify the parent clock. The child component is expected to run forward a single coupling period, i.e. one timeStep on the parent clock. Specifically this means that the currTime on the child clock must match the currTime on the parent clock. It then must take a single timeStep of the parent clock forward, using its own clock to do so. The child component can implement this forward step by taking multiple smaller advances on its own clock. + +
+The generic NUOPC component implementation provides the following assistance to implement the above described behavior: + +
+ +
+ +
+The NUOPC Layer supports component hierarchies. The key function to support this capability is the ability for a generic NUOPC_Driver to add another NUOPC_Driver component as a child, and to drive it much like a NUOPC_Model component. The interactions upward and downward the hierarchy tree are governed by the standard NUOPC component interaction protocols. + +
+In the current implementation, data-dependencies during initialization can be resolved throughout the entire component hierarchy. The implementation is based on a sweep algorithm that continues up and down the hierarchy until either all data-dependencies have been resolved, or a dead-lock situation has been detected and flagged. + +
+Along the downward direction, the interaction of a driver with its children allows the driver to mirror its child components' fields, and to transfer or share geom objects and fields up the component hierarchy. All of the interactions of a driver with its child components are handled by explicit NUOPC_Connector instances. These instances are automatically added by the driver when needed. + +
+The detailed behavior of a NUOPC_Driver component within a component hierarchy depends on the setting of the HierarchyProtocol attribute on the driver component itself. Section 2.3.1 lists all of the driver attributes defined by NUOPC. By default the HierarchyProtocol attribute is unset. For unset HierarchyProtocol or when set to PushUpAllExportsAndUnsatisfiedImports, the driver component pushes all the fields from its children exportStates into its own exportState, and all unsatisfied fields in its children importStates into its own importState. This is done using the standard Field Mirroring protocol discussed under 2.4.9. Further the driver sets the SharePolicyGeomObject, and +SharePolicyField to share for all the fields it mirrors. This triggers the reference share protocol as described in section 2.4.8. + +
+When the HierarchyProtocol is set to Explorer, the driver component still mirrors the fields from its child components' import- and exportStates, as was done for the default, however, the share policies will not be set. This protocol option is used by the NUOPC ComponentExplorer to connect to user provided components. + +
+Finally, for a setting of HierarchyProtocol to ConnectProvidedFields, the driver does not modify its own import- and exportState. Instead connections are made only between fields that have been added to the driver states externally. This is useful for the situation where a NUOPC_Driver component is called directly via ESMF component method from a level that is outside of NUOPC. In this situation, field and/or geom object sharing must be activated explicitly if desired. + +
+Each instance of a NUOPC component within an application is defined on a fixed set of compute resources. The association of resources occurs when the component is added to its parent component via the NUOPC_DriverAddComp() call. Subsequently when any of the component's Initialize, Run, or Finalize phases is called, the component code executes on the associated resources. + +
+The primary control of resource management under NUOPC is implemented through the petList argument that is accepted by NUOPC_DriverAddComp(). This argument holds a list of Persistent Execution Thread (PET) ids of the parent component on which the child component is to execute. By default, i.e. when petList is not specified, all of the parent PETs are associated with the added child component. Using custom petList constructions, a driver has control of exactly how its child components are sharing the available PET resources. + +
+Notice that the order of PETs listed in a petList is significant. The local PET labeling inside a child component always goes from 0 to size(petList)-1. The order in which the child PETs correspond to the parent PETs is that specified by the petList. It is erroneous to list the same parent PET multiple times in the same petList argument. + +
+For the following discussion it is convenient to think of PETs as simple MPI processes. While this is not strictly correct on a technically ESMF level, there are currently no features available to NUOPC where this interpretation would lead to inconsistencies. One of the key consequences of equating each PET to a simple MPI process is that each PET can only execute a single component's code at any given time. Therefore, in order to allow components to execute concurrently, a necessary condition is to define them on exclusive petLists. Of course the data dependencies between components must also support concurrent execution. Often this requires careful placement of Connectors in the run sequence and the introduction of time lags. However, this is more of a scientific than the resource control question covered in this section. + +
+Many model components today implement the hybrid MPI+OpenMP paradigm to support scalability to larger core counts than would be possible in a purely MPI or OpenMP approach. NUOPC supports hybrid MPI+OpenMP components in two ways: NUOPC aware and NUOPC unaware. In the NUOPC unaware approach, the application is launched only on those MPI ranks that are going to participate in the hybrid execution with OpenMP. Usually this means that the MPI launch system (mpirun, mpiexec, aprun, srun, etc.), and a set of environment variables get involved in correctly associating the desired number of hardware cores with each MPI process, and to assure correct affinities. In this approach NUOPC is not at all involved in the resource management, and OpenMP threading happens purely on the user level. + +
+The NUOPC unaware hybrid MPI+OpenMP approach provides a quick way to run hybrid applications that consist of a single model component, or where all of the model components use the same hybrid approach with the same ratio of OpenMP threads per MPI rank. In this case, shell-based user level resource control is often sufficient. However, for more complex coupling scenarios the NUOPC aware hybrid approach provides additional levels of control that are often needed to achieve optimal utilization of the available resources + +
+Under the NUOPC aware resource control, some components might be purely MPI based, while others use the hybrid approach. Different hybrid components can be configured to run with different threading levels. This is possible independent on whether the components use the same or exclusive sets of resources. + +
+Besides the already discussed petList argument, there are two additional optional arguments to NUOPC_DriverAddComp(). It is through those arguments that the advanced resource control features under NUOPC are implemented. One of these arguments is compSetVMRoutine. This argument allows the user to point to a specific public method of the child component. The signature of this method is the same as for the compSetServicesRoutine argument. If compSetVMRoutine is provided, it will be called before compSetServicesRoutine. The purpose of compSetVMRoutine is to allow the child component to set specific aspects of its own ESMF virtual machine (VM) before instantiating it. The ESMF reference manual discusses the details of this procedure under the "User-code SetVM method" section. Based on the information provided there, a user could implement a custom compSetVMRoutine method for a component. However, for convenience, NUOPC provides a generic implementation that can be passed into compSetVMRoutine. For most common situation, the generic implementation provided by NUOPC is sufficient, and there is no need for the user to provide a custom implementation of compSetVMRoutine. + +
+Utilizing the generic SetVM method provided by NUOPC involves a few steps. First, the component implementation must make the generic SetVM public inside its own cap module: + +
+
+module MODEL + + !----------------------------------------------------------------------------- + ! MODEL Component. + !----------------------------------------------------------------------------- + + use ESMF + use NUOPC + use NUOPC_Model, & + modelSS => SetServices + + implicit none + + private + + public SetVM, SetServices ! Here making SetVM and SetServices public. + + !----------------------------------------------------------------------------- + contains + !----------------------------------------------------------------------------- + ... +end module ++ +
+Second, the driver component that adds MODEL via NUOPC_DriverAddComp() as a child component, must make a USE association to the SetVM: + +
+
+module driver + + !----------------------------------------------------------------------------- + ! Code that specializes generic NUOPC_Driver + !----------------------------------------------------------------------------- + + use MPI + use ESMF + use NUOPC + use NUOPC_Driver, & + driverSS => SetServices + + use MODEL, only: & + modelSS => SetServices, & + modelSVM => SetVM ! Here making USE association to SetVM. + + implicit none + + private + + public SetServices + + !----------------------------------------------------------------------------- + contains + !----------------------------------------------------------------------------- + ... +end module ++ +
+Third, the driver can now pass the modelSVM into NUOPC_DriverAddComp() via the compSetVMRoutine argument, essentially providing the generic SetVM method. + +
+Finally, the generic SetVM implementation needs to be informed about the specific resource control request. This is handled through the other optional argument to NUOPC_DriverAddComp() alluded to earlier. This is the info argument. + +
+The info argument is of type(ESMF_Info), which implements a structured key/value pair class. An info object must first be created via ESMF_InfoCreate() before any key/value pairs can be set. + +
+
+ type(ESMF_Info) :: info + ... + info = ESMF_InfoCreate(rc=rc) + ! check rc ++ +
+NUOPC resource control is implemented under the /NUOPC/Hint/PePerPet structure. The following table documents the available keys under this structure, the supported values, and their meaning. Notice that structure and keys are case sensitive, while values are case insensitive. + +
+
+
+
+
key | +value | +Meaning | +
MaxCount | +Positive integer | +The maximum number of Processing Elements (PEs), i.e. cores or hardware threads, associated with each child PET. The procedure is this: the PEs associated with the incoming parent PETs (e.g. via petList), are grouped by single system image (SSI), i.e. shared memory domain or hardware node. Within each SSI the PEs are divided by the MaxCount to determine how many child PETs are needed for each SSI. The PEs on each SSI are then associated with the child PETs.
+
+ +Note that this procedure only then results in every child PET holding exactly MaxCount PEs when the number of PEs per SSI brought in by the parent PETs is a multiple of MaxCount. + + +Parent PETs that for the child VM gave up their PEs, and are not executing as child PETs, are paused for the duration of the child component execution. They resume execution under the parent VM once the child component returns control to the parent. |
+
OpenMpHandling | +String: none, set, init, or pin (the default) | +For "none", OpenMP handling is completely left to the user. In this case the user child component code will typically want to query the child VM for the local number of PEs under each child PET. This number then would be used in an explicit call to omp_set_num_threads() in order to set the OpenMP thread number according to the available PEs under each child PET.
+
+ +For "set", the NUOPC/ESMF layer make the call to omp_set_num_threads() under each child PET with the appropriate number of PEs. + + +For "init", the NUOPC/ESMF layers sets the number of OpenMP threads in each team, and triggers the instantiation of all the threads in the team. + + +For "pin", the NUOPC/ESMF layers sets the number of OpenMP threads in each team, triggers the instantiation of the team, and pins each OpenMP thread to the corresponding PE. |
+
OpenMpNumThreads | +Positive integer | +By default the "set", "init", or "pin" option under OpenMpHandling sets the number of OpenMP threads in each team equal to the number of PEs under each PET. Setting OpenMpNumThreads, this default can be overwritten. The option allows the user to under- or oversubscribe the PEs held by each PET. | +
ForceChildPthreads | +Logical: .true., or .false. (the default) | +By default (.false.) each PET executes under the same thread as its parent PET. Typically this means that PETs execute directly as the MPI process under which they were created. In some cases it is beneficial to create a separate Pthread for each child PET. This can be accomplished by setting the value to .true.. | +
PthreadMinStackSize | +Positive integer | +The minimum stack size in byte of each child PET that is executing as Pthread. By default child PETs do not execute as Pthreads. Therefore the stack size by default is equal to that of the parent PET. However, if ForceChildPthreads is set to true, all child PETs are instantiated as Pthreads. This means that the stack size cannot be unlimited. ESMF implements a default minimum stack size for child PETs of 20MiB. This minimum default can be changed (up or down) via the PthreadMinStackSize key.
+
+ +The system limit or ulimit commands can be used to further increase the stack size of child PETs. Any limit set lower than the PthreadMinStackSize, or set to unlimited, will result in usage of the PthreadMinStackSize if set, or the 20MiB default. + + +Note further that when OpenMP is used inside the child component, each child PET becomes the root thread of each of the OpenMP thread teams. It is therefore the root thread stack size that is affected by PthreadMinStackSize. The stack size of all the other OpenMP threads in each team is set via environment variable OMP_STACKSIZE as usual. |
+
+The following code snippet demonstrates a typical resource control request using the generic SetVM routine and an info object. This request is suitable for a hybrid MPI+OpenMP component where every child PET is expected to run 4-way OpenMP threaded. + +
+
+ call ESMF_InfoSet(info, key="/NUOPC/Hint/PePerPet/MaxCount", value=4, rc=rc) + ! check rc + call NUOPC_DriverAddComp(driver, "MODEL1", modelSS, modelSVM, info=info, rc=rc) + ! check rc ++ +
+A second child component can be created that uses the same parent resources as the first, but sets up 8-way OpenMP threading under each child PET. + +
+
+ call ESMF_InfoSet(info, key="/NUOPC/Hint/PePerPet/MaxCount", value=8, rc=rc) + ! check rc + call NUOPC_DriverAddComp(driver, "MODEL2", modelSS, modelSVM, info=info, rc=rc) + ! check rc ++ +
+If the default settings for some of the keys are not appropriate, they can be set explicitly. Here for instance a child component with the same number of PETs as the previous 4-way OpenMP threaded case is created, but is instructed to not handle any of the OpenMP aspects. + +
+
+ call ESMF_InfoSet(info, key="/NUOPC/Hint/PePerPet/MaxCount", value=4, rc=rc) + ! check rc + call ESMF_InfoSet(info, key="/NUOPC/Hint/PePerPet/OpenMpHandling", & + value="none", rc=rc) + ! check rc + call NUOPC_DriverAddComp(driver, "MODEL3", modelSS, modelSVM, info=info, rc=rc) + ! check rc ++ +
+In this example, all three child components "MODEL1", "MODEL2", and "MODEL3" use the exact same parent resources. Due to this fact all three components can only execute sequentially. However, each child component manages the resources provided by the parent differently, and independently. Through this tailored approach, NUOPC allows optimal use of the available resources by each component. NUOPC_Connector components defined between components work as usual, taking care of all the required data movements automatically and completely transparent to the user. + +
+In order to obtain best performance when using NUOPC aware resource control for hybrid parallelism, it is strongly recommended to set OMP_WAIT_POLICY=PASSIVE in the environment. This is one of the standard OpenMP environment variables. The PASSIVE setting ensures that OpenMP threads relinquish the hardware threads (i.e. cores) as soon as they have completed their work. Without that setting ESMF resource control threads can be delayed, and context switching between components becomes more expensive. + +
+Complete applications can easily be built by assembling NUOPC compliant components. Many such NUOPC applications are in productive use across several institutions. The top level of such applications is typically implemented via a very thin application layer holding the main program that calls into the top level driver component that derives from NUOPC_Driver. Model components sit under the top level driver, interacting with one another and the driver through the NUOPC protocols. Complex systems have one or more component hierarchy levels under the top level driver as discussed in the previous section. + +
+There are situation, however, where a NUOPC application needs to be controlled by an outside component. Such an outside component does not derive from any of the generic NUOPC components, and cannot be expected to implement the complete NUOPC protocol. Typically such an external component implements its own control structure outside of NUOPC and ESMF. One example of such a situation are data assimilation systems that want to drive a NUOPC forecast application. + +
+In order to facilitate the external access into a NUOPC application, the NUOPC_Driver provides an external interface. This interface is implemented through the standard ESMF component methods: Initialize, Run, and Finalize. This interface with the top level NUOPC driver allows an external component to control and interact with the entire NUOPC application. + +
+The standard ESMF component interfaces hold importState, exportState, and a clock argument. These arguments are used to pass data in and out of the NUOPC application, and control the time stepping of the NUOPC model, respectively. The top level driver of a NUOPC application has access to any field that is advertised by any of the components and therefore serves as a single point of access for the entire application. + +
+The external NUOPC interface is currently defined by the Initialize, Run, and Finalize phases documented in the following table. + +
+
+
+
+
methodFlag | +phaseLabel | +Meaning | +
ESMF_METHOD_INITIALIZE | +label_ExternalAdvertise | +Called after the external component has + set up the import- and exportStates with + fields (advertised) that it plans to interact with. + On the NUOPC application side this call will + got through the complete advertise cylce. | +
ESMF_METHOD_INITIALIZE | +label_ExternalRealize | +Called after the external component has + been informed about the connected status of + the fields in the import- and exportState. + On the NUOPC application side this call will + finish setting up RouteHandles between all + components involved. | +
ESMF_METHOD_INITIALIZE | +label_ExternalDataInit | +Trigger a complete data initialize throughout + the NUOPC application. The expectation is that + all components reset their data consistent with + the clock argument. | +
ESMF_METHOD_RUN | ++ | The default Run() method steps the NUOPC + application forward in time according to + the clock argument. | +
ESMF_METHOD_FINALIZE | +label_ExternalReset | +Inform the NUOPC application about a clock + reset. | +
ESMF_METHOD_FINALIZE | ++ | Completely finalize and shut down the NUOPC application. | +
+Here methodFlag and phaseLabel corrsepond to the respective arguments of method NUOPC_CompSearchPhaseMap(). This method is used to determine the actual ESMF phase index needed when calling into ESMF_GridCompInitialize(), ESMF_GridCompRun(), or ESMF_GridCompFinalize(). In cases where no phaseLabel is indicated, the default phase is used for the implementation, accessible by not specifying the argument. + +
+For a complete example of how the External NUOPC API is used in practice, see https://github.com/esmf-org/nuopc-app-prototypes/tree/develop/ExternalDriverAPIProto. The following code snippets demonstrates the critical pieces of code from the external layer interacting with NUOPC/ESMF. + +
+
+ ! Create the external level import/export States + ! NOTE: The "stateintent" must be specified, and it must be set from the + ! perspective of the external level: + ! -> state holding fields exported by the external level to the ESM component + externalExportState = ESMF_StateCreate(stateintent=ESMF_STATEINTENT_EXPORT, rc=rc) + ! check rc + ! -> state holding fields imported by the external level from the ESM component + externalImportState = ESMF_StateCreate(stateintent=ESMF_STATEINTENT_IMPORT, rc=rc) + ! check rc + + ! Advertise field(s) in external import state to receive from the NUOPC layer + call NUOPC_Advertise(externalImportState, & + StandardNames=(/"sea_surface_temperature"/), & + TransferOfferGeomObject="cannot provide", SharePolicyField="share", rc=rc) + ! check rc + + ! Call "ExternalAdvertise" Initialize for the earth system Component + call NUOPC_CompSearchPhaseMap(nuopcApp, methodflag=ESMF_METHOD_INITIALIZE, & + phaseLabel=label_ExternalAdvertise, phaseIndex=phase, rc=rc) + ! check rc + call ESMF_GridCompInitialize(nuopcApp, phase=phase, clock=clock, & + importState=externalExportState, exportState=externalImportState, userRc=urc, rc=rc) + ! check rc and urc + + ! Call "ExternalRealize" Initialize for the earth system Component + call NUOPC_CompSearchPhaseMap(nuopcApp, methodflag=ESMF_METHOD_INITIALIZE, & + phaseLabel=label_ExternalRealize, phaseIndex=phase, rc=rc) + ! check rc + call ESMF_GridCompInitialize(nuopcApp, phase=phase, clock=clock, & + importState=externalExportState, exportState=externalImportState, userRc=urc, rc=rc) + ! check rc and urc + + ! Call "ExternalDataInit" Initialize for the earth system Component + call NUOPC_CompSearchPhaseMap(nuopcApp, methodflag=ESMF_METHOD_INITIALIZE, & + phaseLabel=label_ExternalDataInit, phaseIndex=phase, rc=rc) + ! check rc + call ESMF_GridCompInitialize(nuopcApp, phase=phase, clock=clock, & + importState=externalExportState, exportState=externalImportState, userRc=urc, rc=rc) + ! check rc and urc + + ! Explicit time stepping loop on the external level, here based on ESMF_Clock + do while (.not.ESMF_ClockIsStopTime(clock, rc=rc)) + ! Run the earth system Component: i.e. step ESM forward by timestep + call ESMF_GridCompRun(nuopcApp, clock=clock, & + importState=externalExportState, exportState=externalImportState, userRc=urc, rc=rc) + ! check rc and urc + ! Advance the clock + call ESMF_ClockAdvance(clock, rc=rc) + ! check rc + end do + + ! Finalize the earth system Component + call ESMF_GridCompFinalize(nuopcApp, clock=clock, & + importState=externalExportState, exportState=externalImportState, userRc=urc, rc=rc) + ! check rc and urc ++ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node4.html b/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node4.html new file mode 100644 index 000000000..4242c06e3 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node4.html @@ -0,0 +1,7727 @@ + + + + + ++ +
+ +
+ +
+
+MODULE:
+
module NUOPC_Driver ++ +
+ +
+
+DESCRIPTION:
+
+Component that drives and coordinates initialization of its child components: Model, Mediator, and Connector components. For every Driver time step the same run sequence, i.e. sequence of Model, Mediator, and Connector Run methods is called. The run sequence is fully customizable. The default run sequence implements explicit time stepping.
+
+
+ +
+
+SUPER:
+
ESMF_GridComp ++ +
+ +
+
+USE DEPENDENCIES:
+
use ESMF ++ +
+ +
+
+SETSERVICES:
+
subroutine SetServices(driver, rc) + type(ESMF_GridComp) :: driver + integer, intent(out) :: rc ++ +
+ +
+
+SEMANTIC SPECIALIZATION LABELS:
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverAddComp() + recursive subroutine NUOPC_DriverAddGridComp(driver, compLabel, & + compSetServicesRoutine, compSetVMRoutine, petList, devList, info, config, & + hconfig, comp, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + character(len=*), intent(in) :: compLabel + #if defined (__NVCOMPILER) || defined (__PGI) || defined (ESMF_COMPILER_AOCC) + interface + recursive subroutine compSetServicesRoutine(gridcomp, rc) + use ESMF + implicit none + type(ESMF_GridComp) :: gridcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + interface + recursive subroutine compSetVMRoutine(gridcomp, rc) + use ESMF + implicit none + type(ESMF_GridComp) :: gridcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + optional :: compSetVMRoutine + #else + abstract interface + recursive subroutine SetServicesRoutine(gridcomp, rc) + use ESMF + implicit none + type(ESMF_GridComp) :: gridcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + recursive subroutine SetVMRoutine(gridcomp, rc) + use ESMF + implicit none + type(ESMF_GridComp) :: gridcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + procedure(SetServicesRoutine) :: compSetServicesRoutine + procedure(SetVMRoutine), optional :: compSetVMRoutine + #endif + integer, intent(in), optional :: petList(:) + integer, intent(in), optional :: devList(:) + type(ESMF_Info), intent(in), optional :: info + type(ESMF_Config), intent(in), optional :: config + type(ESMF_HConfig), intent(in), optional :: hconfig + type(ESMF_GridComp), intent(out), optional :: comp + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create and add a GridComp (i.e. Model, Mediator, or Driver) as a child + component to a Driver. The component is created on the provided petList, + or by default across all of the Driver PETs. + +
+The specified compSetServicesRoutine() is called back immediately after + the new child component has been created internally. + Very little around the component is set up at that time (e.g. NUOPC component + attributes are not yet available at this stage). The routine should therefore + be very light weight, with the sole purpose of setting the entry points of + the component - typically by deriving from a generic component followed by + the appropriate specilizations. + +
+If provided, the compSetVMRoutine() is called back before the + compSetServicesRoutine(). This allows the child component to set + aspects of its own VM, such as threading or the PE distribution among PETs. + +
+The info argument can be used to pass custom attributes to the child + component. These attributes are available on the component when + compSetVMRoutine() and compSetServicesRoutine() are called. + The attributes provided in info are copied onto the child + component. This allows the same info object to be used for multiple + child components without conflict. + +
+The compLabel must uniquely identify the child component within the + context of the Driver component. + +
+If the comp argument is specified, it will reference the newly created + component on return. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverAddComp() + recursive subroutine NUOPC_DriverAddGridCompSO(driver, compLabel, & + sharedObj, petList, devList, info, config, hconfig, comp, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + character(len=*), intent(in) :: compLabel + character(len=*), intent(in), optional :: sharedObj + integer, intent(in), optional :: petList(:) + integer, intent(in), optional :: devList(:) + type(ESMF_Info), intent(in), optional :: info + type(ESMF_Config), intent(in), optional :: config + type(ESMF_HConfig), intent(in), optional :: hconfig + type(ESMF_GridComp), intent(out), optional :: comp + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create and add a GridComp (i.e. Model, Mediator, or Driver) as a child + component to a Driver. The component is created on the provided petList, + or by default across all of the Driver PETs. + +
+The SetVM() and SetServices() routines in sharedObj + are called back immediately after the new child component has been created + internally. + Very little around the component is set up at that time (e.g. NUOPC component + attributes are not yet available at this stage). The routine should therefore + be very light weight, with the sole purpose of setting the entry points of + the component - typically by deriving from a generic component followed by + the appropriate specilizations. + +
+The asterisk character (*) is supported as a wildcard for the + file name suffix in sharedObj. When present, the asterisk is replaced + by "so", "dylib", and "dll", in this order, and the first successfully + loaded object is used. If the sharedObj argument is not provided, the + executable itself is searched for the "SetVM" and "SetServices" + symbols. + +
+The info argument can be used to pass custom attributes to the child + component. These attributes are available on the component when + compSetVMRoutine() and compSetServicesRoutine() are called. + The attributes provided in info are copied onto the child + component. This allows the same info object to be used for multiple + child components without conflict. + +
+The compLabel must uniquely identify the child component within the + context of the Driver component. + +
+If the comp argument is specified, it will reference the newly created + component on return. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverAddComp() + recursive subroutine NUOPC_DriverAddCplComp(driver, srcCompLabel, & + dstCompLabel, compSetServicesRoutine, compSetVMRoutine, petList, devList, & + info, config, hconfig, comp, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + character(len=*), intent(in) :: srcCompLabel + character(len=*), intent(in) :: dstCompLabel + #if defined (__NVCOMPILER) || defined (__PGI) || defined (ESMF_COMPILER_AOCC) + interface + recursive subroutine compSetServicesRoutine(cplcomp, rc) + use ESMF + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + interface + recursive subroutine compSetVMRoutine(cplcomp, rc) + use ESMF + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + optional :: compSetVMRoutine + #else + abstract interface + recursive subroutine SetServicesRoutine(cplcomp, rc) + use ESMF + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + recursive subroutine SetVMRoutine(cplcomp, rc) + use ESMF + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + procedure(SetServicesRoutine) :: compSetServicesRoutine + procedure(SetVMRoutine), optional :: compSetVMRoutine + #endif + integer, target, intent(in), optional :: petList(:) + integer, target, intent(in), optional :: devList(:) + type(ESMF_Info), intent(in), optional :: info + type(ESMF_Config), intent(in), optional :: config + type(ESMF_HConfig), intent(in), optional :: hconfig + type(ESMF_CplComp), intent(out), optional :: comp + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create and add a CplComp (i.e. Connector) as a child component to a Driver. + The component is created on the provided petList, or by default across + the union of PETs of the components indicated by srcCompLabel + and dstCompLabel. + +
+The specified SetServices() routine is called back immediately after the + new child component has been created internally. + Very little around the component is set up at that time (e.g. NUOPC component + attributes are not yet available at this stage). The routine should therefore + be very light weight, with the sole purpose of setting the entry points of + the component - typically by deriving from a generic component followed by + the appropriate specilizations. + +
+The info argument can be used to pass custom attributes to the child + component. These attributes are available on the component when + compSetVMRoutine() and compSetServicesRoutine() are called. + The attributes provided in info are copied onto the child + component. This allows the same info object to be used for multiple + child components without conflict. + +
+The compLabel must uniquely identify the child component within the + context of the Driver component. + +
+If the comp argument is specified, it will reference the newly created + component on return. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverAddRunElement() + recursive subroutine NUOPC_DriverAddRunElementMPL(driver, slot, compLabel, & + phaseLabel, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + integer, intent(in) :: slot + character(len=*), intent(in) :: compLabel + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: phaseLabel + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add an element associated with a Model, Mediator, or Driver component to the + run sequence of the Driver. The component must have been added to the Driver, + and associated with compLabel prior to this call. + +
+If phaseLabel was not specified, the first entry in the + RunPhaseMap attribute of the referenced component will be used to + determine the run phase of the added element. + +
+By default an error is returned if no component is associated with the + specified compLabel. This error can be suppressed by setting + relaxedflag=.true., and no entry will be added to the run sequence. + +
+The slot number identifies the run sequence time slot in case multiple + sequences are available. Slots start counting from 1. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverAddRunElement() + recursive subroutine NUOPC_DriverAddRunElementCPL(driver, slot, srcCompLabel,& + dstCompLabel, phaseLabel, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + integer, intent(in) :: slot + character(len=*), intent(in) :: srcCompLabel + character(len=*), intent(in) :: dstCompLabel + -- The following arguments require argument keyword syntax (e.g. rc=rc). -- + character(len=*), intent(in), optional :: phaseLabel + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add an element associated with a Connector component to the + run sequence of the Driver. The component must have been added to the Driver, + and associated with srcCompLabel and dstCompLabel prior to this + call. + +
+If phaseLabel was not specified, the first entry in the + RunPhaseMap attribute of the referenced component will be used to + determine the run phase of the added element. + +
+By default an error is returned if no component is associated with the + specified compLabel. This error can be suppressed by setting + relaxedflag=.true., and no entry will be added to the run sequence. + +
+The slot number identifies the run sequence time slot in case multiple + sequences are available. Slots start counting from 1. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverAddRunElement() + recursive subroutine NUOPC_DriverAddRunElementL(driver, slot, linkSlot, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + integer, intent(in) :: slot + integer, intent(in) :: linkSlot + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add an element to the run sequence of the Driver that links to the time slot + indicated by linkSlot. + +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine NUOPC_DriverEgestRunSequence(driver, freeFormat, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + type(NUOPC_FreeFormat), intent(out) :: freeFormat + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Egest the run sequence stored in the driver as a FreeFormat object. It is the + caller's responsibility to destroy the created freeFormat object. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverGet() + recursive subroutine NUOPC_DriverGet(driver, slotCount, parentClock, & + importState, exportState, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + integer, intent(out), optional :: slotCount + type(ESMF_Clock), intent(out), optional :: parentClock + type(ESMF_State), intent(out), optional :: importState + type(ESMF_State), intent(out), optional :: exportState + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access Driver information. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverGetComp() + recursive subroutine NUOPC_DriverGetGridComp(driver, compLabel, comp, petList, & + importState, exportState, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + character(len=*), intent(in) :: compLabel + type(ESMF_GridComp), intent(out), optional :: comp + integer, pointer, optional :: petList(:) + type(ESMF_State), intent(out), optional :: importState + type(ESMF_State), intent(out), optional :: exportState + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Query the Driver for a GridComp (i.e. Model, Mediator, or Driver) child + component that was added under compLabel. + +
+If provided, the petList argument will be associated with the petList + that was used to create the referenced component. This is an internal + allocation owned by the library. This pointer must not be deallocated + by the user! + +
+By default an error is returned if no component is associated with the + specified compLabel. This error can be suppressed by setting + relaxedflag=.true., and unassociated arguments will be returned. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverGetComp() + recursive subroutine NUOPC_DriverGetCplComp(driver, srcCompLabel, & + dstCompLabel, comp, petList, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + character(len=*), intent(in) :: srcCompLabel + character(len=*), intent(in) :: dstCompLabel + type(ESMF_CplComp), intent(out), optional :: comp + integer, pointer , optional :: petList(:) + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Query the Driver for a CplComp (i.e. Connector) child + component that was added under compLabel. + +
+If provided, the petList argument will be associated with the petList + that was used to create the referenced component. This is an internal + allocation owned by the library. This pointer must not be deallocated + by the user! + +
+By default an error is returned if no component is associated with the + specified compLabel. This error can be suppressed by setting + relaxedflag=.true., and unassociated arguments will be returned. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverGetComp() + recursive subroutine NUOPC_DriverGetAllGridComp(driver, compList, petLists, & + rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + type(ESMF_GridComp), pointer, optional :: compList(:) + type(ESMF_PtrInt1D), pointer, optional :: petLists(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get all the GridComp (i.e. Model, Mediator, or Driver) child components from a + Driver. + +
+The incoming compList and petLists arguments must enter + unassociated. This means that the user code must explicitly call + nullify() or use the => null() syntax on the variables passed in + as the actual arguments. + +
+On return it becomes the responsibility of the caller to deallocate + associated compList and petLists arguments: +
+ if (associated(compList)) deallocate(compList) + if (associated(petLists)) deallocate(petLists) ++ +
+Notice that the petLists(i)%ptr members, if associated, are pointing to + an internal allocation owned by the library. These pointers must not be + deallocated by the user! + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverGetComp() + recursive subroutine NUOPC_DriverGetAllCplComp(driver, compList, petLists, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + type(ESMF_CplComp), pointer :: compList(:) + type(ESMF_PtrInt1D), pointer, optional :: petLists(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get all the CplComp (i.e. Connector) child components from a Driver. + +
+The incoming compList and petLists arguments must enter + unassociated. This means that the user code must explicitly call + nullify() or use the => null() syntax on the variables passed in + as the actual arguments. + +
+On return it becomes the responsibility of the caller to deallocate + associated compList and petLists arguments: +
+ if (associated(compList)) deallocate(compList) + if (associated(petLists)) deallocate(petLists) ++ +
+Notice that the petLists(i)%ptr members, if associated, are pointing to + an internal allocation owned by the library. These pointers must not be + deallocated by the user! + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverIngestRunSequence() + recursive subroutine NUOPC_DriverIngestRunSequenceFF(driver, freeFormat, & + autoAddConnectors, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + type(NUOPC_FreeFormat), intent(in), target :: freeFormat + logical, intent(in), optional :: autoAddConnectors + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Ingest the run sequence from a FreeFormat object and replace the + run sequence currently held by the driver. Every line in + freeFormat corresponds to either a component run sequence element, or + is part of a time loop or alarm block defintion. Anything following a + '#' character on a line is considered a comment, and ignored for the purpose + of ingesting run sequence elements. + +
+Component run sequence elements define the run method of a single + component. The lines are interpreted sequentially, however, components + will execute concurrently as long as this is not prevented by + data-dependencies or overlapping petLists. + +
+Each line specifies the precise run method phase for a single component + instance. For model, mediator, and driver components the format is this: + +
+
+ compLabel [phaseLabel] ++ Here compLabel is the label by which the component instance is known to + the driver. It is optionally followed a phaseLabel identifying a + specific run phase. An example of calling the run phase of the ATM instance + that contains the "fast" processes, and is labeled fast: + +
+
+ ATM fast ++ By default, i.e. without phaseLabel, the first + registered run method of the component is used. + +
+The format for connector components is different. It looks like this: + +
+
+ srcCompLabel -> dstCompLabel [connectionOptions] ++ A connector instance is uniquely known by the two components it connects, + i.e. by srcCompLabel and dstCompLabel. The syntax requires that + the token -> be specified between source and destination. Optionally + connectionOptions can be supplied using the format discussed + under section 2.4.5. The connection options are set + as attribute ConnectionOptions on the respective connector component. + +
+An example of executing the connector + instance that transfers fields from the ATM component to the OCN component, + using redistribution for remapping: + +
+
+ ATM -> OCN :remapMethod=redist ++ +
+By default autoAddConnectors is .false., which means that all + components referenced in the freeFormat run sequence, including + connectors, must already be available as child components of the driver + component. An error will be returned if this is not the case. + However, when autoAddConnectors is set to .true., connector + components encountered in the run sequence that are no already present in + the driver will be added automatically. The default + NUOPC_Connector implementation is used for all automatically added + connector instances. + +
+Lines that contain a time loop definition have the general format: + +
+
+ @{timeStep|*}[:runDuration] + ... + ... + @ ++ Both timeStep and runDuration are numbers in units of seconds. + Time loops can be nested and concatenated. + +
+A wildcard "*" character can be specified in place of an actual timeStep + number. In this case the timeStep of the associated run clock object + is set to be equal to the timeStep of the time loop one level up in the + loop nesting hierarchy. + If a wildcard time step is used for a single outer time loop in the run + sequence, then the associated run clock is identical to the driver clock and + must be set explicitly by the driver code, or its parent component. + +
+The runDuration specification is optional. If omitted, the duration of + the associated run clock is set to the timeStep of the time loop one + level up in the loop nesting hierarchy. This ensures that for a single + nested time loop, the loop returns to the parent loop level at the appropriate + time. + +
+A simple example of a single time loop with one hour timestep: + +
+
+ @3600 + ... + ... + @ ++ Each time loop has its own associated clock object. NUOPC manages these clock + objects, i.e. their creation and destruction, as well as startTime, + endTime, timeStep adjustments during the execution. The outer + most time loop of the run sequence is a special case. It uses the driver + clock itself. If a single outer most loop is defined in the run sequence + provided by freeFormat, this loop becomes the driver loop level + directly. Therefore, setting the timeStep or runDuration for + the outer most time loop results modifiying the driver clock itself. + However, for cases with concatenated loops on the upper level of + the run sequence in freeFormat, a single outer loop is added + automatically during ingestion, and the driver clock is used for this loop + instead. + +
+A more complex run sequence example, that shows component run + sequence elements outside of time loops, a nested time loop, time step + wildcards, explicit duration specifications, and concatenated time loops: + +
+
+ @100:800 + ATM -> OCN + OCN -> ATM + ATM + OCN + @* + OCN -> EXTOCN + EXTOCN + @ + @ + ATM -> EXTATM + EXTATM + @100:1000 + ATM -> OCN + OCN -> ATM + ATM + OCN + @ ++ Here the timeStep of the first time loop is explicitly chosen at + . The runDuration is explicitly set to . The first time + loop steps the current time forward for , for each iteration executing + ATM-OCN coupling, followed by the nested loop that calls the + OCN -> EXTOCN and EXTOCN components. The nested loop uses a + wildcard timeStep and therefore is + identical to the parent loop level timeStep of . The nested + runDuration is not specified and therefore also defaults to the parent + time step of . In other words, the nested loop is executed exactly once + for every parent loop iteration. + +
+After the first time loop is exited, and followed by explicit calls to + ATM -> EXTAMT and EXTATM components. Finally the second time loop + is entered for another runDuration. The timeStep is again + explicitly set to . The second time loop only implements ATM-OCN + coupling, and no coupling to EXTOCN is implemented. Finally, after + the sequence returns to the driver level loop. + +
+Lines that contain an alarm block definition have the general format: + +
+
+ @@{alarmTime|*} + ... + ... + @@ ++ The alarmTime is a number in units of seconds, and indicates at which + interval the alarm will ring. The first ring time of an alarm is the current + time of the parent clock. + +
+Specification of the wildcard character * sets the alarmTime equal to + the timeStep of the parentClock. + +
+When an alarm rings, the entire alarm block is executed once. + +
+Nesting of time loops and alarm blocks is supported. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverIngestRunSequence() + recursive subroutine NUOPC_DriverIngestRunSequenceHC(driver, hconfig, & + autoAddConnectors, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + type(ESMF_HConfig), intent(in) :: hconfig + logical, intent(in), optional :: autoAddConnectors + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Ingest the run sequence from a HConfig object and replace the run sequence + currently held by the driver. The provided hconfig must be a scalar, + or else an error is returned. The scalar is interpreted as a string, broken + into lines at the newline character. Each line is subsequently + interpreted according to the rules described under the FreeFormat version of + the NUOPC_DriverIngestRunSequence() interface. + +
+To preserve newline characters in run sequences expressed in YAML + block notation, it is important to use literals indicated by the + '|' character in YAML. For example: + +
+
+ # A simple run sequence example as a YAML block literal + --- | + @900:1800 # comments are ignored + MED + MED -> ATM # any line can have a comment + MED -> OCN + ATM + OCN + ATM -> MED + OCN -> MED + @ ++ +
+Notice the leading whitespace character(s) on each line of the block + literal string. YAML requires at least one (1) leading whitespace + character for strings in block notation. + +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine NUOPC_DriverNewRunSequence(driver, slotCount, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + integer, intent(in) :: slotCount + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Replace the current run sequence of the Driver with a new one that has + slotCount slots. Each slot uses its own clock for time keeping. + +
+ +
+ +
+ +
+
+INTERFACE:
+
recursive subroutine NUOPC_DriverPrint(driver, orderflag, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + logical, intent(in), optional :: orderflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Print internal Driver information. If orderflag is provided and set + to .true., the output is ordered from lowest to highest PET. Setting + this flag makes the method collective. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_DriverSetRunSequence() + recursive subroutine NUOPC_DriverSetRunSequence(driver, slot, clock, alarm, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: driver + integer, intent(in) :: slot + type(ESMF_Clock), intent(in) :: clock + type(ESMF_Alarm), intent(in), optional :: alarm + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the clock in the run sequence under slot of the Driver. + + +
+ +
+ +
+ +
+
+MODULE:
+
module NUOPC_ModelBase ++ +
+ +
+
+DESCRIPTION:
+
+Partial specialization of a component with a default explicit time dependency. Each time the Run method is called the component steps one timeStep forward on the passed in parent
+clock. The component flags incompatibility during Run if the current time of the incoming
+clock does not match the current time of the internal clock.
+
+
+ +
+
+SUPER:
+
ESMF_GridComp ++ +
+ +
+
+USE DEPENDENCIES:
+
use ESMF ++ +
+ +
+
+SETSERVICES:
+
subroutine SetServices(modelBase, rc) + type(ESMF_GridComp) :: modelBase + integer, intent(out) :: rc ++ +
+ +
+
+SEMANTIC SPECIALIZATION LABELS:
+
+
+ +
+ +
+ +
+ +
+ +
+
+MODULE:
+
module NUOPC_Model ++ +
+ +
+
+DESCRIPTION:
+
+Model component with a default explicit time dependency. Each time the Run method is called the model integrates one timeStep forward on the passed in parent clock. The internal clock is advanced at the end of each Run call. The component flags incompatibility during Run if the current time of the incoming clock does not match the current time of the internal clock.
+
+
+ +
+
+SUPER:
+
NUOPC_ModelBase ++ +
+ +
+
+USE DEPENDENCIES:
+
use ESMF ++ +
+ +
+
+SETSERVICES:
+
subroutine SetServices(model, rc) + type(ESMF_GridComp) :: model + integer, intent(out) :: rc ++ +
+ +
+
+SEMANTIC SPECIALIZATION LABELS:
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_ModelGet(model, driverClock, modelClock, & + importState, exportState, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: model + type(ESMF_Clock), intent(out), optional :: driverClock + type(ESMF_Clock), intent(out), optional :: modelClock + type(ESMF_State), intent(out), optional :: importState + type(ESMF_State), intent(out), optional :: exportState + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access Model information. + + +
+ +
+ +
+ +
+
+MODULE:
+
module NUOPC_Mediator ++ +
+ +
+
+DESCRIPTION:
+
+Mediator component with a default explicit time dependency. Each time the Run method is called, the time stamp on the imported Fields must match the current time (on both the incoming and internal clock). Before returning, the Mediator time stamps the exported Fields with the same current time, before advancing the internal clock one timeStep forward.
+
+
+ +
+
+SUPER:
+
NUOPC_ModelBase ++ +
+ +
+
+USE DEPENDENCIES:
+
use ESMF ++ +
+ +
+
+SETSERVICES:
+
subroutine SetServices(mediator, rc) + type(ESMF_GridComp) :: mediator + integer, intent(out) :: rc ++ +
+ +
+
+SEMANTIC SPECIALIZATION LABELS:
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_MediatorGet(mediator, driverClock, mediatorClock, & + importState, exportState, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: mediator + type(ESMF_Clock), intent(out), optional :: driverClock + type(ESMF_Clock), intent(out), optional :: mediatorClock + type(ESMF_State), intent(out), optional :: importState + type(ESMF_State), intent(out), optional :: exportState + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access Mediator information. + + +
+ +
+ +
+ +
+
+MODULE:
+
module NUOPC_Connector ++ +
+ +
+
+DESCRIPTION:
+
+Component that makes a unidirectional connection between model, mediator, and or driver components. During initialization field pairing is performed between the import and export side according to section 2.4.2, and paired fields are connected. By default the bilinear regrid method is used during Run to transfer data from the connected import Fields to the connected export Fields.
+
+
+ +
+
+SUPER:
+
ESMF_CplComp ++ +
+ +
+
+USE DEPENDENCIES:
+
use ESMF ++ +
+ +
+
+SETSERVICES:
+
subroutine SetServices(connector, rc) + type(ESMF_CplComp) :: connector + integer, intent(out) :: rc ++ +
+ +
+
+SEMANTIC SPECIALIZATION LABELS:
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_ConnectorGet(connector, srcFields, dstFields, rh, state, & + CplSet, cplSetList, srcVM, dstVM, driverClock, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: connector + type(ESMF_FieldBundle), intent(out), optional :: srcFields + type(ESMF_FieldBundle), intent(out), optional :: dstFields + type(ESMF_RouteHandle), intent(out), optional :: rh + type(ESMF_State), intent(out), optional :: state + character(*), intent(in), optional :: CplSet + character(ESMF_MAXSTR), pointer, optional :: cplSetList(:) + type(ESMF_VM), intent(out), optional :: srcVM + type(ESMF_VM), intent(out), optional :: dstVM + type(ESMF_Clock), intent(out), optional :: driverClock + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Get parameters from the connector internal state. + +
+The Connector keeps information about the connection that it implements + in its internal state. When customizing a Connector, it is often necessary + to access and sometimes modify these data objects. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_ConnectorSet(connector, srcFields, dstFields, rh, state, & + CplSet, srcVM, dstVM, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: connector + type(ESMF_FieldBundle), intent(in), optional :: srcFields + type(ESMF_FieldBundle), intent(in), optional :: dstFields + type(ESMF_RouteHandle), intent(in), optional :: rh + type(ESMF_State), intent(in), optional :: state + character(*), intent(in), optional :: CplSet + type(ESMF_VM), intent(in), optional :: srcVM + type(ESMF_VM), intent(in), optional :: dstVM + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set parameters in the connector internal state. + +
+The Connector keeps information about the connection that it implements + in its internal state. When customizing a Connector, it is often necessary + to access and sometimes modify these data objects. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAreServicesSet() + function NUOPC_GridCompAreServicesSet(comp, rc) +RETURN VALUE: +
logical :: NUOPC_GridCompAreServicesSet +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: comp + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if SetServices has been called for comp. + Otherwise return .false.. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAreServicesSet() + function NUOPC_CplCompAreServicesSet(comp, rc) +RETURN VALUE: +
logical :: NUOPC_CplCompAreServicesSet +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: comp + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if SetServices has been called for comp. + Otherwise return .false.. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeAdd() + subroutine NUOPC_GridCompAttributeAdd(comp, attrList, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + character(len=*), intent(in) :: attrList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add Attributes to the highest level of the standard NUOPC AttPack + hierarchy (convention="NUOPC", purpose="Instance"). + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeAdd() + subroutine NUOPC_CplCompAttributeAdd(comp, attrList, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + character(len=*), intent(in) :: attrList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add Attributes to the highest level of the standard NUOPC AttPack + hierarchy (convention="NUOPC", purpose="Instance"). + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeEgest() + subroutine NUOPC_GridCompAttributeEge(comp, freeFormat, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: comp + type(NUOPC_FreeFormat), intent(out) :: freeFormat + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Egest the Attributes of the highest level of the standard NUOPC AttPack + hierarchy (convention="NUOPC", purpose="Instance") as a FreeFormat object. + It is the caller's responsibility to destroy the created freeFormat + object. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeEgest() + subroutine NUOPC_CplCompAttributeEge(comp, freeFormat, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: comp + type(NUOPC_FreeFormat), intent(out) :: freeFormat + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Egest the Attributes of the highest level of the standard NUOPC AttPack + hierarchy (convention="NUOPC", purpose="Instance") as a FreeFormat object. + It is the caller's responsibility to destroy the created freeFormat + object. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeGet() + subroutine NUOPC_GridCompAttributeGet(comp, name, value, isPresent, isSet, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: comp + character(*), intent(in) :: name + character(*), intent(out) :: value + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isSet + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access the attribute name inside of comp using the + convention NUOPC and purpose Instance. + +
+This call assumes to find a scalar value. An error is returned otherwise. + +
+This call concverts to a string value, regardless of the actual attribute + storage. + +
+Unless isPresent and isSet are provided, return with error if + the attribute is not present or not set, respectively. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeGet() + subroutine NUOPC_CplCompAttributeGet(comp, name, value, isPresent, isSet, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: comp + character(*), intent(in) :: name + character(*), intent(out) :: value + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isSet + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access the attribute name inside of comp using the + convention NUOPC and purpose Instance. + +
+This call assumes to find a scalar value. An error is returned otherwise. + +
+This call concverts to a string value, regardless of the actual attribute + storage. + +
+Unless isPresent and isSet are provided, return with error if + the attribute is not present or not set, respectively. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeGet() + subroutine NUOPC_GridCompAttributeGetI(comp, name, value, isPresent, isSet, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: comp + character(*), intent(in) :: name + integer, intent(out) :: value + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isSet + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access the attribute name inside of comp using the + convention NUOPC and purpose Instance. + +
+Unless isPresent and isSet are provided, return with error if + the attribute is not present or not set, respectively. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeGet() + subroutine NUOPC_CplCompAttributeGetI(comp, name, value, isPresent, isSet, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: comp + character(*), intent(in) :: name + integer, intent(out) :: value + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isSet + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access the attribute name inside of comp using the + convention NUOPC and purpose Instance. + +
+Unless isPresent and isSet are provided, return with error if + the attribute is not present or not set, respectively. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeGet() + subroutine NUOPC_GridCompAttributeGetSL(comp, name, valueList, isPresent, & + isSet, itemCount, typekind, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: comp + character(*), intent(in) :: name + character(*), intent(out), optional :: valueList(:) + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isSet + integer, intent(out), optional :: itemCount + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access the attribute name inside of comp using the + convention NUOPC and purpose Instance. Returns with error if + the attribute is not present or not set. + +
+Unless isPresent and isSet are provided, return with error if + the attribute is not present or not set, respectively. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeGet() + subroutine NUOPC_CplCompAttributeGetSL(comp, name, valueList, isPresent, & + isSet, itemCount, typekind, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: comp + character(*), intent(in) :: name + character(*), intent(out), optional :: valueList(:) + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isSet + integer, intent(out), optional :: itemCount + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access the attribute name inside of comp using the + convention NUOPC and purpose Instance. Returns with error if + the attribute is not present or not set. + +
+Unless isPresent and isSet are provided, return with error if + the attribute is not present or not set, respectively. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeGet() + subroutine NUOPC_GridCompAttributeGetIL(comp, name, valueList, isPresent, & + isSet, itemCount, typekind, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: comp + character(*), intent(in) :: name + integer, intent(out) :: valueList(:) + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isSet + integer, intent(out), optional :: itemCount + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access the attribute name inside of comp using the + convention NUOPC and purpose Instance. Returns with error if + the attribute is not present or not set. + +
+Unless isPresent and isSet are provided, return with error if + the attribute is not present or not set, respectively. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeGet() + subroutine NUOPC_CplCompAttributeGetIL(comp, name, valueList, isPresent, & + isSet, itemCount, typekind, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: comp + character(*), intent(in) :: name + integer, intent(out) :: valueList(:) + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isSet + integer, intent(out), optional :: itemCount + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access the attribute name inside of comp using the + convention NUOPC and purpose Instance. Returns with error if + the attribute is not present or not set. + +
+Unless isPresent and isSet are provided, return with error if + the attribute is not present or not set, respectively. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeIngest() + subroutine NUOPC_GridCompAttributeIng(comp, freeFormat, addFlag, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: comp + type(NUOPC_FreeFormat), intent(in) :: freeFormat + logical, intent(in), optional :: addFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Ingest the Attributes from a FreeFormat object onto the highest level + of the standard NUOPC AttPack hierarchy (convention="NUOPC", + purpose="Instance"). + +
+Important: Attributes ingested by this method are stored as type character + strings, and must be accessed accordingly. Conversion from string into a + different data type, e.g. integer or real, is the user's + responsibility. + +
+If addFlag is .false. (default), an error will be returned if + an attribute is to be ingested that was not previously added to the + comp object. If addFlag is .true., all missing attributes + will be added by this method automatically as needed. + +
+Each line in freeFormat is of this format: + +
+
+ attributeName = attributeValue ++ +
+For example: +
+ Verbosity = 0 + Profiling = 0 + Diagnostic = 0 ++ could directly be ingested as Attributes for any instance of the four + standard NUOPC component kinds. This is because Verbosity, + Profiling, and Diagnostic are pre-defined Attributes of the + NUOPC component kinds according to sections 2.3.1, + 2.3.2, 2.3.3, and 2.3.4. + +
+When Attributes are specified in freeFormat that are not pre-defined + for a specific component kind, they can still be ingested by a component + instance using the addFlag=.true. option. For instance: +
+ ModelOutputChoice = 2 ++ specifies a user-level Attribute, which is not part of the pre-defined + Attributes of any of the standard NUOPC component kinds. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeIngest() + subroutine NUOPC_CplCompAttributeIng(comp, freeFormat, addFlag, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: comp + type(NUOPC_FreeFormat), intent(in) :: freeFormat + logical, intent(in), optional :: addFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Ingest the Attributes from a FreeFormat object onto the highest level + of the standard NUOPC AttPack hierarchy (convention="NUOPC", + purpose="Instance"). + +
+Important: Attributes ingested by this method are stored as type character + strings, and must be accessed accordingly. Conversion from string into a + different data type, e.g. integer or real, is the user's + responsibility. + +
+If addFlag is .false. (default), an error will be returned if + an attribute is to be ingested that was not previously added to the + comp object. If addFlag is .true., all missing attributes + will be added by this method automatically as needed. + +
+Each line in freeFormat is of this format: + +
+
+ attributeName = attributeValue ++ +
+For example: +
+ Verbosity = 0 + Profiling = 0 + Diagnostic = 0 ++ could directly be ingested as Attributes for any instance of the four + standard NUOPC component kinds. This is because Verbosity, + Profiling, and Diagnostic are pre-defined Attributes of the + NUOPC component kinds according to sections 2.3.1, + 2.3.2, 2.3.3, and 2.3.4. + +
+When Attributes are specified in freeFormat that are not pre-defined + for a specific component kind, they can still be ingested by a component + instance using the addFlag=.true. option. For instance: +
+ ModelOutputChoice = 2 ++ specifies a user-level Attribute, which is not part of the pre-defined + Attributes of any of the standard NUOPC component kinds. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeIngest() + subroutine NUOPC_GridCompAttributeIngHC(comp, hconfig, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: comp + type(ESMF_HConfig), intent(in) :: hconfig + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Ingest component attributes from a HConfig object onto the highest level + of the standard NUOPC AttPack hierarchy (convention="NUOPC", + purpose="Instance"). + +
+The provided hconfig is expected to be a map. An error is + returned if this condition is not met. Each key-value pair held by + hconfig is added as an attribute to comp. + A copy of the source contents is made. + +
+Transfers of scalar, sequence, and map values + from hconfig are supported. Maps are treated recursively. + Sequences are restricted to scalar elements of the same typekind. + +
+The keys of any map provided by the hconfig object must + be of scalar type. Keys are interpreted as strings when transferred as an + attribute. + +
+Existing attributes with the same key are overridden by this operation. + When attributes are overridden, the typekind of the associated value + element is allowed to change. + +
+
+ # A simple YAML definition of standard NUOPC attributes, followed by + # component specific attributes. + + Verbosity: 4609 # decimal representation of explicit bit pattern + Profiling: low # pre-defined NUOPC setting + Diagnostic: 0 # explicit 0 turns OFF feature + CustomSeq1: [1, 2, 3, 4] # sequence of integers + CustomSeq2: [1., 2., 3., 4.] # sequence of floats + CustomSeq3: [true, false] # sequence of bools + CustomType: {k1: [a, aa, aaa], k2: b, k3: c} # complex structure ++ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeIngest() + subroutine NUOPC_CplCompAttributeIngHC(comp, hconfig, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: comp + type(ESMF_HConfig), intent(in) :: hconfig + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Ingest component attributes from a HConfig object onto the highest level + of the standard NUOPC AttPack hierarchy (convention="NUOPC", + purpose="Instance"). + +
+The provided hconfig is expected to be a map. An error is + returned if this condition is not met. Each key-value pair held by + hconfig is added as an attribute to comp. + A copy of the source contents is made. + +
+Transfers of scalar, sequence, and map values + from hconfig are supported. Maps are treated recursively. + Sequences are restricted to scalar elements of the same typekind. + +
+The keys of any map provided by the hconfig object must + be of scalar type. Keys are interpreted as strings when transferred as an + attribute. + +
+Existing attributes with the same key are overridden by this operation. + When attributes are overridden, the typekind of the associated value + element is allowed to change. + +
+
+ # A simple YAML definition of standard NUOPC attributes, followed by + # component specific attributes. + + Verbosity: 4609 # decimal representation of explicit bit pattern + Profiling: low # pre-defined NUOPC setting + Diagnostic: 0 # explicit 0 turns OFF feature + CustomSeq1: [1, 2, 3, 4] # sequence of integers + CustomSeq2: [1., 2., 3., 4.] # sequence of floats + CustomSeq3: [true, false] # sequence of bools + CustomType: {k1: [a, aa, aaa], k2: b, k3: c} # complex structure ++ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeReset() + subroutine NUOPC_GridCompAttributeReset(comp, attrList, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + character(len=*), intent(in) :: attrList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Reset Attributes on the highest level of the standard NUOPC AttPack + hierarchy (convention="NUOPC", purpose="Instance"). + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeReset() + subroutine NUOPC_CplCompAttributeReset(comp, attrList, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + character(len=*), intent(in) :: attrList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Reset Attributes on the highest level of the standard NUOPC AttPack + hierarchy (convention="NUOPC", purpose="Instance"). + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeSet() + subroutine NUOPC_GridCompAttributeSetS(comp, name, value, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + character(*), intent(in) :: name + character(*), intent(in) :: value + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the Attribute name inside of comp on the highest level + of the standard NUOPC AttPack hierarchy (convention="NUOPC", + purpose="Instance"). + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeSet() + subroutine NUOPC_CplCompAttributeSetS(comp, name, value, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + character(*), intent(in) :: name + character(*), intent(in) :: value + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the Attribute name inside of comp on the highest level + of the standard NUOPC AttPack hierarchy (convention="NUOPC", + purpose="Instance"). + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeSet() + subroutine NUOPC_GridCompAttributeSetI(comp, name, value, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + character(*), intent(in) :: name + integer, intent(in) :: value + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the Attribute name inside of comp on the highest level + of the standard NUOPC AttPack hierarchy (convention="NUOPC", + purpose="Instance"). + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeSet() + subroutine NUOPC_CplCompAttributeSetI(comp, name, value, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + character(*), intent(in) :: name + integer, intent(in) :: value + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the Attribute name inside of comp on the highest level + of the standard NUOPC AttPack hierarchy (convention="NUOPC", + purpose="Instance"). + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeSet() + subroutine NUOPC_GridCompAttributeSetSL(comp, name, valueList, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + character(*), intent(in) :: name + character(*), intent(in) :: valueList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the Attribute name inside of comp on the highest level + of the standard NUOPC AttPack hierarchy (convention="NUOPC", + purpose="Instance"). + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompAttributeSet() + subroutine NUOPC_CplCompAttributeSetSL(comp, name, valueList, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + character(*), intent(in) :: name + character(*), intent(in) :: valueList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the Attribute name inside of comp on the highest level + of the standard NUOPC AttPack hierarchy (convention="NUOPC", + purpose="Instance"). + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompCheckSetClock() + subroutine NUOPC_GridCompCheckSetClock(comp, externalClock, checkTimeStep, & + forceTimeStep, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: comp + type(ESMF_Clock), intent(in) :: externalClock + logical, intent(in), optional :: checkTimeStep + logical, intent(in), optional :: forceTimeStep + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Compare externalClock to the internal clock of comp to make sure + they match in their current time. Also ensure that the time step of the + external clock is a multiple of the time step of the internal clock. If + both conditions are satisfied then set the stop time of the internal clock + so it is reached in one time step of the external clock. Otherwise leave the + internal clock unchanged and return with error. The direction of + the involved clocks is taking into account. + Setting the forceTimeStep argument to .true. forces the + timeStep of the externalClock to be used to reset the + timeStep of the internal clock. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompDerive() + recursive subroutine NUOPC_GridCompDerive(comp, genericSetServicesRoutine, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(in) :: comp + interface + subroutine genericSetServicesRoutine(gridcomp, rc) + use ESMF + implicit none + type(ESMF_GridComp) :: gridcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Derive a GridComp (i.e. Model, Mediator, or Driver) from a generic + component by calling into the specified SetServices() routine of the + generic component. This is typically the first call in the + SetServices() routine of the specializing component, and is followed + by NUOPC_CompSpecialize() calls. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompDerive() + recursive subroutine NUOPC_CplCompDerive(comp, genericSetServicesRoutine, rc) +ARGUMENTS: +
type(ESMF_CplComp), intent(in) :: comp + interface + subroutine genericSetServicesRoutine(cplcomp, rc) + use ESMF + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Derive a CplComp (i.e. Connector) from a generic + component by calling into the specified SetServices() routine of the + generic component. This is typically the first call in the + SetServices() routine of the specializing component, and is followed + by NUOPC_CompSpecialize() calls. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompFilterPhaseMap() + subroutine NUOPC_GridCompFilterPhaseMap(comp, methodflag, acceptStringList, & + rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + type(ESMF_Method_Flag), intent(in) :: methodflag + character(len=*), intent(in) :: acceptStringList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Filter all PhaseMap entries in a GridComp (i.e. Model, Mediator, or Driver) + that do not match any entry in the acceptStringList. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompFilterPhaseMap() + subroutine NUOPC_CplCompFilterPhaseMap(comp, methodflag, acceptStringList, & + rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + type(ESMF_Method_Flag), intent(in) :: methodflag + character(len=*), intent(in) :: acceptStringList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Filter all PhaseMap entries in a CplComp (i.e. Connector) + that do not match any entry in the acceptStringList. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompGet() + subroutine NUOPC_GridCompGet(comp, name, verbosity, profiling, diagnostic, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + character(len=*), intent(out), optional :: name + integer, intent(out), optional :: verbosity + integer, intent(out), optional :: profiling + integer, intent(out), optional :: diagnostic + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access information from a GridComp. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompGet() + subroutine NUOPC_CplCompGet(comp, name, verbosity, profiling, diagnostic, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + character(len=*), intent(out), optional :: name + integer, intent(out), optional :: verbosity + integer, intent(out), optional :: profiling + integer, intent(out), optional :: diagnostic + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access information from a CplComp. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSearchPhaseMap() + subroutine NUOPC_GridCompSearchPhaseMap(comp, methodflag, internalflag, & + phaseLabel, phaseIndex, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + type(ESMF_Method_Flag), intent(in) :: methodflag + logical, intent(in), optional :: internalflag + character(len=*), intent(in), optional :: phaseLabel + integer, intent(out) :: phaseIndex + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Search all PhaseMap entries in a GridComp (i.e. Model, Mediator, or Driver) + to see if phaseLabel is found. Return the associated ESMF + phaseIndex, or -1 if not found. If phaseLabel is not + specified, set phaseIndex to the first entry in the PhaseMap, or + -1 if there are no entries. The internalflag argument + allows to search the internal phase maps of driver components. The default + is internalflag=.false.. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSearchPhaseMap() + subroutine NUOPC_CplCompSearchPhaseMap(comp, methodflag, phaseLabel, & + phaseIndex, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + type(ESMF_Method_Flag), intent(in) :: methodflag + character(len=*), intent(in), optional :: phaseLabel + integer, intent(out) :: phaseIndex + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Search all PhaseMap entries in a CplComp (i.e. Connector) + to see if phaseLabel is found. Return the associated ESMF + phaseIndex, or -1 if not found. If phaseLabel is not + specified, set phaseIndex to the first entry in the PhaseMap, or + -1 if there are no entries. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSearchRevPhaseMap() + subroutine NUOPC_GridCompSearchRevPhaseMap(comp, methodflag, internalflag, & + phaseIndex, phaseLabel, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + type(ESMF_Method_Flag), intent(in) :: methodflag + logical, intent(in), optional :: internalflag + integer, intent(in), optional :: phaseIndex + character(len=*), intent(out) :: phaseLabel + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Search all PhaseMap entries in a GridComp (i.e. Model, Mediator, or Driver) + to see if the ESMF phaseIndex is found. Return the associated + phaseLabel, or an empty string if not found. If phaseIndex is not + specified, set phaseLabel to the first entry in the PhaseMap, or + an empty string if there are no entries. The internalflag argument + allows to search the internal phase maps of driver components. The default + is internalflag=.false.. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSearchRevPhaseMap() + subroutine NUOPC_CplCompSearchRevPhaseMap(comp, methodflag, phaseIndex, & + phaseLabel, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + type(ESMF_Method_Flag), intent(in) :: methodflag + integer, intent(in), optional :: phaseIndex + character(len=*), intent(out) :: phaseLabel + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Search all PhaseMap entries in a CplComp (i.e. Connector) + to see if the ESMF phaseIndex is found. Return the associated + phaseLabel, or an empty string if not found. If phaseIndex is not + specified, set phaseLabel to the first entry in the PhaseMap, or + an empty string if there are no entries. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSetClock() + subroutine NUOPC_GridCompSetClock(comp, externalClock, stabilityTimeStep, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: comp + type(ESMF_Clock), intent(in) :: externalClock + type(ESMF_TimeInterval), intent(in), optional :: stabilityTimeStep + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the component internal clock as a copy of externalClock, but + with a timeStep that is less than or equal to the stabilityTimeStep. + At the same time ensure that the timeStep of the external clock is + a multiple of the timeStep of the internal clock. If the stabilityTimeStep + argument is not provided then the internal clock will simply be set + as a copy of the external clock. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSetEntryPoint() + subroutine NUOPC_GridCompSetEntryPoint(comp, methodflag, phaseLabelList, & + userRoutine, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + type(ESMF_Method_Flag), intent(in) :: methodflag + character(len=*), intent(in) :: phaseLabelList(:) + interface + subroutine userRoutine(gridcomp, importState, exportState, clock, rc) + use ESMF_CompMod + use ESMF_StateMod + use ESMF_ClockMod + implicit none + type(ESMF_GridComp) :: gridcomp ! must not be optional + type(ESMF_State) :: importState ! must not be optional + type(ESMF_State) :: exportState ! must not be optional + type(ESMF_Clock) :: clock ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set an entry point for a GridComp (i.e. Model, Mediator, or Driver). Publish + the new entry point in the correct PhaseMap component attribute. + +
+Starting with version 8.1.0, the use of this method is deprecated. Components + should instead specialize exclusively using the NUOPC_CompSpecialize() + method. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSetEntryPoint() + subroutine NUOPC_CplCompSetEntryPoint(comp, methodflag, phaseLabelList, & + userRoutine, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + type(ESMF_Method_Flag), intent(in) :: methodflag + character(len=*), intent(in) :: phaseLabelList(:) + interface + subroutine userRoutine(cplcomp, importState, exportState, clock, rc) + use ESMF_CompMod + use ESMF_StateMod + use ESMF_ClockMod + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + type(ESMF_State) :: importState ! must not be optional + type(ESMF_State) :: exportState ! must not be optional + type(ESMF_Clock) :: clock ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set an entry point for a CplComp (i.e. Connector). Publish + the new entry point in the correct PhaseMap component attribute. + +
+Starting with version 8.1.0, the use of this method is deprecated. Components + should instead specialize exclusively using the NUOPC_CompSpecialize() + method. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSetInternalEntryPoint() + subroutine NUOPC_GridCompSetIntEntryPoint(comp, methodflag, phaseLabelList, & + userRoutine, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + type(ESMF_Method_Flag), intent(in) :: methodflag + character(len=*), intent(in) :: phaseLabelList(:) + interface + subroutine userRoutine(gridcomp, importState, exportState, clock, rc) + use ESMF_CompMod + use ESMF_StateMod + use ESMF_ClockMod + implicit none + type(ESMF_GridComp) :: gridcomp ! must not be optional + type(ESMF_State) :: importState ! must not be optional + type(ESMF_State) :: exportState ! must not be optional + type(ESMF_Clock) :: clock ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set an internal entry point for a GridComp (i.e. Driver). Only Drivers + currently utilize internal entry points. Internal entry points allow user + specialization on the driver level during initialization and run sequencing. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSetServices() + recursive subroutine NUOPC_GridCompSetServices(comp, sharedObj, userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: comp + character(len=*), intent(in), optional :: sharedObj + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Try to find a routine called "SetServices" in the sharedObj file + and execute the routine. An attempt is made to find a routine that + is close in name to "SetServices", allowing for compiler name + mangling, i.e. upper and lower case, as well as trailing underscores. + The asterisk character (*) is supported as a wildcard for the + file name suffix in sharedObj. When present, the asterisk is replaced + by "so", "dylib", and "dll", in this order, and the first successfully + loaded object is used. If the sharedObj argument is not provided, the + executable itself is searched. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSetVM() + recursive subroutine NUOPC_GridCompSetVM(comp, sharedObj, userRc, rc) +ARGUMENTS: +
type(ESMF_GridComp), intent(inout) :: comp + character(len=*), intent(in), optional :: sharedObj + integer, intent(out), optional :: userRc + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Try to find a routine called "SetVM" in the sharedObj file + and execute the routine. An attempt is made to find a routine that + is close in name to "SetVM", allowing for compiler name + mangling, i.e. upper and lower case, as well as trailing underscores. + The asterisk character (*) is supported as a wildcard for the + file name suffix in sharedObj. When present, the asterisk is replaced + by "so", "dylib", and "dll", in this order, and the first successfully + loaded object is used. If the sharedObj argument is not provided, the + executable itself is searched. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSpecialize() + subroutine NUOPC_GridCompSpecialize(comp, specLabel, specPhaseLabel, & + specRoutine, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: comp + character(len=*), intent(in) :: specLabel + character(len=*), intent(in), optional :: specPhaseLabel + interface + subroutine specRoutine(gridcomp, rc) + use ESMF + implicit none + type(ESMF_GridComp) :: gridcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Specialize a derived GridComp (i.e. Model, Mediator, or Driver). If + specPhaseLabel is specified, the specialization only applies to + the associated phase. Otherwise the specialization applies to all phases. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_CompSpecialize() + subroutine NUOPC_CplCompSpecialize(comp, specLabel, specPhaseLabel, & + specRoutine, rc) +ARGUMENTS: +
type(ESMF_CplComp) :: comp + character(len=*), intent(in) :: specLabel + character(len=*), intent(in), optional :: specPhaseLabel + interface + subroutine specRoutine(cplcomp, rc) + use ESMF + implicit none + type(ESMF_CplComp) :: cplcomp ! must not be optional + integer, intent(out) :: rc ! must not be optional + end subroutine + end interface + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Specialize a derived CplComp (i.e. Connector). If + specPhaseLabel is specified, the specialization only applies to + the associated phase. Otherwise the specialization applies to all phases. + + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_FieldDictionaryAddEntry(standardName, canonicalUnits, rc) +ARGUMENTS: +
character(*), intent(in) :: standardName + character(*), intent(in) :: canonicalUnits + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add an entry to the NUOPC Field dictionary. If necessary the dictionary is + first set up. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_FieldDictionaryEgest(freeFormat, iofmt, rc) +ARGUMENTS: +
type(NUOPC_FreeFormat), intent(out) :: freeFormat + type(ESMF_IOFmt_Flag), intent(in), optional :: iofmt + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Egest the contents of the NUOPC Field dictionary into a FreeFormat object. + If I/O format option iofmt is provided and equal to ESMF_IOFMT_YAML, + the FreeFormat object will contain the NUOPC Field dictionary expressed in YAML + format. Other values for iofmt are ignored and this method behaves as if + the optional iofmt argument were missing. In such a case, freeFormat + will contain NUOPC Field dictionary entries in the traditional format. + It is the caller's responsibility to destroy the created freeFormat + object. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_FieldDictionaryGetEntry(standardName, canonicalUnits, rc) +ARGUMENTS: +
character(*), intent(in) :: standardName + character(*), intent(out), optional :: canonicalUnits + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return the canonical units that the NUOPC Field dictionary associates with + the standardName. + +
+ +
+ +
+ +
+
+INTERFACE:
+
function NUOPC_FieldDictionaryHasEntry(standardName, rc) +RETURN VALUE: +
logical :: NUOPC_FieldDictionaryHasEntry +ARGUMENTS: +
character(*), intent(in) :: standardName + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the NUOPC Field dictionary has an entry with the + specified standardName, .false. otherwise. + +
+ +
+ +
+ +
+
+INTERFACE:
+
function NUOPC_FieldDictionaryMatchSyno(standardName1, standardName2, rc) +RETURN VALUE: +
logical :: NUOPC_FieldDictionaryMatchSyno +ARGUMENTS: +
character(*), intent(in) :: standardName1 + character(*), intent(in) :: standardName2 + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the NUOPC Field dictionary considers + standardName1 and standardName2 synonyms, .false. + otherwise. Also, if standardName1 and/or standardName2 do not + correspond to an existing dictionary entry, .false. will be returned. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_FieldDictionarySetSyno(standardNames, rc) +ARGUMENTS: +
character(*), intent(in) :: standardNames(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set all of the elements of the standardNames argument to be considered + synonyms by the field dictionary. Every element in standardNames must + correspond to the standard name of already existing entries in the field + dictionary, or else an error will be returned. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_FieldDictionarySetup() + subroutine NUOPC_FieldDictionarySetupDefault(rc) +ARGUMENTS: +
integer, intent(out), optional :: rc ++DESCRIPTION: +
+Setup the default NUOPC Field dictionary. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_FieldDictionarySetup() + subroutine NUOPC_FieldDictionarySetupFile(fileName, rc) +ARGUMENTS: +
character(len=*), intent(in) :: fileName + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Setup the NUOPC Field dictionary by reading its content from YAML file. + If the NUOPC Field dictionary already exists, remove it and create a new one. + This feature requires ESMF built with YAML support. Please see the + ESMF User's Guide for details. + + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_FreeFormatAdd(freeFormat, stringList, line, rc) +ARGUMENTS: +
type(NUOPC_FreeFormat), intent(inout) :: freeFormat + character(len=*), intent(in) :: stringList(:) + integer, optional, intent(in) :: line + integer, optional, intent(out) :: rc ++DESCRIPTION: +
+Add lines to a FreeFormat object. The capacity of freeFormat may + increase during this operation. The new lines provided in stringList + are added starting at position line. If line is greater than the + current lineCount of freeFormat, blank lines are inserted to + fill the gap. By default, i.e. without specifying the line argument, + the elements in stringList are added to the end of the + freeFormat object. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_FreeFormatCreate() + function NUOPC_FreeFormatCreateDefault(freeFormat, stringList, capacity, rc) +RETURN VALUE: +
type(NUOPC_FreeFormat) :: NUOPC_FreeFormatCreateDefault +ARGUMENTS: +
type(NUOPC_FreeFormat), optional, intent(in) :: freeFormat + character(len=*), optional, intent(in) :: stringList(:) + integer, optional, intent(in) :: capacity + integer, optional, intent(out) :: rc ++DESCRIPTION: +
+Create a new FreeFormat object, which by default is empty. + If freeFormat is provided, then the newly created object starts as + a copy of freeFormat. If stringList is provided, then it is + added to the end of the newly created object. If capacity is provided, + it is used for the initial creation of the newly created FreeFormat + object. However, if the freeFormat or stringList arguments are + present, the final capacity may be larger than specified by capacity. + +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_FreeFormatCreate() + function NUOPC_FreeFormatCreateRead(config, label, relaxedflag, rc) +RETURN VALUE: +
type(NUOPC_FreeFormat) :: NUOPC_FreeFormatCreateRead +ARGUMENTS: +
type(ESMF_Config) :: config + character(len=*), intent(in) :: label + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Create a new FreeFormat object from ESMF_Config object. The config + object must exist, and label must reference either a single line + or a table attribute within config. The content of the attribute is + read and returned in the newly created FreeFormat object. + +
+By default an error is returned if label is not found in config. + This error can be suppressed by setting relaxedflag=.true., in which + case an empty FreeFormat object is returned. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_FreeFormatDestroy(freeFormat, rc) +ARGUMENTS: +
type(NUOPC_FreeFormat), intent(inout) :: freeFormat + integer, optional, intent(out) :: rc ++DESCRIPTION: +
+Destroy a FreeFormat object. All internal memory is deallocated. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_FreeFormatGet(freeFormat, lineCount, capacity, stringList, rc) +ARGUMENTS: +
type(NUOPC_FreeFormat), intent(in) :: freeFormat + integer, optional, intent(out) :: lineCount + integer, optional, intent(out) :: capacity + character(len=NUOPC_FreeFormatLen), optional, pointer :: stringList(:) + integer, optional, intent(out) :: rc ++DESCRIPTION: +
+Get information from a FreeFormat object. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_FreeFormatGetLine(freeFormat, line, commentChar, lineString, & + tokenCount, tokenList, rc) +ARGUMENTS: +
type(NUOPC_FreeFormat), intent(in) :: freeFormat + integer, intent(in) :: line + character, optional, intent(in) :: commentChar + character(len=NUOPC_FreeFormatLen), optional, intent(out) :: lineString + integer, optional, intent(out) :: tokenCount + character(len=NUOPC_FreeFormatLen), optional, intent(out) :: tokenList(:) + integer, optional, intent(out) :: rc ++DESCRIPTION: +
+Get information about a specific line in a FreeFormat object. If + commentChar is specified, anything on the line, starting with + commentChar is considered a comment, and subsequently ignored. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_FreeFormatLog(freeFormat, rc) +ARGUMENTS: +
type(NUOPC_FreeFormat), intent(in) :: freeFormat + integer, optional, intent(out) :: rc ++DESCRIPTION: +
+Write a FreeFormat object to the default Log. + +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_FreeFormatPrint(freeFormat, rc) +ARGUMENTS: +
type(NUOPC_FreeFormat), intent(in) :: freeFormat + integer, optional, intent(out) :: rc ++DESCRIPTION: +
+Print a FreeFormat object. + + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_AddNamespace(state, Namespace, nestedStateName, & + nestedState, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + character(len=*), intent(in) :: Namespace + character(len=*), intent(in), optional :: nestedStateName + type(ESMF_State), intent(out), optional :: nestedState + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Add a Namespace to state. Namespaces are implemented via nested + states. This creates a nested state inside of state. The nested state + is returned as nestedState. If provided, nestedStateName will + be used to name the newly created nested state. The default name of the + nested state is equal to Namespace. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_AddNestedState(state, Namespace, CplSet, nestedStateName, & + vm, nestedState, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + character(len=*), intent(in), optional :: Namespace + character(len=*), intent(in), optional :: CplSet + character(len=*), intent(in), optional :: nestedStateName + type(ESMF_VM), intent(in), optional :: vm + type(ESMF_State), intent(out), optional :: nestedState + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Create a nested state inside of state. The arguments Namespace + and tt CplSet are used to set NUOPC attributes on the newly created + state. The nested state is returned as nestedState. If provided, + nestedStateName will be used to name the newly created nested state. + The default name of the nested state is equal to + Namespace_CplSet, Namespace, or CplSet if the + arguments are provided. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Advertise() + subroutine NUOPC_AdvertiseField(state, StandardName, Units, & + LongName, ShortName, name, TransferOfferGeomObject, SharePolicyField, & + SharePolicyGeomObject, vm, field, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + character(*), intent(in) :: StandardName + character(*), intent(in), optional :: Units + character(*), intent(in), optional :: LongName + character(*), intent(in), optional :: ShortName + character(*), intent(in), optional :: name + character(*), intent(in), optional :: TransferOfferGeomObject + character(*), intent(in), optional :: SharePolicyField + character(*), intent(in), optional :: SharePolicyGeomObject + type(ESMF_VM), intent(in), optional :: vm + type(ESMF_Field), intent(out), optional :: field + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Advertise a field in a state. This creates an empty field and adds it to + state. The "StandardName", "Units", "LongName", "ShortName", and + "TransferOfferGeomObject" attributes of the field are set according to the + provided input.. + +
+The call checks the provided information against the NUOPC Field Dictionary + to ensure correctness. Defaults are set according to the NUOPC Field + Dictionary. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Advertise() + subroutine NUOPC_AdvertiseFields(state, StandardNames, & + TransferOfferGeomObject, SharePolicyField, SharePolicyGeomObject, vm, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + character(*), intent(in) :: StandardNames(:) + character(*), intent(in), optional :: TransferOfferGeomObject + character(*), intent(in), optional :: SharePolicyField + character(*), intent(in), optional :: SharePolicyGeomObject + type(ESMF_VM), intent(in), optional :: vm + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Advertise a list of fields in a state. This creates a list of empty fields + and adds it to the state. The "StandardName", "TransferOfferGeomObject", + "SharePolicyField", and "SharePolicyGeomObject" attributes of all the + fields are set according to the provided input. The "Units", "LongName", + and "ShortName" attributes for each field are set according to the defaults + documented under method 3.9.3 + +
+The call checks the provided information against the NUOPC Field Dictionary + to ensure correctness. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_AdjustClock(clock, maxTimestep, rc) +ARGUMENTS: +
type(ESMF_Clock) :: clock + type(ESMF_TimeInterval), intent(in), optional :: maxTimestep + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Adjust the clock to have a potentially smaller timestep. The timestep + on the incoming clock object is compared to the maxTimestep, and + reset to the smaller of the two. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_CheckSetClock(setClock, checkClock, setStartTimeToCurrent, & + currTime, forceCurrTime, checkTimeStep, forceTimeStep, rc) +ARGUMENTS: +
type(ESMF_Clock), intent(inout) :: setClock + type(ESMF_Clock), intent(in) :: checkClock + logical, intent(in), optional :: setStartTimeToCurrent + type(ESMF_Time), intent(in), optional :: currTime + logical, intent(in), optional :: forceCurrTime + logical, intent(in), optional :: checkTimeStep + logical, intent(in), optional :: forceTimeStep + integer, intent(out), optional :: rc ++DESCRIPTION: +
+By default compare setClock to checkClock to ensure they match + in their current time. Further ensure that the timeStep of checkClock + is a multiple of the timeStep of setClock. If both conditions are + satisfied then the stopTime of the setClock is set one + checkClock timeStep, or setClock runDuration, ahead of the + current time, which ever is shorter. The direction of checkClock + is considered when setting the stopTime. + +
+By default the startTime of the setClock is not modified. However, if + setStartTimeToCurrent == .true. the startTime of setClock is set + to the currentTime of checkClock. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_GetAttribute() + subroutine NUOPC_GetAttributeFieldVal(field, name, value, isPresent, isSet, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + character(*), intent(in) :: name + character(*), intent(out) :: value + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isSet + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access the attribute name inside of field using the + convention NUOPC and purpose Instance. + +
+Unless isPresent and isSet are provided, return with error if + the Attribute is not present or not set, respectively. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_GetAttribute() + subroutine NUOPC_GetAttributeFieldTK(field, name, isPresent, isSet, & + itemCount, typekind, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + character(*), intent(in) :: name + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isSet + integer, intent(out), optional :: itemCount + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Query the typekind of the attribute name inside of field + using the convention NUOPC and purpose Instance. + +
+Unless isPresent and isSet are provided, return with error if + the Attribute is not present or not set, respectively. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_GetAttribute() + subroutine NUOPC_GetAttributeState(state, name, value, isPresent, isSet, & + itemCount, typekind, rc) +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + character(*), intent(in) :: name + character(*), intent(out), optional :: value + logical, intent(out), optional :: isPresent + logical, intent(out), optional :: isSet + integer, intent(out), optional :: itemCount + type(ESMF_TypeKind_Flag), intent(out), optional :: typekind + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access the attribute name inside of state using the + convention NUOPC and purpose Instance. Returns with error if + the attribute is not present or not set. + +
+Unless isPresent and isSet are provided, return with error if + the Attribute is not present or not set, respectively. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_GetStateMemberLists(state, StandardNameList, & + ConnectedList, NamespaceList, CplSetList, itemNameList, fieldList, & + stateList, nestedFlag, rc) +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + character(ESMF_MAXSTR), pointer, optional :: StandardNameList(:) + character(ESMF_MAXSTR), pointer, optional :: ConnectedList(:) + character(ESMF_MAXSTR), pointer, optional :: NamespaceList(:) + character(ESMF_MAXSTR), pointer, optional :: CplSetList(:) + character(ESMF_MAXSTR), pointer, optional :: itemNameList(:) + type(ESMF_Field), pointer, optional :: fieldList(:) + type(ESMF_State), pointer, optional :: stateList(:) + logical, intent(in), optional :: nestedFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Construct lists containing the StandardNames, field names, and connected + status of the fields in state. Return this information in the + list arguments. Recursively parse through nested States. + +
+All pointer arguments present must enter this method unassociated. This + means that the user code must explicitly call nullify() or use the + => null() syntax on the variables passed in as any of the pointer + arguments. On return, the pointer arguments may either be unassociated or + associated. Consequently the user code must first check the status of any + of the returned pointer arguments via the associated() intrinsic + before accessing the argument. The responsibility for deallocation of + associated pointer arguments transfers to the caller. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_GetStateMemberCount(state, fieldCount, nestedFlag, rc) +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + integer, intent(out), optional :: fieldCount + logical, intent(in), optional :: nestedFlag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Determine the number of fields in state. By default recursively parse + through nested States. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_GetTimestamp(field, isValid, time, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + logical, intent(out), optional :: isValid + type(ESMF_Time), intent(out), optional :: time + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Access the timestamp on field in form of an ESMF_Time object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_IngestPetList() + subroutine NUOPC_IngestPetListFF(petList, freeFormat, rc) +ARGUMENTS: +
integer, allocatable, intent(out) :: petList(:) + type(NUOPC_FreeFormat), intent(in), target :: freeFormat + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Construct a petList from a FreeFormat object. + +
+The arguments are: +
+For an example, the free format petList definition +
+ "2-5 12 0 15-23" ++ would translate into a petList output of +
+ (/2, 3, 4, 5, 12, 0, 15, 16, 17, 18, 19, 20, 21, 22, 23/) ++ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_IngestPetList() + subroutine NUOPC_IngestPetListHC(petList, hconfig, rc) +ARGUMENTS: +
integer, allocatable, intent(out) :: petList(:) + type(ESMF_HConfig), intent(in) :: hconfig + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Construct a petList from a HConfig object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_IsAtTime() + function NUOPC_IsAtTimeField(field, time, rc) +RETURN VALUE: +
logical :: NUOPC_IsAtTimeField +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + type(ESMF_Time), intent(in) :: time + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Returns .true. if field has a timestamp + that matches time. Otherwise returns .false.. On PETs + with only a proxy instance of the field, .true. is returned + regardless of the actual timestamp. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_IsAtTime() + function NUOPC_IsAtTimeState(state, time, fieldName, count, fieldList, rc) +RETURN VALUE: +
logical :: NUOPC_IsAtTimeState +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + type(ESMF_Time), intent(in) :: time + character(*), intent(in), optional :: fieldName + integer, intent(out), optional :: count + type(ESMF_Field), allocatable, intent(out), optional :: fieldList(:) + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the field(s) in state have a timestamp + that matches time. Otherwise return .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_IsConnected() + function NUOPC_IsConnectedField(field, rc) +RETURN VALUE: +
logical :: NUOPC_IsConnectedField +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the field is connected. + Otherwise return .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_IsConnected() + function NUOPC_IsConnectedState(state, fieldName, count, rc) +RETURN VALUE: +
logical :: NUOPC_IsConnectedState +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + character(*), intent(in), optional :: fieldName + integer, intent(out), optional :: count + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the field(s) in state are connected. Otherwise + return .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_IsUpdated() + function NUOPC_IsUpdatedField(field, rc) +RETURN VALUE: +
logical :: NUOPC_IsUpdatedField +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the field has its "Updated" + attribute set to "true". Otherwise return .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_IsUpdated() + function NUOPC_IsUpdatedState(state, fieldName, count, rc) +RETURN VALUE: +
logical :: NUOPC_IsUpdatedState +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + character(*), intent(in), optional :: fieldName + integer, intent(out), optional :: count + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Return .true. if the field(s) in state have the "Updated" + attribute set to "true". Otherwise return .false.. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
subroutine NUOPC_NoOp(gcomp, rc) +ARGUMENTS: +
type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc ++DESCRIPTION: +
+No-Op method with an interface that matches the + requirements for a attachable method for ESMF_GridComp objects. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Realize() + subroutine NUOPC_RealizeCompleteG(state, grid, fieldName, typekind, & + staggerloc, selection, dataFillScheme, field, rc) +ARGUMENTS: +
type(ESMF_State) :: state + type(ESMF_Grid), intent(in) :: grid + character(*), intent(in), optional :: fieldName + type(ESMF_TypeKind_Flag), intent(in), optional :: typekind + type(ESMF_StaggerLoc), intent(in), optional :: staggerloc + character(len=*), intent(in), optional :: selection + character(len=*), intent(in), optional :: dataFillScheme + type(ESMF_Field), intent(out), optional :: field + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Realize or remove fields inside of state according to selection. + All of the fields that are realized are created internally on the same + grid object, allocating memory for as many field dimensions as there + are grid dimensions. + +
+The type and kind of the created fields is according to argument + typekind. + +
+Realized fields are filled with data according to the dataFillScheme + argument. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Realize() + subroutine NUOPC_RealizeCompleteLS(state, locstream, fieldName, typekind, selection,& + dataFillScheme, field, rc) +ARGUMENTS: +
type(ESMF_State) :: state + type(ESMF_LocStream), intent(in) :: locstream + character(*), intent(in), optional :: fieldName + type(ESMF_TypeKind_Flag), intent(in), optional :: typekind + character(len=*), intent(in), optional :: selection + character(len=*), intent(in), optional :: dataFillScheme + type(ESMF_Field), intent(out), optional :: field + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Realize or remove fields inside of state according to selection. + All of the fields that are realized are created internally on the same + locstream object, allocating memory accordingly. + +
+The type and kind of the created fields is according to argument + typekind. + +
+Realized fields are filled with data according to the dataFillScheme + argument. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Realize() + subroutine NUOPC_RealizeCompleteM(state, mesh, fieldName, typekind, & + meshloc, selection, dataFillScheme, field, rc) +ARGUMENTS: +
type(ESMF_State) :: state + type(ESMF_Mesh), intent(in) :: mesh + character(*), intent(in), optional :: fieldName + type(ESMF_TypeKind_Flag), intent(in), optional :: typekind + type(ESMF_MeshLoc), intent(in), optional :: meshloc + character(len=*), intent(in), optional :: selection + character(len=*), intent(in), optional :: dataFillScheme + type(ESMF_Field), intent(out), optional :: field + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Realize or remove fields inside of state according to selection. + All of the fields that are realized are created internally on the same + mesh object, allocating memory accordingly. + +
+The type and kind of the created fields is according to argument + typekind. + +
+Realized fields are filled with data according to the dataFillScheme + argument. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Realize() + subroutine NUOPC_RealizeField(state, field, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + type(ESMF_Field), intent(in) :: field + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Realize a previously advertised field in state by replacing the + advertised field with field of the same name. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Realize() + subroutine NUOPC_RealizeTransfer(state, fieldName, typekind, gridToFieldMap, & + ungriddedLBound, ungriddedUBound, totalLWidth, totalUWidth, & + realizeOnlyConnected, removeNotConnected, realizeOnlyNotShared, & + realizeOnlyNotComplete, field, rc) +ARGUMENTS: +
type(ESMF_State) :: state + character(*), intent(in) :: fieldName + type(ESMF_TypeKind_Flag), intent(in), optional :: typekind + integer, target, intent(in), optional :: gridToFieldMap(:) + integer, target, intent(in), optional :: ungriddedLBound(:) + integer, target, intent(in), optional :: ungriddedUBound(:) + integer, intent(in), optional :: totalLWidth(:) + integer, intent(in), optional :: totalUWidth(:) + logical, intent(in), optional :: realizeOnlyConnected + logical, intent(in), optional :: removeNotConnected + logical, intent(in), optional :: realizeOnlyNotShared + logical, intent(in), optional :: realizeOnlyNotComplete + type(ESMF_Field), intent(out), optional :: field + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Realize a field where GeomObject has been set by the NUOPC GeomObject + transfer protocol. + +
+The data of the realized field is left uninitialized by this method. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_SetAttribute() + subroutine NUOPC_SetAttributeField(field, name, value, rc) +ARGUMENTS: +
type(ESMF_Field) :: field + character(*), intent(in) :: name + character(*), intent(in) :: value + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the attribute name inside of field using the + convention NUOPC and purpose Instance. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_SetAttribute() + subroutine NUOPC_SetAttributeState(state, name, value, rc) +ARGUMENTS: +
type(ESMF_State) :: state + character(*), intent(in) :: name + character(*), intent(in) :: value + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the attribute name inside of state using the + convention NUOPC and purpose Instance. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_SetTimestamp() + subroutine NUOPC_SetTimestampField(field, time, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: field + type(ESMF_Time), intent(in) :: time + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the TimeStamp according to time on field. + +
+This call should rarely be needed in user written code. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_SetTimestamp() + subroutine NUOPC_SetTimestampFieldList(fieldList, time, selective, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: fieldList(:) + type(ESMF_Time), intent(in) :: time + logical, intent(in), optional :: selective + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the TimeStamp according to time on field. + +
+This call should rarely be needed in user written code. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_SetTimestamp() + subroutine NUOPC_SetTimestampFieldListClk(fieldList, clock, selective, rc) +ARGUMENTS: +
type(ESMF_Field), intent(inout) :: fieldList(:) + type(ESMF_Clock), intent(in) :: clock + logical, intent(in), optional :: selective + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the TimeStamp according to time on field. + +
+This call should rarely be needed in user written code. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_SetTimestamp() + subroutine NUOPC_SetTimestampState(state, time, selective, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + type(ESMF_Time), intent(in) :: time + logical, intent(in), optional :: selective + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the TimeStamp according to clock on all the fields in + state. Depending on selective, all or only some fields may be + updated. + +
+This call should rarely be needed in user written code. It is used + by the generic Connector. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_SetTimestamp() + subroutine NUOPC_SetTimestampStateClk(state, clock, selective, rc) +ARGUMENTS: +
type(ESMF_State), intent(inout) :: state + type(ESMF_Clock), intent(in) :: clock + logical, intent(in), optional :: selective + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Set the TimeStamp according to clock on all the fields in + state. Depending on selective, all or only some fields may be + updated. + +
+This call should rarely be needed in user written code. It is used + by the generic Connector. + +
+The arguments are: +
+ + +
+ +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Write() + subroutine NUOPC_SCRIPWrite(factorList, factorIndexList, fileName, & + relaxedflag, rc) +ARGUMENTS: +
real(ESMF_KIND_R8), intent(in), target :: factorList(:) + integer, intent(in), target :: factorIndexList(:,:) + character(*), intent(in) :: fileName + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+ Write the destributed interpolaton matrix provided by factorList + and factorIndexList to a SCRIP formatted NetCDF file. Each PET calls + with its local list of factors and indices. The call then writes the + distributed factors into a single file. If the file already exists, the + contents is replaced by this call. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Write() + subroutine NUOPC_FactorsWrite(factorList, fileName, rc) +ARGUMENTS: +
real(ESMF_KIND_R8), pointer :: factorList(:) + character(*), intent(in) :: fileName + integer, intent(out), optional :: rc ++DESCRIPTION: +
+THIS METHOD IS DEPRECATED. Use 3.10.1 instead. + +
+Write the destributed factorList to file. Each PET calls with its + local list of factors. The call then writes the distributed factors into + a single file. The order of the factors in the file is first by PET, and + within each PET the PET-local order is preserved. Changing the number of + PETs for the same regrid operation will likely change the order of factors + across PETs, and therefore files written will differ. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Write() + subroutine NUOPC_FieldWrite(field, fileName, overwrite, status, timeslice, & + iofmt, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_Field), intent(in) :: field + character(*), intent(in) :: fileName + logical, intent(in), optional :: overwrite + type(ESMF_FileStatus_Flag), intent(in), optional :: status + integer, intent(in), optional :: timeslice + type(ESMF_IOFmt_Flag), intent(in), optional :: iofmt + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write the data in field to file under the field's "StandardName" + attribute if supported by the iofmt. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Write() + subroutine NUOPC_StateWrite(state, fieldNameList, fileNamePrefix, overwrite, & + status, timeslice, iofmt, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_State), intent(in) :: state + character(len=*), intent(in), optional :: fieldNameList(:) + character(len=*), intent(in), optional :: fileNamePrefix + logical, intent(in), optional :: overwrite + type(ESMF_FileStatus_Flag), intent(in), optional :: status + integer, intent(in), optional :: timeslice + type(ESMF_IOFmt_Flag), intent(in), optional :: iofmt + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write the data of the fields contained in state to NetCDF files. + Each field is written to an individual file using its "StandardName" + attribute as its NetCDF attribute. + FieldBundle objects that are encountered within state are traversed, + and the contained fields are handled in the same manner as fields directly + held by the state object. + +
+The arguments are: +
+ +
+ +
+ +
+
+INTERFACE:
+
! Private name; call using NUOPC_Write() + subroutine NUOPC_FieldBundleWrite(fieldbundle, fieldNameList, fileNamePrefix, overwrite, & + status, timeslice, iofmt, relaxedflag, rc) +ARGUMENTS: +
type(ESMF_FieldBundle), intent(in) :: fieldbundle + character(len=*), intent(in), optional :: fieldNameList(:) + character(len=*), intent(in), optional :: fileNamePrefix + logical, intent(in), optional :: overwrite + type(ESMF_FileStatus_Flag), intent(in), optional :: status + integer, intent(in), optional :: timeslice + type(ESMF_IOFmt_Flag), intent(in), optional :: iofmt + logical, intent(in), optional :: relaxedflag + integer, intent(out), optional :: rc ++DESCRIPTION: +
+Write the data of the fields contained in fieldbundle to NetCDF files. + Each field is written to an individual file using its "StandardName" + attribute as its NetCDF attribute. + +
+The arguments are: +
+ + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node5.html b/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node5.html new file mode 100644 index 000000000..92db16d6a --- /dev/null +++ b/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node5.html @@ -0,0 +1,718 @@ + + + + + ++DEPRECATION NOTICE: The mechanism described in this section for defining build dependencies between components has been deprecated! The approach discussed here is based exclusively on GNU Makefiles. It has been superseded by the functionality implemented in the ESMX Layer. The ESMX approach addresses all of the issues discussed here, based on a more holistic solution. It includes a standard CMake based option, which is the recommended approach for all new NUOPC projects. + +
+Most of the NUOPC Layer deals with specifying the interaction between ESMF components within a running ESMF application. ESMF provides several mechanisms of how an application can be made up of individual Components. This chapter deals with reigning in the many options supported by ESMF and setting up a standard way for assembling NUOPC compliant components into a working application. + +
+ESMF supports single executable as well as some forms of multiple executable applications. Currently the NUOPC Layer only addresses the case of single executable applications. While it is generally true that executing single executable applications is easier and more widely supported than executing multiple executable applications, building a single executable from multiple components can be challenging. This is especially true when the individual components are supplied by different groups, and the assembly of the final application happens apart from the component development. The purpose of standardizing component dependencies as part of the NUOPC Layer is to provide a solution to the technical aspect of assembling applications built from NUOPC compliant components. + +
+As with the other parts of the NUOPC Layer, the standardized component dependencies specify aspects that ESMF purposefully leaves unspecified. Having a standard way to deal with component dependencies has several advantages. It makes reading and understand NUOPC compliant applications more easily. It also provides a means to promote best practices across a wide range of application systems. Ultimately the goal of standardizing the component dependencies is to support "plug & build" between NUOPC compliant components and applications, where everything needed to use a component by a upper level software layer is supplied in a standard way, ready to be used by the software. + +
+There is one aspect of the standardized component dependency that affects the component code itself: The name of the public set services entry point into a NUOPC compliant component must be called "SetServices". The only exception to this rule are components that are written in C/C++ and made available for static linking. In this case, because of lack of namespace protection, the SetServices part must be followed by a component specific suffix. This will be discussed later in this chapter. For all other cases, unique namespaces exist that allow the entry point to be called SetServices across all components. + +
+Having standardized the name of the single public entry point into a component solves the issue of having to communicate its name to the software layer that intends to use the component. At the same time, limiting the public entry point to a single accepted name does not remove any flexibility that is generally leveraged by ESMF applications. Within the context of the NUOPC Layer, there is great flexibility designed into the initialize steps. Removing the need to have to deal with alternative set services routines focuses and clarifies the NUOPC approach. + +
+The remaining aspects of component dependency standardization all deal with build specific issues, i.e. how does the software layer that uses a component compile and link against the component code. For now the NUOPC Layer does not deal with the question on how the component itself is being built. Instead the focus is on the information that a component must provide about itself, and the format of this information, in order to be usable by another piece of software. This clear separation allows components to provide their own independent build system, which often is critical to ensure bit-for-bit reproducibility. At the same time it does not prevent build systems to be connected top-down if that is desirable. + +
+Technically the problem of passing component specific build information up the build hierarchy is solved by using GNU makefile fragments that allow every component to provide information in form of variables to the upper level build system. The NUOPC Layer standardization requires that: Every component must provide a makefile fragment that defines 6 variables: +
+ ESMF_DEP_FRONT + ESMF_DEP_INCPATH + ESMF_DEP_CMPL_OBJS + ESMF_DEP_LINK_OBJS + ESMF_DEP_SHRD_PATH + ESMF_DEP_SHRD_LIBS ++The convention for makefile fragments is to provide them in files with a suffix of .mk. The NUOPC Layer currently adds no further restriction to the name of the makefile fragment file of a component. There seems little gain in standardizing the name of the NUOPC compliant makefile fragment of a component since the location must be made available anyway, and adding the specific file name at the end of the supplied path does not appear inappropriate. + +
+The meaning of the 6 makefile variables is defined in a manner that supports many different situations, ranging from simple statically linked components to situations where components are made available in shared objects, not loaded by the application until needed during runtime. The design idea of the NUOPC Layer component makefile fragment is to have each component provide a simple makefile fragment that is self-describing. Usage of advanced options requires a more sophisticated build system on the software layer that uses the component, while at the same time the same standard format is able to keep simple situations simple. + +
+An indepth understanding of the capabilities of the NUOPC Layer build dependency standard requires looking at various common cases in detail. The remainder of this chapter is dedicated to this effort. Here a general definition of each variable is provided. + +
+ +
+
+
+
+
+
+
+The following sections discuss how the standard makefile fragment is utilized in common use cases. It shows how the .mk file would need to look like in these cases. Each section further contains hints of how a compliant .mk file can be auto-generated by the component build system (provider side), as well as hints on how it can be used by an upper level software layer (consumer side). Makefile segments provided in these hint sections are not part of the NUOPC Layer component dependency standard. They are only provided here as a convenience to the user, showing best practices of how the standard .mk files can be used in practice. Any specific compiler and linker flags shown in the hint sections are those compliant with the GNU Compiler Collection. + +
+The NUOPC Layer standard only covers the contents of the .mk file itself. + +
+ +
+Statically building a component into the executable requires that the associated files (object files, and for Fortran the associated module files) are available when the application is being built. It makes the component code part of the executable. A change in the component code requires re-compilation and re-linking of the executable. + +
+A NUOPC compliant Fortran component that defines its public entry point in a module called "ABC", where all component code is contained in a single object file called "abc.o", makes itself available by providing the following .mk file: + +
+
+ ESMF_DEP_FRONT = ABC + ESMF_DEP_INCPATH = <absolute path to associated ABC module file> + ESMF_DEP_CMPL_OBJS = <absolute path>/abc.o + ESMF_DEP_LINK_OBJS = <absolute path>/abc.o + ESMF_DEP_SHRD_PATH = + ESMF_DEP_SHRD_LIBS = ++ +
+If, however, the component implementation is spread across several object files (e.g. abc.o and xyz.o), they must all be listed in the ESMF_DEP_LINK_OBJS variable: + +
+
+ ESMF_DEP_FRONT = ABC + ESMF_DEP_INCPATH = <absolute path to associated ABC module file> + ESMF_DEP_CMPL_OBJS = <absolute path>/abc.o + ESMF_DEP_LINK_OBJS = <absolute path>/abc.o <absolute path>/xyz.o + ESMF_DEP_SHRD_PATH = + ESMF_DEP_SHRD_LIBS = ++ +
+In cases that require a large number of object files to be linked into the executable it is often more convenient to provide them in an archive file, e.g. "libABC.a". Archive files are also specified in ESMF_DEP_LINK_OBJS: + +
+
+ ESMF_DEP_FRONT = ABC + ESMF_DEP_INCPATH = <absolute path to associated ABC module file> + ESMF_DEP_CMPL_OBJS = <absolute path>/abc.o + ESMF_DEP_LINK_OBJS = <absolute path>/libABC.a + ESMF_DEP_SHRD_PATH = + ESMF_DEP_SHRD_LIBS = ++ +
+Hints for the provider side: A build rule for creating a compliant self-describing .mk file can be added to the component's makefile. For the case that component "ABC" is implemented in object files listed in variable "OBJS", a build rule that produces "abc.mk" could look like this: + +
+
+.PRECIOUS: %.o +%.mk : %.o + @echo "# ESMF self-describing build dependency makefile fragment" > $@ + @echo >> $@ + @echo "ESMF_DEP_FRONT = ABC" >> $@ + @echo "ESMF_DEP_INCPATH = `pwd`" >> $@ + @echo "ESMF_DEP_CMPL_OBJS = `pwd`/"$< >> $@ + @echo "ESMF_DEP_LINK_OBJS = "$(addprefix `pwd`/, $(OBJS)) >> $@ + @echo "ESMF_DEP_SHRD_PATH = " >> $@ + @echo "ESMF_DEP_SHRD_LIBS = " >> $@ + +abc.mk: $(OBJS) ++ +
+Hints for the consumer side: The format of the NUOPC compliant .mk files allows the consumer side to collect the information provided by multiple components into one set of internal variables. Notice that in the makefile code below it is critical to use the := style assignment instead of a simple = in order to have the assignment be based on the current value of the right hand variables. + +
+
+include abc.mk +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_ABC=$(ESMF_DEP_FRONT) +DEP_INCS := $(DEP_INCS) $(addprefix -I, $(ESMF_DEP_INCPATH)) +DEP_CMPL_OBJS := $(DEP_CMPL_OBJS) $(ESMF_DEP_CMPL_OBJS) +DEP_LINK_OBJS := $(DEP_LINK_OBJS) $(ESMF_DEP_LINK_OBJS) +DEP_SHRD_PATH := $(DEP_SHRD_PATH) $(addprefix -L, $(ESMF_DEP_SHRD_PATH)) +DEP_SHRD_LIBS := $(DEP_SHRD_LIBS) $(addprefix -l, $(ESMF_DEP_SHRD_LIBS)) + +include xyz.mk +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_XYZ=$(ESMF_DEP_FRONT) +DEP_INCS := $(DEP_INCS) $(addprefix -I, $(ESMF_DEP_INCPATH)) +DEP_CMPL_OBJS := $(DEP_CMPL_OBJS) $(ESMF_DEP_CMPL_OBJS) +DEP_LINK_OBJS := $(DEP_LINK_OBJS) $(ESMF_DEP_LINK_OBJS) +DEP_SHRD_PATH := $(DEP_SHRD_PATH) $(addprefix -L, $(ESMF_DEP_SHRD_PATH)) +DEP_SHRD_LIBS := $(DEP_SHRD_LIBS) $(addprefix -l, $(ESMF_DEP_SHRD_LIBS)) ++ +
+Besides the accumulation of information into the internal variables, there is a small amount of processing going on. The module name provided by the ESMF_DEP_FRONT variable is assigned to a pre-processor macro. The intention of this macro is to be used in a Fortran USE statement to access the Fortran module that contains the public access point of the component. + +
+The include paths in ESMF_DEP_INCPATH are prepended with the appropriate compiler flag (here "-I"). The ESMF_DEP_SHRD_PATH and ESMF_DEP_SHRD_LIBS variables are also prepended by the respective compiler and linker flags in case a component brings in a shared library dependencies. + +
+Once the .mk files of all component dependencies have been included and processed in this manner, the internal variables can be used in the build system of the application layer, as shown in the following example: + +
+
+.SUFFIXES: .f90 .F90 .c .C + +%.o : %.f90 + $(ESMF_F90COMPILER) -c $(DEP_FRONTS) $(DEP_INCS) \ +$(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(ESMF_F90COMPILEFREENOCPP) $< + +%.o : %.F90 + $(ESMF_F90COMPILER) -c $(DEP_FRONTS) $(DEP_INCS) \ +$(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(ESMF_F90COMPILEFREECPP) \ +$(ESMF_F90COMPILECPPFLAGS) $< + +%.o : %.c + $(ESMF_CXXCOMPILER) -c $(DEP_FRONTS) $(DEP_INCS) \ +$(ESMF_CXXCOMPILEOPTS) $(ESMF_CXXCOMPILEPATHSLOCAL) $(ESMF_CXXCOMPILEPATHS) \ +$(ESMF_CXXCOMPILECPPFLAGS) $< + +%.o : %.C + $(ESMF_CXXCOMPILER) -c $(DEP_FRONTS) $(DEP_INCS) \ +$(ESMF_CXXCOMPILEOPTS) $(ESMF_CXXCOMPILEPATHSLOCAL) $(ESMF_CXXCOMPILEPATHS) \ +$(ESMF_CXXCOMPILECPPFLAGS) $< + +app: app.o appSub.o $(DEP_LINK_OBJS) + $(ESMF_F90LINKER) $(ESMF_F90LINKOPTS) $(ESMF_F90LINKPATHS) \ +$(ESMF_F90LINKRPATHS) -o $@ $^ $(DEP_SHRD_PATH) $(DEP_SHRD_LIBS) \ +$(ESMF_F90ESMFLINKLIBS) + +app.o: appSub.o +appSub.o: $(DEP_CMPL_OBJS) ++ +
+ +
+Providing a component in form of a shared library requires that the associated files (object files, and for Fortran the associated module files) are available when the application is being built. However, different from the statically linked case, the component code does not become part of the executable, instead it will be loaded separately each time the executable is loaded during start-up. This requires that the executable finds the component shared libraries, on which it depends, during start-up. A change in the component code typically does not require re-compilation and re-linking of the executable, instead a new version of the component shared library will be loaded automatically when it is available at execution start-up. + +
+A NUOPC compliant Fortran component that defines its public entry point in a module called "ABC", where all component code is contained in a single shared library called "libABC.so", makes itself available by providing the following .mk file: + +
+
+ ESMF_DEP_FRONT = ABC + ESMF_DEP_INCPATH = <absolute path to associated ABC module file> + ESMF_DEP_CMPL_OBJS = + ESMF_DEP_LINK_OBJS = + ESMF_DEP_SHRD_PATH = <absolute path to libABC.so> + ESMF_DEP_SHRD_LIBS = libABC.so ++ +
+Hints for the provider side: The following build rule will create a compliant self-describing .mk file ("abc.mk") for a component that is made available as a shared library. The case assumes that component "ABC" is implemented in object files listed in variable "OBJS". + +
+
+.PRECIOUS: %.so +%.mk : %.so + @echo "# ESMF self-describing build dependency makefile fragment" > $@ + @echo >> $@ + @echo "ESMF_DEP_FRONT = ABC" >> $@ + @echo "ESMF_DEP_INCPATH = `pwd`" >> $@ + @echo "ESMF_DEP_CMPL_OBJS = " >> $@ + @echo "ESMF_DEP_LINK_OBJS = " >> $@ + @echo "ESMF_DEP_SHRD_PATH = `pwd`" >> $@ + @echo "ESMF_DEP_SHRD_LIBS = "$* >> $@ + +abc.mk: + +abc.so: $(OBJS) + $(ESMF_CXXLINKER) -shared -o $@ $< + mv $@ lib$@ + rm -f $< ++ +
+Hints for the consumer side: The format of the NUOPC compliant .mk files allows the consumer side to collect the information provided by multiple components into one set of internal variables. This is independent on whether some or all of the components are provided as shared libraries. + +
+The path specified in ESMF_DEP_SHRD_PATH is required when building the executable in order for the linker to find the shared library. Depending on the situation, it may be desirable to also encode this search path into the executable through the RPATH mechanism as shown below. However, in some cases, e.g. when the actual shared library to be used during execution is not available from the same location as during build-time, it may not be useful to encode the RPATH. In either case, having set the LD_LIBRARY_PATH environment variable to the desired location of the shared library at run-time will ensure that the correct library file is found. + +
+Notice that in the makefile code below it is critical to use the := style assignment instead of a simple = in order to have the assignment be based on the current value of the right hand variables. + +
+
+include abc.mk +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_ABC=$(ESMF_DEP_FRONT) +DEP_INCS := $(DEP_INCS) $(addprefix -I, $(ESMF_DEP_INCPATH)) +DEP_CMPL_OBJS := $(DEP_CMPL_OBJS) $(ESMF_DEP_CMPL_OBJS) +DEP_LINK_OBJS := $(DEP_LINK_OBJS) $(ESMF_DEP_LINK_OBJS) +DEP_SHRD_PATH := $(DEP_SHRD_PATH) $(addprefix -L, $(ESMF_DEP_SHRD_PATH)) \ + $(addprefix -Wl$(COMMA)-rpath$(COMMA), $(ESMF_DEP_SHRD_PATH)) +DEP_SHRD_LIBS := $(DEP_SHRD_LIBS) $(addprefix -l, $(ESMF_DEP_SHRD_LIBS)) ++ +
+(Here COMMA is a variable that contains a single comma which would cause syntax issues if it was written into the "addprefix" command directly.) + +
+The internal variables set by the above makefile code can then be used by exactly the same makefile rules shown for the statically linked case. In fact, component "ABC" that comes in through "abc.mk" could either be a statically linked component or a shared library component. The makefile code shown here for the consumer side handles both cases alike. + +
+ +
+Making components available in the form of shared objects allows the executable to be built in the complete absence of any information that depends on the component code. The only information required when building the executable is the name of the shared object file that will supply the component code during run-time. The shared object file of the component can be replaced at will, and it is not until run-time, when the executable actually tries to access the component, that the shared object must be available to be loaded. + +
+A NUOPC compliant component where all component code, including its public access point, is contained in a single shared object called "abc.so", makes itself available by providing the following .mk file: + +
+
+ ESMF_DEP_FRONT = abc.so + ESMF_DEP_INCPATH = + ESMF_DEP_CMPL_OBJS = + ESMF_DEP_LINK_OBJS = + ESMF_DEP_SHRD_PATH = + ESMF_DEP_SHRD_LIBS = ++ +
+The other parts of the .mk file may be utilized in special cases, but typically the shared object should be self-contained. + +
+It is interesting to note that at this level of abstraction, there is no more difference between a component written in Fortran, and a component written in in C/C++. In both cases the public entry point available in the shared object must be SetServices as required by the NUOPC Layer component dependency standard. (NUOPC does allow for customary name mangling by the Fortran compiler.) + +
+Hints for the provider side: The following build rule will create a compliant self-describing .mk file ("abc.mk") for a component that is made available as a shared object. The case assumes that component "ABC" is implemented in object files listed in variable "OBJS". + +
+
+.PRECIOUS: %.so +%.mk : %.so + @echo "# ESMF self-describing build dependency makefile fragment" > $@ + @echo >> $@ + @echo "ESMF_DEP_FRONT = "$< >> $@ + @echo "ESMF_DEP_INCPATH = " >> $@ + @echo "ESMF_DEP_CMPL_OBJS = " >> $@ + @echo "ESMF_DEP_LINK_OBJS = " >> $@ + @echo "ESMF_DEP_SHRD_PATH = " >> $@ + @echo "ESMF_DEP_SHRD_LIBS = " >> $@ + +abc.mk: + +abc.so: $(OBJS) + $(ESMF_CXXLINKER) -shared -o $@ $< + rm -f $< ++ +
+Hints for the consumer side: The format of the NUOPC compliant .mk files still allows the consumer side to collect the information provided by multiple components into one set of internal variables. This still holds when some or all of the components are provided as shared objects. In fact it is very simple to make all of the component sections in the consumer makefile handle both cases. + +
+Notice that in the makefile code below it is critical to use the := style assignment instead of a simple = in order to have the assignment be based on the current value of the right hand variables. + +
+
+include abc.mk +ifneq (,$(findstring .so,$(ESMF_DEP_FRONT))) +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_SO_ABC=\"$(ESMF_DEP_FRONT)\" +else +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_ABC=$(ESMF_DEP_FRONT) +endif +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_ABC=$(ESMF_DEP_FRONT) +DEP_INCS := $(DEP_INCS) $(addprefix -I, $(ESMF_DEP_INCPATH)) +DEP_CMPL_OBJS := $(DEP_CMPL_OBJS) $(ESMF_DEP_CMPL_OBJS) +DEP_LINK_OBJS := $(DEP_LINK_OBJS) $(ESMF_DEP_LINK_OBJS) +DEP_SHRD_PATH := $(DEP_SHRD_PATH) $(addprefix -L, $(ESMF_DEP_SHRD_PATH)) \ + $(addprefix -Wl$(COMMA)-rpath$(COMMA), $(ESMF_DEP_SHRD_PATH)) +DEP_SHRD_LIBS := $(DEP_SHRD_LIBS) $(addprefix -l, $(ESMF_DEP_SHRD_LIBS)) ++ +
+The above makefile segment supports component "ABC" that is described in "abc.mk" to be made available as a Fortran static component, a Fortran shared library, or a shared object. The conditional around assigning variable DEP_FRONTS either leads to having set the macro FRONT_ABC as before, or setting a different macro FRONT_SO_ABC. The former indicates that a Fortran module is available for the component and requires a USE statement in the code. The latter macro indicates that the component is made available through a shared object, and the macro can be used to specify the name of the shared object in the associated call. + +
+Again the internal variables set by the above makefile code can be used by the same makefile rules shown for the statically linked case. + +
+ +
+The NUOPC Layer supports component hierarchies where a component can be a child of another component. This hierarchy of components translates into component build dependencies that must be dealt with in the NUOPC Layer standardization of component dependencies. + +
+A component that sits in an intermediate level of the component hierarchy depends on the components "below" while at the same time it introduces a dependency by itself for the parent further "up" in the hierarchy. Within the NUOPC Layer component dependency standard this means that the intermediate component functions as a consumer of its child components' .mk files, and as a provider of its own .mk file that is then consumed by its parent. In practice this double role translates into passing link dependencies and shared library dependencies through to the parent, while the front and compile dependency is simply defined my the intermediate component itself. + +
+Consider a NUOPC compliant component that defines its public entry point in a module called "ABC", and where all component code is contained in a single object file called "abc.o". Further assume that component "ABC" depends on two components "XXX" and "YYY", where "XXX" provides the .mk file: +
+ ESMF_DEP_FRONT = XXX + ESMF_DEP_INCPATH = <absolute path to the associated XXX module file> + ESMF_DEP_CMPL_OBJS = <absolute path>/xxx.o + ESMF_DEP_LINK_OBJS = <absolute path>/xxx.o + ESMF_DEP_SHRD_PATH = + ESMF_DEP_SHRD_LIBS = ++and "YYY" provides the following: +
+ ESMF_DEP_FRONT = YYY + ESMF_DEP_INCPATH = <absolute path to the associated XXX module file> + ESMF_DEP_CMPL_OBJS = + ESMF_DEP_LINK_OBJS = + ESMF_DEP_SHRD_PATH = <absolute path to libYYY.so> + ESMF_DEP_SHRD_LIBS = libYYY.so ++Then the .mk file provided by "ABC" needs to contain the following information: +
+ ESMF_DEP_FRONT = ABC + ESMF_DEP_INCPATH = <absolute path to the associated ABC module file> + ESMF_DEP_CMPL_OBJS = <absolute path>/abc.o + ESMF_DEP_LINK_OBJS = <absolute path>/abc.o <absolute path>/xxx.o + ESMF_DEP_SHRD_PATH = <absolute path to libYYY.so> + ESMF_DEP_SHRD_LIBS = libYYY.so ++ +
+Hints for an intermediate component that is consumer and provider: For the consumer side it is convenient to collect the information provided by multiple component dependencies into one set of internal variables. However, the details on how some of the imported information is processed into the internal variables depends on whether the intermediate component is going to make itself available for static or dynamic access. + +
+In the static case all link and shared library dependencies must be passed to the next higher level, and these dependencies should simply be collected and passed on to the next level: + +
+
+include xxx.mk +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_XXX=$(ESMF_DEP_FRONT) +DEP_INCS := $(DEP_INCS) $(addprefix -I, $(ESMF_DEP_INCPATH)) +DEP_CMPL_OBJS := $(DEP_CMPL_OBJS) $(ESMF_DEP_CMPL_OBJS) +DEP_LINK_OBJS := $(DEP_LINK_OBJS) $(ESMF_DEP_LINK_OBJS) +DEP_SHRD_PATH := $(DEP_SHRD_PATH) $(ESMF_DEP_SHRD_PATH) +DEP_SHRD_LIBS := $(DEP_SHRD_LIBS) $(ESMF_DEP_SHRD_LIBS) + +include yyy.mk +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_YYY=$(ESMF_DEP_FRONT) +DEP_INCS := $(DEP_INCS) $(addprefix -I, $(ESMF_DEP_INCPATH)) +DEP_CMPL_OBJS := $(DEP_CMPL_OBJS) $(ESMF_DEP_CMPL_OBJS) +DEP_LINK_OBJS := $(DEP_LINK_OBJS) $(ESMF_DEP_LINK_OBJS) +DEP_SHRD_PATH := $(DEP_SHRD_PATH) $(ESMF_DEP_SHRD_PATH) +DEP_SHRD_LIBS := $(DEP_SHRD_LIBS) $(ESMF_DEP_SHRD_LIBS) + +.PRECIOUS: %.o +%.mk : %.o + @echo "# ESMF self-describing build dependency makefile fragment" > $@ + @echo >> $@ + @echo "ESMF_DEP_FRONT = ABC" >> $@ + @echo "ESMF_DEP_INCPATH = `pwd`" >> $@ + @echo "ESMF_DEP_CMPL_OBJS = `pwd`/"$< >> $@ + @echo "ESMF_DEP_LINK_OBJS = `pwd`/"$< $(DEP_LINK_OBJS) >> $@ + @echo "ESMF_DEP_SHRD_PATH = " $(DEP_SHRD_PATH) >> $@ + @echo "ESMF_DEP_SHRD_LIBS = " $(DEP_SHRD_LIBS) >> $@ ++ +
+In the case where the intermediate component is linked into a dynamic library, or a dynamic object, all of its object and shared library dependencies can be linked in. In this case it is more useful to do some processing on the shared library dependencies, and not to include them in the produced .mk file. + +
+
+include xxx.mk +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_XXX=$(ESMF_DEP_FRONT) +DEP_INCS := $(DEP_INCS) $(addprefix -I, $(ESMF_DEP_INCPATH)) +DEP_CMPL_OBJS := $(DEP_CMPL_OBJS) $(ESMF_DEP_CMPL_OBJS) +DEP_LINK_OBJS := $(DEP_LINK_OBJS) $(ESMF_DEP_LINK_OBJS) +DEP_SHRD_PATH := $(DEP_SHRD_PATH) $(addprefix -L, $(ESMF_DEP_SHRD_PATH)) \ + $(addprefix -Wl$(COMMA)-rpath$(COMMA), $(ESMF_DEP_SHRD_PATH)) +DEP_SHRD_LIBS := $(DEP_SHRD_LIBS) $(addprefix -l, $(ESMF_DEP_SHRD_LIBS)) + +include yyy.mk +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_YYY=$(ESMF_DEP_FRONT) +DEP_INCS := $(DEP_INCS) $(addprefix -I, $(ESMF_DEP_INCPATH)) +DEP_CMPL_OBJS := $(DEP_CMPL_OBJS) $(ESMF_DEP_CMPL_OBJS) +DEP_LINK_OBJS := $(DEP_LINK_OBJS) $(ESMF_DEP_LINK_OBJS) +DEP_SHRD_PATH := $(DEP_SHRD_PATH) $(addprefix -L, $(ESMF_DEP_SHRD_PATH)) \ + $(addprefix -Wl$(COMMA)-rpath$(COMMA), $(ESMF_DEP_SHRD_PATH)) +DEP_SHRD_LIBS := $(DEP_SHRD_LIBS) $(addprefix -l, $(ESMF_DEP_SHRD_LIBS)) + +.PRECIOUS: %.o +%.mk : %.o + @echo "# ESMF self-describing build dependency makefile fragment" > $@ + @echo >> $@ + @echo "ESMF_DEP_FRONT = ABC" >> $@ + @echo "ESMF_DEP_INCPATH = `pwd`" >> $@ + @echo "ESMF_DEP_CMPL_OBJS = `pwd`/"$< >> $@ + @echo "ESMF_DEP_LINK_OBJS = `pwd`/"$< >> $@ + @echo "ESMF_DEP_SHRD_PATH = " >> $@ + @echo "ESMF_DEP_SHRD_LIBS = " >> $@ ++ +
+ +
+ESMF provides a basic C API that supports writing components in C or C++. There is currently no C version of the NUOPC Layer API available, making it harder, but not impossible to write NUOPC Layer compliant ESMF components in C/C++. For the sake of completeness, the NUOPC component dependency standardization does cover the case of components being written in C/C++. + +
+The issue of whether a component is written in Fortran or C/C++ only matters when the dependent software layer has a compile dependency on the component. In other words, components that are accessed through a shared object have no compile dependency, and the language is of no effect (see 4.3). However, components that are statically linked or made available through shared libraries do introduce compile dependencies. These compile dependencies become language dependent: a Fortran component must be accessed via the USE statement, while a component with a C interface must be accessed via #include. + +
+The decision between the three cases: compile dependency on a Fortran component, compile dependency on a C/C++ component, or no compile dependency can be made on the ESMF_DEP_FRONT variable. By default it is assumed to contain the name of the Fortran module that provides the public entry point into a component written in Fortran. However, if the contents of the ESMF_DEP_FRONT variable ends in .h, it is interpreted as the header file of a component with a C interface. Finally, if it ends in .so, there is no compile dependency, and the component is accessible through a shared object. + +
+A NUOPC compliant component written in C/C++ that defines its public access point in "abc.h", where all component code is contained in a single object file called "abc.o", makes itself available by providing the following .mk file: + +
+
+ ESMF_DEP_FRONT = abc.h + ESMF_DEP_INCPATH = <absolute path to abc.h> + ESMF_DEP_CMPL_OBJS = <absolute path>/abc.o + ESMF_DEP_LINK_OBJS = <absolute path>/abc.o + ESMF_DEP_SHRD_PATH = + ESMF_DEP_SHRD_LIBS = ++ +
+Hints for the implementor: + +
+There are a few subtle complications to cover for the case where a component with C interface comes in as a compile dependency. First there is Fortran name mangling of symbols which includes underscores, but also changes to lower or upper case letters. The ESMF C interface provides a macro (FTN_X) that deals with the underscore issue on the C component side, but it cannot address the lower/upper case issue. The ESMF convention for using C in Fortran assumes all external symbols lower case. The NUOPC Layer follows this convention in accessing components with C interface from Fortran. + +
+Secondly, there is no namespace protection of the public entry points. For this reason, the public entry point cannot just be setservices for all components written in C. Instead, for components with C interface, the public entry point must be setservices_name, where "name" is the same as the root name of the header file specified in ESMF_DEP_FRONT. (The absence of namespace protection is still an issue where multiple C components with the same name are specified. This case requires that components are renamed to something more unique.) + +
+Finally there is the issue of providing an explicit Fortran interface for the public entry point. One way of handling this is to provide the explicit Fortran interface as part of the components header file. This is essentially a few lines of Fortran code that can be used by the upper software layer to implement the explicit interface. As such it must be protected from being processed by the C/C++ compiler: + +
+
+#if (defined __STDC__ || defined __cplusplus) + +// ---------- C/C++ block ------------ + +#include "ESMC.h" +extern "C" { + void FTN_X(setservices_abc)(ESMC_GridComp gcomp, int *rc); +} + +#else + +!! ---------- Fortran block ---------- + +interface + subroutine setservices_abc(gcomp, rc) + use ESMF + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + end subroutine +end interface + +#endif ++ +
+An upper level software layer that intends to use a component that comes with such a header file can then use it directly on the Fortran side to make the component available with an explicit interface. For example, assuming the macro FRONT_H_ATMF holds the name of the associated header file: + +
+
+#ifdef FRONT_H_ATMF +module ABC +#include FRONT_H_ATMF +end module +#endif ++ +
+This puts the explicit interface of the setservices_abc entry point into a module named "ABC". Except for this small block of code, the C/C++ component becomes indistinguishable from a component implemented in Fortran. + +
+Hints for the provider side: Adding a build rule for creating a compliant self-describing .mk file into the component's makefile is straightforward. For the case that the component in "abc.h" is implemented in object files listed in variable "OBJS", a build rule that produces "abc.mk" could look like this: + +
+
+.PRECIOUS: %.o +%.mk : %.o + @echo "# ESMF self-describing build dependency makefile fragment" > $@ + @echo >> $@ + @echo "ESMF_DEP_FRONT = abc.h" >> $@ + @echo "ESMF_DEP_INCPATH = `pwd`" >> $@ + @echo "ESMF_DEP_CMPL_OBJS = `pwd`/"$< >> $@ + @echo "ESMF_DEP_LINK_OBJS = `pwd`/"$< >> $@ + @echo "ESMF_DEP_SHRD_PATH = " >> $@ + @echo "ESMF_DEP_SHRD_LIBS = " >> $@ + +abc.mk: + +abc.o: abc.h ++ +
+Hints for the consumer side: The format of the NUOPC compliant .mk files still allows the consumer side to collect the information provided by multiple components into one set of internal variables. This still holds even when any of the provided components could come in as a Fortran component for static linking, as a C/C++ component for static linking, or as a shared object. All of the component sections in the consumer makefile can be made capable of handling all three cases. However, if it is clear that a certain component is for sure supplied as one of these flavors, it may be clearer to hard-code support for only one mechanism for this component. + +
+Notice that in the makefile code below it is critical to use the := style assignment instead of a simple = in order to have the assignment be based on the current value of the right hand variables. + +
+This example shows how the section for a specific component can be made compatible with all component dependency modes: + +
+
+include abc.mk +ifneq (,$(findstring .h,$(ESMF_DEP_FRONT))) +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_H_ABC=\"$(ESMF_DEP_FRONT)\" +else ifneq (,$(findstring .so,$(ESMF_DEP_FRONT))) +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_SO_ABC=\"$(ESMF_DEP_FRONT)\" +else +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_ABC=$(ESMF_DEP_FRONT) +endif +DEP_FRONTS := $(DEP_FRONTS) -DFRONT_ABC=$(ESMF_DEP_FRONT) +DEP_INCS := $(DEP_INCS) $(addprefix -I, $(ESMF_DEP_INCPATH)) +DEP_CMPL_OBJS := $(DEP_CMPL_OBJS) $(ESMF_DEP_CMPL_OBJS) +DEP_LINK_OBJS := $(DEP_LINK_OBJS) $(ESMF_DEP_LINK_OBJS) +DEP_SHRD_PATH := $(DEP_SHRD_PATH) $(addprefix -L, $(ESMF_DEP_SHRD_PATH)) \ + $(addprefix -Wl$(COMMA)-rpath$(COMMA), $(ESMF_DEP_SHRD_PATH)) +DEP_SHRD_LIBS := $(DEP_SHRD_LIBS) $(addprefix -l, $(ESMF_DEP_SHRD_LIBS)) ++ +
+The above makefile segment will end up setting macro FRONT_H_ABC to the header file name, if the component described in "abc.mk" is a C/C++ component. It will instead set macro FRONT_SO_ABC to the shared object if this is how the component is made available, or set macro FRONT_ABC to the Fortran module name if that is the mechanism for gaining access to the component code. The calling code can use these macros to activate the corresponding code, as well as has access to the required name string in each case + +
+The internal variables set by the above makefile code can be used by the same makefile rules shown for the statically linked case. This usage implements the correct dependency rules, and passes the macros through the compiler flags. + +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node6.html b/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node6.html new file mode 100644 index 000000000..165e1bd1e --- /dev/null +++ b/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node6.html @@ -0,0 +1,356 @@ + + + + + ++The NUOPC Layer introduces a modeling system architecture based on Models, Mediators, Connectors, and Drivers. The Layer defines the rules of engagement between these components. Many of these rules are formulated on the basis of metadata. This metadata can be expected for compliance. + +
+One of the challenges when inspecting a component for NUOPC Layer compliance is that many of the rules of engagement are run-time rules. This means that they address the dynamical behavior of a component during run-time. For this reason, comprehensive compliance testing cannot be done statically but requires the execution of code. + +
+Currently there are two sets of tools available to address the issue of NUOPC Layer compliance testing. The Compliance Checker is a runtime analysis tool that can be enabled by setting an ESMF environment variable at runtime. When active, the Compliance Checker intercepts all interactions between components that go throught the ESMF component interface, and analyzes them with respect to the NUOPC Layer rules of engagement. Warnings are printed to the log files when issues or non-compliances are detected. + +
+The Component Explorer is another compliance testing tool. It focuses on interacting with a single component, and analyzing it during the early initialization phases. The Component Explorer and Compliance Checker are compatible with each other and it is often useful to use them both at the same time. + +
+The NUOPC Compliance Checker is a run-time analysis tool that can be turned on for any ESMF application. The Compliance Checker is turned off by default, as to not negatively affect performance critical runs. The Compliance Checker is enabled by setting the following ESMF runtime environment variable: +
+ESMF_RUNTIME_COMPLIANCECHECK=ON ++As a run-time variable, setting it does not require recompilation of the ESMF library or the user application. The same executable and library will start to generate Compliance Checker output when the above variable is found set during execution. + +
+The function of the Compliance Checker is to intercept all interactions between the components of an ESMF application, and to analyze them according to the NUOPC Layer rules of engagement. The following aspects are currently reported on: + +
+Besides the above aspects, the output of the Compliance Checker also provides a means to easily get an idea of the exact dynamical control flow between the components of an application. + +
+The Compliance Checker uses the ESMF Log facility to produce the compliance report during the execution of an ESMF application. The output is located in the default ESMF Log files. There are advantages of using the existing Log facility to generate the compliance report. First, the ESMF Log facility offers time stamping of messages, and deals with all of the file access and multi-PET issues. Second, going through the ESMF Log guarantees that all the output appears in the correct chronological order. This applies to all of the output, including entries from other ESMF system levels or from the user level. + +
+A sample output of the Compliance Checker output in action: + +
+
+20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM:>START register compliance check. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: phase Zero for Initialize registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: 5 phase(s) of Initialize registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: 1 phase(s) of Run registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: 1 phase(s) of Finalize registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM:>STOP register compliance check. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM2MED:>START register compliance check. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM2MED: phase Zero for Initialize registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM2MED: 3 phase(s) of Initialize registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM2MED: 1 phase(s) of Run registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM2MED: 1 phase(s) of Finalize registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM2MED:>STOP register compliance check. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:MED2ATM:>START register compliance check. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:MED2ATM: phase Zero for Initialize registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:MED2ATM: 3 phase(s) of Initialize registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:MED2ATM: 1 phase(s) of Run registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:MED2ATM: 1 phase(s) of Finalize registered. +20131108 172844.458 INFO PET0 COMPLIANCECHECKER:|->|->|->:MED2ATM:>STOP register compliance check. +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: >START InitializePrologue for phase= 0 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: importState name: modelComp 1 Import State +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: importState stateintent: ESMF_STATEINTENT_IMPORT +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: importState itemCount: 0 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: exportState name: modelComp 1 Export State +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: exportState stateintent: ESMF_STATEINTENT_EXPORT +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: exportState itemCount: 0 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM:ESMF Stats: the virtual memory used by this PET (in KB): 974868 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM:ESMF Stats: the physical memory used by this PET (in KB): 49440 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM:ESMF Stats: ESMF Fortran objects referenced by the ESMF garbage collection: 0 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM:ESMF Stats: ESMF objects (F & C++) referenced by the ESMF garbage collection: 0 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|->|->|->:ATM: >STOP InitializePrologue for phase= 0 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: >START InitializeEpilogue for phase= 0 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM:ESMF Stats: the virtual memory used by this PET (in KB): 974868 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM:ESMF Stats: the physical memory used by this PET (in KB): 49448 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM:ESMF Stats: ESMF Fortran objects referenced by the ESMF garbage collection: 0 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM:ESMF Stats: ESMF objects (F & C++) referenced by the ESMF garbage collection: 0 +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: GridComp level attribute check: convention: 'NUOPC', purpose: 'General'. +20131108 172844.459 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> Component level attribute: <ShortName> present but NOT set! +20131108 172844.459 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> Component level attribute: <LongName> present but NOT set! +20131108 172844.459 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> Component level attribute: <Description> present but NOT set! +20131108 172844.459 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> Component level attribute: <ModelType> present but NOT set! +20131108 172844.459 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> Component level attribute: <ReleaseDate> present but NOT set! +20131108 172844.459 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> Component level attribute: <PreviousVersion> present but NOT set! +20131108 172844.459 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> Component level attribute: <ResponsiblePartyRole> present but NOT set! +20131108 172844.459 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> Component level attribute: <Name> present but NOT set! +20131108 172844.459 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> Component level attribute: <EmailAddress> present but NOT set! +20131108 172844.459 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> Component level attribute: <PhysicalAddress> present but NOT set! +20131108 172844.459 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> Component level attribute: <URL> present but NOT set! +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: Component level attribute: <Verbosity> present and set: high +20131108 172844.459 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: Component level attribute: <InitializePhaseMap>[1] present and set: IPDv02p1=1 +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: Component level attribute: <InitializePhaseMap>[2] present and set: IPDv02p3=2 +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: Component level attribute: <InitializePhaseMap>[3] present and set: IPDv02p4=3 +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: Component level attribute: <InitializePhaseMap>[4] present and set: IPDv02p5=5 +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: Component level attribute: <NestingGeneration> present and set: 0 +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: Component level attribute: <Nestling> present and set: 0 +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: importState name: modelComp 1 Import State +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: importState stateintent: ESMF_STATEINTENT_IMPORT +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: importState itemCount: 0 +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: exportState name: modelComp 1 Export State +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: exportState stateintent: ESMF_STATEINTENT_EXPORT +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: exportState itemCount: 0 +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: The incoming Clock was not modified. +20131108 172844.460 WARNING PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: ==> The internal Clock is not present! +20131108 172844.460 INFO PET0 COMPLIANCECHECKER:|<-|<-|<-:ATM: >STOP InitializeEpilogue for phase= 0 ++ +
+All of the output generated by the Compliance Checker contains the string COMPLIANCECHECK, which can be used to grep on. The checker currently generates two types of messages, INFO for general analysis output, and WARNING for when issues with respect to the NUOPC Layer rules are detected. + +
+In practice, when dealing with applications that have been componentized down to a very low level of the model, the output generated by the Compliance Checker can become overwhelming. For this reason a depth parameter is available that can be specified for the Compliance Checker environment variable: +
+ESMF_RUNTIME_COMPLIANCECHECK=ON:depth=4 ++This will limit the number of component levels that the Compliance Checker parses (here 4 levels), starting from the top level application. + +
+ +
+The NUOPC Component Explorer is a run-time tool that can be used to gain insight into a NUOPC Layer compliant component, or to test a component's compliance. The Component Explorer is currently available as a separate download from the prototype repository: + +
+
+https://github.com/esmf-org/nuopc-app-prototypes/tree/develop/AtmOcnProto ++ +
+There are two parts to the Component Explorer. First the script nuopcExplorerScript is used to compile and link the explorer application specifically against a specified component. This part of the explorer leverages and tests the standardized component dependencies discussed in section 4. This step is initiated by calling the explorer script with the component's mk-file as an argument: + +
+
+./nuopcExplorerScript <component-mk-file> ++ +
+Any issues found during this step are reported. The successful completion of this step will produce an executable called nuopcExplorerApp. Success is indicated by + +
+
+SUCCESS: nuopcExplorerApp successfully built +...exiting nuopcExplorerScript. ++ +
+and failure by + +
+
+FAILURE: nuopcExplorerApp failed to build +...exiting nuopcExplorerScript. ++ +
+The second part of the Component Explorer is the explorer application itself. It can either be built using the explorer script as outlined above (recommended when a makefile fragment for the component is available) or by using the makefile directly: + +
+
+make nuopcExplorerApp ++ +
+In the second case the resulting nuopcExplorerApp is not tied to a specific component, instead the executable expects a component in form of a shared object to be specified as a command line argument when executing nuopcExplorerApp. In either case the explorer application needs to be started according to the execution requirements of the component it attempts to explore. This may mean that input files must be present, and that the executable be launched on a sufficient number of processes. In terms of the common mpirun tool, launching of nuopcExplorerApp may look like this +
+mpirun -np X ./nuopcExplorerApp ++for an executable that was built against a specific component. Or like this +
+mpirun -np X ./nuopcExplorerApp <component-shared-object-file> ++for an executable that expects a the component in form of a shared object. + +
+The nuopcExplorerApp expects to find a configuration file by the name of explorer.config in the run directory. The configuration file contains several basic model parameter used to explore the component. An example configuration file is shown here: + +
+
+### NUOPC Component Explorer configuration file ### + +start_year: 2009 +start_month: 12 +start_day: 01 +start_hour: 00 +start_minute: 0 +start_second: 0 + +stop_year: 2009 +stop_month: 12 +stop_day: 03 +stop_hour: 00 +stop_minute: 0 +stop_second: 0 + +step_seconds: 21600 + +filter_initialize_phases: no + +enable_run: yes +enable_finalize: yes ++ +
+The nuopcExplorerApp starts to interact with the specified component, using the information read in from the configuration file. During the interaction the finding are reported to stdout, with output that will look similar to this: + +
+
+ NUOPC Component Explorer App + ---------------------------- + Exploring a component with a Fortran module front... + Model component # 1 InitializePhaseMap: + IPDv00p1=1 + IPDv00p2=2 + IPDv00p3=3 + IPDv00p4=4 + Model component # 1 // name = ocnA + ocnA: <LongName> : Attribute is present but NOT set! + ocnA: <ShortName> : Attribute is present but NOT set! + ocnA: <Description> : Attribute is present but NOT set! + -------- + ocnA: importState // itemCount = 2 + ocnA: importState // item # 001 // [FIELD] name = pmsl + <StandardName> = air_pressure_at_sea_level + <Units> = Pa + <LongName> = Air Pressure at Sea Level + <ShortName> = pmsl + ocnA: importState // item # 002 // [FIELD] name = rsns + <StandardName> = surface_net_downward_shortwave_flux + <Units> = W m-2 + <LongName> = Surface Net Downward Shortwave Flux + <ShortName> = rsns + -------- + ocnA: exportState // itemCount = 1 + ocnA: exportState // item # 001 // [FIELD] name = sst + <StandardName> = sea_surface_temperature + <Units> = K + <LongName> = Sea Surface Temperature + <ShortName> = sst ++ +
+Turning on the Compliance Checker (see section 5.1) will result in additional information in the log files. + +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node7.html b/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node7.html new file mode 100644 index 000000000..1d13ce0e2 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/NUOPC_refdoc/node7.html @@ -0,0 +1,79 @@ + + + + + +
+
+
+
+ |
+IMPORTANT: Use of explicit Initialize Phase Definition versions and phase labels is deprecated - this section is provided only for reference for NUOPC caps that still use the IPD syntax. See the section on Semantic Specialization Labels for the preferred method of specializing NUOPC caps. + +
+The interaction between NUOPC compliant components during the initialization process is regulated by the Initialize Phase Definition or IPD. The IPDs are versioned, with a higher version number indicating backward compatibility with all previous versions. + +
+There are two perspectives of looking at the IPD. From the driver perspective the IPD regulates the sequence in which it must call the different phases of the Initialize() routines of its child components. To this end the generic NUOPC_Driver component implements support for IPDs up to a version specified in the API documentation. + +
+The other angle of looking at the IPD is from the driver's child components. From this perspective the IPD assigns specific meaning to each initialize phase. The child components of a driver can be divided into two groups with respect to the meaning the IPD assigns to each initialize phase. In one group are the model, mediator, and driver components, and in the other group are the connector components. Child components publish their available initialize phases through the InitializePhaseMap attribute. + +
+The driver also calls into its own internal initialize methods. This allows the driver to participate in the initialization of its children in a structured fashion. The internal initialization phases of a driver are published via the InternalInitializePhaseMap attribute. + +
+The following tables document the meaning of each initialization phase of the available IPD versions for the child components and for the driver component itself. The phases are listed in the sequence in which the driver calls them.
+
+
+
+
+
+
+
IPDv00 label | +Component | +Meaning | +
IPDv00p1 | +driver-internal | +unspecified by NUOPC | +
IPDv00p1 | +models, mediators, drivers | +Advertise their import and export Fields. | +
IPDv00p1 | +connectors | +Construct their CplList Attribute. | +
IPDv00p2 | +driver-internal | +unspecified by NUOPC | +
IPDv00p2 | +models, mediators, drivers | +Realize their import and export Fields. | +
IPDv00p2a | +connectors | +Set the Connected Attribute on each import and export Field according to the CplList Attribute. Reconcile the import and export States. | +
IPDv00p2b | +connectors | +Precompute the RouteHandle. | +
IPDv00p3 | +driver-internal | +unspecified by NUOPC | +
IPDv00p3 | +models, mediators, drivers | +Check for compatibility of their Fields' Connected status. | +
IPDv00p4 | +driver-internal | +unspecified by NUOPC | +
IPDv00p4 | +models, mediators, drivers | +Handle Field data initialization. Timestamp their export Fields. | +
+
+
+
+
+
IPDv01 label | +Component | +Meaning | +
IPDv01p1 | +driver-internal | +unspecified by NUOPC | +
IPDv01p1 | +models, mediators, drivers | +Advertise their import and export Fields. | +
IPDv01p1 | +connectors | +Construct their CplList Attribute. | +
IPDv01p2 | +driver-internal | +Modify the CplList Attributes on the Connectors. | +
IPDv01p2 | +models, mediators, drivers | +unspecified/unused by NUOPC | +
IPDv01p2 | +connectors | +Set the Connected Attribute on each import and export Field according to the CplList Attribute. | +
IPDv01p3 | +driver-internal | +unspecified by NUOPC | +
IPDv01p3 | +models, mediators, drivers | +Realize their "connected" import and export Fields. | +
IPDv01p3a | +connectors | +Reconcile the import and export States. | +
IPDv01p3b | +connectors | +Precompute the RouteHandle according to the CplList Attribute. | +
IPDv01p4 | +driver-internal | +unspecified by NUOPC | +
IPDv01p4 | +models, mediators, drivers | +Check for compatibility of their Fields' Connected status. | +
IPDv01p5 | +driver-internal | +unspecified by NUOPC | +
IPDv01p5 | +models, mediators, drivers | +Handle Field data initialization. Timestamp their export Fields. | +
+
+
+
+
+
IPDv02 label | +Component | +Meaning | +
IPDv02p1 | +driver-internal | +unspecified by NUOPC | +
IPDv02p1 | +models, mediators, drivers | +Advertise their import and export Fields. | +
IPDv02p1 | +connectors | +Construct their CplList Attribute. | +
IPDv02p2 | +driver-internal | +Modify the CplList Attributes on the Connectors. | +
IPDv02p2 | +models, mediators, drivers | +unspecified/unused by NUOPC | +
IPDv02p2 | +connectors | +Set the Connected Attribute on each import and export Field according to the CplList Attribute. | +
IPDv02p3 | +driver-internal | +unspecified by NUOPC | +
IPDv02p3 | +models, mediators, drivers | +Realize their "connected" import and export Fields. | +
IPDv02p3a | +connectors | +Reconcile the import and export States. | +
IPDv02p3b | +connectors | +Precompute the RouteHandle according to the CplList Attribute. | +
IPDv02p4 | +driver-internal | +unspecified by NUOPC | +
IPDv02p4 | +models, mediators, drivers | +Check for compatibility of their Fields' Connected status. | +
IPDv02p5 | +driver-internal | +unspecified by NUOPC | +
IPDv02p5 | +models, mediators, drivers | +Handle Field data initialization. Timestamp their export Fields. | +
A loop is entered over all those model, mediator, driver Components that use IPDv02 and have + unsatisfied data dependencies, repeating the following two steps: | +||
Run() | +connectors | +Loop over all Connectors that connect to the Component that is currently indexed by the outer loop. | +
IPDv02p5 | +models, mediators, drivers | +Handle Field data initialization. Timestamp their export Fields and set the Updated and InitializeDataComplete Attributes accordingly. | +
Repeat these two steps until all data + dependencies have been statisfied, or a dead-lock situation is detected. | +
+
+
+
+
+
IPDv03 label | +Component | +Meaning | +
IPDv03p1 | +driver-internal | +unspecified by NUOPC | +
IPDv03p1 | +models, mediators, drivers | +Advertise their import and export Fields and set the TransferOfferGeomObject Attribute. | +
IPDv03p1 | +connectors | +Construct their CplList Attribute. | +
IPDv03p2 | +driver-internal | +Modify the CplList Attributes on the Connectors. | +
IPDv03p2 | +models, mediators, drivers | +unspecified/unused by NUOPC | +
IPDv03p2 | +connectors | +Set the Connected Attribute on each import and export Field according to the CplList Attribute. Set the TransferActionGeomObject Attribute. | +
IPDv03p3 | +driver-internal | +unspecified by NUOPC | +
IPDv03p3 | +models, mediators, drivers | +Realize their "connected" import and export Fields that have TransferActionGeomObject equal to "provide". | +
IPDv03p3 | +connectors | +Transfer the Grid/Mesh/LocStream objects (only DistGrid) for Field pairs that have a provider and an acceptor side. | +
IPDv03p4 | +driver-internal | +unspecified by NUOPC | +
IPDv03p4 | +models, mediators, drivers | +Optionally modify the decomposition and distribution information of the accepted Grid/Mesh/LocStream by replacing the DistGrid. | +
IPDv03p4 | +connectors | +Transfer the full Grid/Mesh/LocStream objects (with coordinates) for Field pairs that have a provider and an acceptor side. | +
IPDv03p5 | +driver-internal | +unspecified by NUOPC | +
IPDv03p5 | +models, mediators, drivers | +Realize all Fields that have TransferActionGeomObject equal to "accept" on the transferred Grid/Mesh/LocStream objects. | +
IPDv03p5a | +connectors | +Reconcile the import and export States. | +
IPDv03p5b | +connectors | +Precompute the RouteHandle according to the CplList Attribute. | +
IPDv03p6 | +driver-internal | +unspecified by NUOPC | +
IPDv03p6 | +models, mediators, drivers | +Check compatibility of their Fields' Connected status. | +
IPDv03p7 | +driver-internal | +unspecified by NUOPC | +
IPDv03p7 | +models, mediators, drivers | +Handle Field data initialization. Timestamp the export Fields. | +
A loop is entered over all those model, mediator, driver Components that use IPDv02 and have + unsatisfied data dependencies, repeating the following two steps: | +||
Run() | +connectors | +Loop over all Connectors that connect to the Component that is currently indexed by the outer loop. | +
IPDv03p7 | +models, mediators, drivers | +Handle Field data initialization. Time stamp the export Fields and set the Updated and InitializeDataComplete Attributes accordingly. | +
Repeat these two steps until all data + dependencies have been statisfied, or a dead-lock situation is detected. | +
+
+
+
+
+
IPDv04 label | +Component | +Meaning | +
IPDv04p1 | +driver-internal | +unspecified by NUOPC | +
IPDv04p1 | +models, mediators, drivers | +Advertise their import and export Fields and set the TransferOfferGeomObject Attribute. | +
IPDv04p1a | +connectors | +Consider all connection possibilities for their CplList Attribute. | +
IPDv04p1b | +connectors | +Unambiguous construction of their CplList Attribute. | +
IPDv04p2 | +driver-internal | +Modify the CplList Attributes on the Connectors. | +
IPDv04p2 | +models, mediators, drivers | +unspecified/unused by NUOPC | +
IPDv04p2 | +connectors | +Set the Connected Attribute on each import and export Field according to the CplList Attribute. Set the TransferActionGeomObject Attribute. | +
IPDv04p3 | +driver-internal | +unspecified by NUOPC | +
IPDv04p3 | +models, mediators, drivers | +Realize their "connected" import and export Fields that have TransferActionGeomObject equal to "provide". | +
IPDv04p3 | +connectors | +Transfer the Grid/Mesh/LocStream objects (only DistGrid) for Field pairs that have a provider and an acceptor side. | +
IPDv04p4 | +driver-internal | +unspecified by NUOPC | +
IPDv04p4 | +models, mediators, drivers | +Optionally modify the decomposition and distribution information of the accepted Grid/Mesh/LocStream by replacing the DistGrid. | +
IPDv04p4 | +connectors | +Transfer the full Grid/Mesh/LocStream objects (with coordinates) for Field pairs that have a provider and an acceptor side. | +
IPDv04p5 | +driver-internal | +unspecified by NUOPC | +
IPDv04p5 | +models, mediators, drivers | +Realize all Fields that have TransferActionGeomObject equal to "accept" on the transferred Grid/Mesh/LocStream objects. | +
IPDv04p5a | +connectors | +Reconcile the import and export States. | +
IPDv04p5b | +connectors | +Precompute the RouteHandle according to the CplList Attribute. | +
IPDv04p6 | +driver-internal | +unspecified by NUOPC | +
IPDv04p6 | +models, mediators, drivers | +Check compatibility of their Fields' Connected status. | +
IPDv04p7 | +driver-internal | +unspecified by NUOPC | +
IPDv04p7 | +models, mediators, drivers | +Handle Field data initialization. Timestamp the export Fields. | +
A loop is entered over all those model, mediator, driver Components that use IPDv02 and have + unsatisfied data dependencies, repeating the following two steps: | +||
Run() | +connectors | +Loop over all Connectors that connect to the Component that is currently indexed by the outer loop. | +
IPDv04p7 | +models, mediators, drivers | +Handle Field data initialization. Time stamp the export Fields and set the Updated and InitializeDataComplete Attributes accordingly. | +
Repeat these two steps until all data + dependencies have been statisfied, or a dead-lock situation is detected. | +
+
+
+
+
+
IPDv05 label | +Component | +Meaning | +
IPDv05p1 | +driver-internal | +Advertise import and export Fields and set the TransferOfferGeomObject Attribute. Optionally set FieldTransferPolicy Attribute on States. | +
IPDv05p1 | +models, mediators, drivers | +Advertise their import and export Fields and set the TransferOfferGeomObject Attribute. Optionally set FieldTransferPolicy Attribute on States. | +
IPDv05p1 | +connectors | +Consider FieldTransferPolicy Attribute on import and export States. Advertise Fields to be transferred. | +
IPDv05p2 | +driver-internal | +Optionally modify import and export States before connectors construct CplList Attribute. | +
IPDv05p2 | +models, mediators, drivers | +Optionally modify import and export States before connectors construct CplList Attribute. | +
IPDv05p2a | +connectors | +Consider all connection possibilities for their CplList Attribute. | +
IPDv05p2b | +connectors | +Unambiguous construction of their CplList Attribute. | +
IPDv05p3 | +driver-internal | +Modify the CplList Attributes on the Connectors. | +
IPDv05p3 | +models, mediators, drivers | +unspecified/unused by NUOPC | +
IPDv05p3 | +connectors | +Set the Connected Attribute on each import and export Field according to the CplList Attribute. Set the TransferActionGeomObject Attribute. | +
IPDv05p4 | +driver-internal | +Realize "connected" import and export Fields that have TransferActionGeomObject equal to "provide". | +
IPDv05p4 | +models, mediators, drivers | +Realize their "connected" import and export Fields that have TransferActionGeomObject equal to "provide". | +
IPDv05p4 | +connectors | +Transfer the Grid/Mesh/LocStream objects (only DistGrid) for Field pairs that have a provider and an acceptor side. | +
IPDv05p5 | +driver-internal | +Optionally modify the decomposition and distribution information of the accepted Grid/Mesh/LocStream by replacing the DistGrid. | +
IPDv05p5 | +models, mediators, drivers | +Optionally modify the decomposition and distribution information of the accepted Grid/Mesh/LocStream by replacing the DistGrid. | +
IPDv05p5 | +connectors | +Transfer the full Grid/Mesh/LocStream objects (with coordinates) for Field pairs that have a provider and an acceptor side. | +
IPDv05p6 | +driver-internal | +Realize all Fields that have TransferActionGeomObject equal to "accept" on the transferred Grid/Mesh/LocStream objects. | +
IPDv05p6 | +models, mediators, drivers | +Realize all Fields that have TransferActionGeomObject equal to "accept" on the transferred Grid/Mesh/LocStream objects. | +
IPDv05p6a | +connectors | +Reconcile the import and export States. | +
IPDv05p6b | +connectors | +Precompute the RouteHandle according to the CplList Attribute. | +
IPDv05p7 | +driver-internal | +unspecified by NUOPC | +
IPDv05p7 | +models, mediators, drivers | +Check compatibility of their Fields' Connected status. | +
IPDv05p8 | +driver-internal | +unspecified by NUOPC | +
IPDv05p8 | +models, mediators, drivers | +Handle Field data initialization. Timestamp the export Fields. | +
A loop is entered over all those model, mediator, driver Components that use IPDv02 and have + unsatisfied data dependencies, repeating the following two steps: | +||
Run() | +connectors | +Loop over all Connectors that connect to the Component that is currently indexed by the outer loop. | +
IPDv05p8 | +models, mediators, drivers | +Handle Field data initialization. Time stamp the export Fields and set the Updated and InitializeDataComplete Attributes accordingly. | +
Repeat these two steps until all data + dependencies have been statisfied, or a dead-lock situation is detected. | +
+ +
+
+INITIALIZE:
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+RUN:
+
+
+ +
+
+FINALIZE:
+
+
+ +
+
+INITIALIZE:
+
+
+ +
+
+RUN:
+
+
+ +
+
+FINALIZE:
+
+
+ +
+
+INITIALIZE:
+
+
+The NUOPC_Realize methods (3.9.22, 3.9.23, 3.9.24, 3.9.25, 3.9.26) are used to realize fields. Only previously advertised fields can be realized and the field's name is used to search the state for the previously advertised field. + +
+*Note: This phase is not required if all fields are accepting a geometric object. + +
+This phase is useful when accepting a Grid from another component, but when the PET counts differ between components. In this case, a new decomposition needs to be set based on the current processor count. + +
+The NUOPC_Realize methods (3.9.22, 3.9.23, 3.9.24, 3.9.25, 3.9.26) are used to realize fields. Only previously advertised fields can be realized and the field's name is used to search the state for the previously advertised field. + +
+*Note: This phase is not required if all fields are providing a geometric object. + +
+ +
+
+RUN:
+
+
+ +
+
+FINALIZE:
+
+
+ +
+The specialization method can change aspects of the internal clock, which defaults to a copy of the incoming parent clock. For example, the timeStep size may be changed and/or Alarms may be set on the clock.
+
+
+The method NUOPC_CompSetClock(comp, externalClock, stabilityTimeStep) (3.6.38) can be used to set the internal clock as a copy of externalClock, but with a timeStep that is less than or equal to the stabilityTimeStep. At the same time it ensures that the timeStep of the external clock is a multiple of the timeStep of the internal clock. If the stabilityTimeStep argument is not provided then the internal clock will simply be set as a copy of the external clock. + +
+ +
+The specialization method should initialize field data in the export state. Fields in the export state will be timestamped automatically by the calling phase for all fields that have the “Updated” attribute set to “true”. + +
+ +
+A specialization method to check and set the internal clock against the incoming clock. This method is called by the default run phase.
+
+
+If not overridden, the default method will check that the internal clock and incoming clock agree on the current time and that the time step of the incoming clock is a multiple of the internal clock time step. Under these conditions set the internal stop time to one time step interval of the incoming clock. Otherwise exit with error, flagging an incompatibility. + +
+ +
+A specialization method to verify import fields before advancing in time. If not overridden, the default method verifies that all import fields are at the current time of the internal clock. + +
+ +
+A specialization method that advances the model forward in time by one timestep of the internal clock. This method will be called iteratively by the default run phase until reaching the stop time on the internal clock. + +
+ +
+A specialization method to set the timestamp on export fields after the model has advanced. If not overridden, the default method sets the timestamp on all export fields to the stop time on the internal clock (which is also now the current model time). + +
+ +
+An optional specialization method for custom finalization code and deallocations of user data structures. + +
+ +
+
+INITIALIZE:
+
+
+ +
+
+RUN:
+
+
+ +
+
+FINALIZE:
+
+
+ +
+
+INITIALIZE:
+
+
+ +
+
+RUN:
+
+
+ +
+
+FINALIZE:
+
+
+This document was generated using the +LaTeX2HTML translator Version 2018 (Released Feb 1, 2018) +
+Copyright © 1993, 1994, 1995, 1996,
+Nikos Drakos,
+Computer Based Learning Unit, University of Leeds.
+
+Copyright © 1997, 1998, 1999,
+Ross Moore,
+Mathematics Department, Macquarie University, Sydney.
+
+The command line arguments were:
+ latex2html -white -toc_depth 5 -split +1 -show_section_numbers -local_icons -address 'esmf_support@ucar.edu' NUOPC_refdoc.tex
+
+The translation was initiated on 2024-12-03
+
+ +
+ +
+
+
+
+ +
+
+ +
+ +
+
+
+
+ +
+
+ +
+ +
+
+ +
+ESMF developers are encouraged to use as few external +software libraries as possible, to minimize the effort +needed to build and run the ESMF software. The external +utilities and libraries that the ESMF distribution relies +on are listed on the Download tab of the ESMF website. + +
+ +
+ESMF uses the MS Visio package to produce its graphics. +Both Visio files and *.eps files are checked into the +main repository. + +
+ +
+ + +
+
+Industry-accepted definitions exist for software errors and defects (faults), found in the ANSI/IEEE,
+Glossary of Software Engineering Terminology, are
+listed in Table A1.
+
+
+Table A1 - IEEE Software Engineering Terminology [#!ieee!#]
+
+
+
Category | +Definition | +
Error | +The difference between a computed, observed, or measured value or + condition and the true, specified, or theoretically correct value + or condition. | +
Fault | +An incorrect step, process, or data definition in a computer program. | +
Debug | +To detect, locate, and correct faults in a computer program. | +
Failure | +The inability of a system or component to perform its required functions + within specified performance requirements. It is manifested as a fault. | +
Testing | +The process of analyzing a software item to detect the differences between + existing and required conditions (that is, bugs) and to evaluate the features + of the software items. | +
Static analysis | +The process of evaluating a system or component based on its form, + structure, content, or documentation. | +
Dynamic analysis | +The process of evaluating a system or component based on its behavior + during execution. | +
Correctness | + The degree to which a system or component is free from faults in its
+ specification, design, and implementation. + The degree to which software, documentation, or other items meet + specified requirements. + The degree to which software, documentation, or other items meet user + needs and expectations, whether specified or not. |
+
Verification | + The process of evaluating a system or component to determine whether the
+ products of a given development phase satisfy the conditions imposed at
+ the start of that phase. + Formal proof of program correctness. |
+
Validation | +The process of evaluating a system or component during or at the end of + the development process to determine whether it satisfies specified + requirements. | +
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/dev_guide/node12.html b/docs/nightly/fix/reconcile-info/dev_guide/node12.html new file mode 100644 index 000000000..58769983a --- /dev/null +++ b/docs/nightly/fix/reconcile-info/dev_guide/node12.html @@ -0,0 +1,56 @@ + + + + + +
+
+This document was generated using the +LaTeX2HTML translator Version 2018 (Released Feb 1, 2018) +
+Copyright © 1993, 1994, 1995, 1996,
+Nikos Drakos,
+Computer Based Learning Unit, University of Leeds.
+
+Copyright © 1997, 1998, 1999,
+Ross Moore,
+Mathematics Department, Macquarie University, Sydney.
+
+The command line arguments were:
+ latex2html -white -toc_depth 5 -split 4 -local_icons -show_section_numbers -address 'esmf_support@ucar.edu' dev_guide.tex
+
+The translation was initiated on 2024-12-03
+
+ +
+Suggestions on how to improve the Guide should be sent to +esmf_support@ucar.edu. + +
+ +
+The Guide doesn't contain instructions on how to build +ESMF, adapt user codes for ESMF, or use the ESMF interfaces. +For documentation corresponding to the last public release, see +the Users tab on the ESMF website. For documentation of +all releases, including internal releases and previous public releases, +click the Download tab on the website and then View All +Releases. + +
+ +
+ +
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/dev_guide/node3.html b/docs/nightly/fix/reconcile-info/dev_guide/node3.html new file mode 100644 index 000000000..9959852be --- /dev/null +++ b/docs/nightly/fix/reconcile-info/dev_guide/node3.html @@ -0,0 +1,307 @@ + + + + + ++For more detail on the groups below, including their Terms of +Reference, see the ESMF Project Plan[#!bib:ESMFprojectplan!#]. +This document is available via the Management link on +the ESMF website navigation bar. + +
+ +
+All Core Team members are responsible for helping to +develop effective project processes and for following +processes that are in place. + +
+ +
+The Integrator is the lead tester. He or she is responsible for running regression +tests, managing project computing accounts, preparing for releases, +generating project metrics, and overseeing request and bug tracking. + +
+The Core Team Manager is responsible for overseeing the overall development, and +for coordinating the activities of multiple developers +so that project schedules and priorities are achieved. +Responsibilities include: + +
+ +
+Code Advocates are Core Team members who have been assigned to interface with owners of +a particular code e.g. CCSM, GEOS-5. Advocates are expected to contact the code owners and keep track of what and how they are doing. They should know the following things about their assigned code: + +
+ +
+Code Advocates should do the following for their code: + +
+Advocates are NOT responsible for: + +
+All customers should send support requests to esmf_support@ucar.edu. +They should not call their Advocate or other developers. Dire emergencies are exempt from the no-phone rule. +There are many good reason for doing this, including developer absences, group visibility and communication, +and enabling developers to set priorities. If a customer really feels the need to talk with an +Advocate or developer, they need to arrange for a date and time through the support list. +
+Handlers are developers assigned to fix a particular problem reported on one of the trackers (see + for list). They are expected to be sufficiently familiar with the issue and the +code involved so as to not unnecessarily pester the customer with requests for information (e.g. the +information is contained in previous tickets from the same customer). See section for +a complete list of Handlers activities in the support process. + +
+Support Lead is a Core Team member who has been assigned the responsibility for monitoring customer relations and the quality of the customer support process. Specific duties include: + +
+ +
+ +
+ +
+Collective public reviews and the intelligence and attentiveness of +project staff are the two primary mechanisms for software quality assurance. + +
+Requirements, design, code, and project documents such as plans +are subject to public review. The purpose of the reviews is +to look for models of good documentation, as well as inconsistencies, +errors, inefficiencies, and areas for improvement. Reviews also +increase coordination and awareness within the ESMF project. + +
+The Integrator ensures that support requests +and bugs are reported, tracked, and resolved, and that automated +test and backup scripts are operating correctly. + +
+The Core Team Manager works with team to ensure that documentation +is sufficient, tracks consistency between documentation and source +code before releases, and monitors conformance to coding and +documentation standards. The Core Team Manager is also responsible +for ensuring the quality and accuracy of the ESMF source code +distribution overall, by leading the development, +implementation and documentation of development, test, and release +procedures. + +
+ +
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/dev_guide/node4.html b/docs/nightly/fix/reconcile-info/dev_guide/node4.html new file mode 100644 index 000000000..005a543de --- /dev/null +++ b/docs/nightly/fix/reconcile-info/dev_guide/node4.html @@ -0,0 +1,270 @@ + + + + + ++ +
+The main ESMF technical mailing list is: +
+ ++This list handles telecon announcements, technical questions and +comments, discussions and materials relating to design and code +reviews, planning discussions, project announcements, and any other +items that concern the JST. + +
+The list for active ESMF developers is: +
+ ++This list is for people who are developing code and checking +it into the ESMF repository. Mails here may cover coordination +issues relating to check-ins and releases, technical material that +is not yet ready for the JST, and information specific to NCAR +and particular development platforms. + +
+Support questions should be directed to: +
+ ++The Users tab on the ESMF website describes +how to submit an effective support request and outlines the ESMF support +policy. + +
+People who are interested in occasional high-level project updates +can join the mailing list: +
+ ++Subscribers to this list receive more or less quarterly newletters +describing ESMF achievements and events. + +
+To subscribe to any of these lists on-line, see the Users +tab on the ESMF website. + +
+ +
+ESMF JST telecons are held as needed, typically on a weekly basis. +Normal telecon times are 1:00pm MT Thursdays, and sometimes Tuesdays. +A calendar of telecon topics is maintained on the home page of +the ESMF website. These telecons are open and are announced to +the esmf_jst@cgd.ucar.edu list. + +
+The Core Team meets weekly, at 9:30am MT on Wednesdays. The +meeting is also set up as a telecon. Core Team meetings are open +to active developers. + +
+The ESMF project has open community meetings on an annual basis, +usually during late spring. + +
+CRB meetings are held quarterly and are closed. However, prior +to each CRB meeting a JST telecon is devoted to collecting comments, +requirements, and priorities from JST members for consideration by +the CRB. + +
+ +
+ +
+The main ESMF GitHub site is at: +
+ ++This site is accessible from the ESMF website, +via either the Developers link or the GitHub +logo on the navigation bar. It is used for + +
+The source code and tools on this site are maintained by the +ESMF Core Team, and contributions and changes cannot be made to +them without coordination with the Core Team. + +
+The main ESMF Git repository is web-accessible at: +https://github.com/esmf-org/esmf +
+The GitHub site has instructions for checking out code. + +
+All ESMF documents, source code and test and other scripts are stored +in the main repository. + +
+The GitHub repository contains only the ESMF framework. Components +that use ESMF are stored in repositories at their home institutions. + +
+ +
+Contributors in the broader community can use this site +to archive and share code related to ESMF. Coordination is +not required with the ESMF Core Team in order to check into the +contributions repository. + +
+ +
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/dev_guide/node5.html b/docs/nightly/fix/reconcile-info/dev_guide/node5.html new file mode 100644 index 000000000..05a580e57 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/dev_guide/node5.html @@ -0,0 +1,1799 @@ + + + + + ++The ESMF development environment has several defining characteristics. +First, both the ESMF Core Team and the JST are distributed. This makes +incorporating simple, efficient communication mechanisms into the +development process essential. Second, the JST and Core Team work on +a range of different platforms, at sites that don't have the time, resources, +or inclination to install demanding packages. Collaboration +tools that require no purchase or installation before use are essential. +Finally, ESMF is committed to open development. As much as possible, +the ESMF team tries to keep the workings of the project - metrics, +support and bug lists, schedules, task lists, source code, you name it - +visible to the broad community. + +
+ +
+The ESMF software development cycle is based on the staged +delivery model [#!mcconnell96!#]. The steps in this software development +model are: + +
+ +
+
+
+
+ +
+
+
+
+
+
+We have customized and extended this standard model to suit the ESMF project. +At this stage of ESMF development, we are in the iterative design/implement/release +cycle. Below are a few notes on earlier stages. + +
+ +
+ +
+ +
+ +
+ +
+The following are processes the ESMF team is actively following. These +guidelines apply to core team developers and outside contributors +who will be checking code into the main ESMF repository. + +
+All design and code reviews are telecons held with the JST. +Telecons are scheduled with the Core Team Manager, put on the ESMF +calendar on the home page of the ESMF website, and announced on the +esmf_jst@ucar.edu list. + +
+ +
+When you call in, it's nice to give your name at the first opportunity. +Telecon hosts will make an effort to introduce people on the JST calls, +especially first-timers. Please don't put the telecon on hold (we sometimes +get telecon-stopping music or beeps this way). + +
+Within a week or so after the telecon, the host (the developer if it's a design +or code review) is expected to send out a summary to esmf_jst@ucar.edu +with the date of the call, the participants, and notes or conclusions. + +
+ +
+ +
+For these introductory discussions, any form of material is fine - diagrams, +slides, plain text ramblings, lists of questions, ... + +
+
+This step is iterated until developers and customers converge. + +
+
+
+It doesn't have to work (and probably won't) before it's reviewed, but it +needs to work before the functionality appears in a release. The developer +checks it into the top-level use_test_case directory on SourceForge and +prepares a HTML page outlining it for the Test & Validation page on the +ESMF website. Unlike unit and system tests, use test cases aren't +distributed with the ESMF source. +
+ +
+Code should be written in accordance with the interface specifications +agreed to during design reviews and the coding conventions described in +Section . + +
+There is an internal release checklist on the Test & Validation page of the +ESMF website that contains an exhaustive listing of develop and tester +responsibilities for releases. For additional discussion +of test and validation procedures, see Section . + +
+The developer is responsible for working with the tester(s) to make sure +that the following are present before an internal release: + +
+ +
+There is a public release checklist on the Test & Validation page of the ESMF +website that contains an exhaustive listing of develop and tester +responsibilities for releases. For additional discussion +of test and validation procedures, see Section . + +
+Same as for internal release, plus: + +
+ +
+Developers are encouraged to check their changes into the repository +as they complete them, as frequently as possible without breaking the +existing code base. + +
+ +
+To accomplish the first item on the list after a commit of source code, an email can be sent +to esmftest@cgd,ucar.edu with the exact subject "Run_ESMF_Test_Build". The mailbox is checked +every quarter hour on the quarter hour. This email initiates a test on pluto that +builds and installs ESMF with four compilers: g95, gfortran, lahey, and nag, with +ESMF_BOPT set to "g" and "O". + +
+When the test is started an email with the subject "ESMF_Test_Builds_Pluto_started", +is sent to esmf_core@ucar.edu, with a time stamp in the body of the message. +If a test is already running, an email, with the subject "ESMF_Test_Builds_Pluto_not_started", +is sent with "Test not started, a test is already running." in the body. +The test that is running will run to completion, a new test will NOT be queued up. A new +"Run_ESMF_Test_Build" email must be sent when the running test is completed. + +
+ +
+ +
+The ESMF produces internal releases and public releases based +on the schedule generated by the CRB. Every public release +is preceded by an internal release three months prior, for the +purpose of beta testing. During those three months, bugs may be +fixed and documentation improved, but no new functionality may be +added. Occasionally the Core Team releases an internal release +that does not become a public release. This would happen, for +example, when major changes are being made to ESMF and user +input is needed for multiple preliminary versions of the software. + +
+The Integrator tags new system versions with coherent changes prior +to release. The tagging convention for public and internal releases is +described in Section . + +
+Prior to release all ESMF software is regression-tested on all platforms +and interfaces. The Integrator is responsible for regression testing, +identifying problems and notifying the appropriate developers, and +collecting and sending out Release Notes and Known Bugs. + +
+ESMF releases are announced +on the esmf_jst@ucar.edu mailing list and are posted on the ESMF +website. Source code is available for download from the ESMF +website and from the main ESMF GitHub page. + +
+ +
+The backup strategy for each entity of the ESMF project is as follows: + +
+ +
+
+
+
+To conserve memory only the backup files for the current year and the prior year are retained. For years beyond the prior year, only 6 month backup files are retained i.e. for 2010 to 2012 of the ESMF cvs files are: + +
+20100103.esmf-cvsroot.tar.gz
+
+20100606.esmf-cvsroot.tar.gz
+
+20110102.esmf-cvsroot.tar.gz
+
+20110605.esmf-cvsroot.tar.gz
+
+20120101.esmf-cvsroot.tar.gz
+
+All of 1012 and 1013
+
+
+
+Once a year in January, the backup files of the year before the prior year will be cleaned up. For example, In January 2014 all of backup files of 2012 and 2013 would be archived, so the 2012 backup files will be cleaned up and only 6 month backup files will be retained. + +
+ +
+ +
+ +
+ESMF software is subject to the following tests: + +
+The ESMF team keeps track of test coverage on a per-method basis. +This information is on the Metrics page under the Development +link on the navigation bar. + +
+Testing information is stored on a Test and Validation web page, +under the Development link on the ESMF +web site. This web page includes: + +
+The ESMF is designed to run on several target platforms, in different +configurations, and is required to interoperate with many combinations +of application software. Thus our test strategy includes the following. + +
+ +
+ +
+Each class in the framework is associated with a suite of unit tests. +Typically the unit tests are stored in one file per class, and are +located near the corresponding source code in a test directory. The +framework make system will have an option to build and run unit tests. +The user has the option of building either a "sanity check" type test +or an exhaustive suite. The exhaustive tests include tests of many +functionalities and a variety of valid and invalid input values. The sanity +check tests are a minimum set of tests to indicate whether, for example, the +software has been installed correctly. It is the responsibility of the +software developer to write and execute the unit tests. Unit tests +are distributed with the framework software. + +
+To achieve adequate unit testing, developers shall attempt to meet the following goals. + +
+ +
+ +
+Unit tests usually test a single argument of a method to make it easier to +identify the bug when a unit test fails. +There are several steps to writing a unit test. +First, each unit test must be labeled with one of the following tags: + +
+Second, a string is specified describing the test, for example: +
+ write(name, *) "Grid Destroy Test" ++Third, a string to be printed when the test fails is specified, for example: +
+ write(failMsg, *) "Did not return ESMF_SUCCESS" ++Fourth, the ESMF_Test subroutine is called to determine the test results, for example: +
+ call ESMF_Test((rc.eq.ESMF_SUCCESS), name, failMsg, result, ESMF_SRCLINE) ++The following two tests are good examples of how unit tests should be written. +The first test verify that getting the attribute count from a Field returns ESMF_SUCCESS, while +the second verifies the attribute count is correct. These two tests could be combined into one +with a logical AND statement when calling ESMF_Test, but breaking the tests up allows you +to identify the source of the bug immediately. +
+ !------------------------------------------------------------------------ + !EX_UTest + ! Getting Attrubute count from a Field + call ESMF_FieldGetAttributeCount(f1, count, rc=rc) + write(failMsg, *) "Did not return ESMF_SUCCESS" + write(name, *) "Getting Attribute count from a Field " + call ESMF_Test((rc.eq.ESMF_SUCCESS), name, failMsg, result, ESMF_SRCLINE) + + !------------------------------------------------------------------------ + !EX_UTest + ! Verify Attribute Count Test + write(failMsg, *) "Incorrect count" + write(name, *) "Verify Attribute count from a Field " + call ESMF_Test((count.eq.0), name, failMsg, result, ESMF_SRCLINE) + + !------------------------------------------------------------------------ ++ +
+Sometimes a unit test is written expecting a subset of the processors to fail the test. To +handle this case, the unit test must verify results from each processor as in the unit test below: +
+ !------------------------------------------------------------------------ + !EX_UTest + ! Verify that the rc is correct on all pets. + write(failMsg, *) "Did not return FAILURE on PET 1, SUCCESS otherwise" + write(name, *) "Verify rc of a Gridded Component Test" + if (localPet==1) then + call ESMF_Test((rc.eq.ESMF_FAILURE), name, failMsg, result, ESMF_SRCLINE) + else + call ESMF_Test((rc.eq.ESMF_SUCCESS), name, failMsg, result, ESMF_SRCLINE) + endif + + !------------------------------------------------------------------------ ++ +
+Some tests may require that a loop be written to verify multiple results. The following is +an example of how a single tag, NEX_UTest, is used instead of a tag for each loop iteration. + +
+
+ !----------------------------------------------------------------------------- + !NEX_UTest + write(name, *) "Verifying data in Array via Fortran array pointer access" + write(failMsg, *) "Incorrect data detected" + looptest = .true. + do i = -12, -6 + j = i + 12 + lbound(fptr, 1) + print *, fptr(j), fdata(i) + if (fptr(j) /= fdata(i)) looptest = .false. + enddo + call ESMF_Test(looptest, name, failMsg, result, ESMF_SRCLINE) + !----------------------------------------------------------------------------- ++ +
+ +
+ +
+ +
+The following section now appears in the output of "make info". + +
+
+ +-------------------------------------------------------------- + * ESMF Benchmark directory and parameters * +ESMF_BENCHMARK_PREFIX: ./DEFAULTBENCHMARKDIR +ESMF_BENCHMARK_TOLERANCE: 3% +ESMF_BENCHMARK_THRESHOLD_MSEC: 500 + +-------------------------------------------------------------- ++ +
+The steps for using the benchmarking test tool are as follows: + +
+ +
+According to the default settings above, the benchmarking test will only analyze unit tests that run +500 msecs (ESMF_BENCHMARK_THRESHOLD_MSEC) +or longer. If a unit test runs 3 percent (ESMF_BENCHMARK_TOLERANCE) or more beyond the benchmarked +unit test, it will be flagged as failing the benchmark test. The developer may change these parameters +as desired. The following is an example of the output of running "make run_unit_tests_benchmark": + +
+ +
+ + + +The following unit tests with a threshold of 500 msecs. passed the 3% + tolerance benchmark test: + +PASS: src/Infrastructure/DELayout/tests/ESMF_DELayoutWorkQueueUTest.F90 +PASS: src/Infrastructure/Field/tests/ESMF_FieldCreateGetUTest.F90 +PASS: src/Infrastructure/Field/tests/ESMF_FieldRegridCsrvUTest.F90 +PASS: src/Infrastructure/Field/tests/ESMF_FieldRegridXGUTest.F90 +PASS: src/Infrastructure/Field/tests/ESMF_FieldStressUTest.F90 +PASS: src/Infrastructure/TimeMgr/tests/ESMF_CalRangeUTest.F90 +PASS: src/Infrastructure/VM/tests/ESMF_VMBarrierUTest.F90 +PASS: src/Infrastructure/VM/tests/ESMF_VMUTest.F90 +PASS: src/Infrastructure/XGrid/tests/ESMF_XGridMaskingUTest.F90 +PASS: src/Infrastructure/XGrid/tests/ESMF_XGridUTest.F90 +PASS: src/Superstructure/Component/tests/ESMF_CompTunnelUTest.F90 + + +The following unit tests with a threshold of 500 msecs. failed the 3% + tolerance benchmark test: + +FAIL: src/Infrastructure/Field/tests/ESMF_FieldRegridUTest.F90 + Test elapsed time: 4331.446 msec. + Benchmark elapsed time: 2958.47675 msec. + Increase: 46.41% + +FAIL: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleRegridUTest.F90 + Test elapsed time: 2051.05675 msec. + Benchmark elapsed time: 1920.42125 msec. + Increase: 6.8% + +FAIL: src/Infrastructure/LogErr/tests/ESMF_LogErrUTest.F90 + Test elapsed time: 2986.40425 msec. + Benchmark elapsed time: 2583.36775 msec. + Increase: 15.6% + + + +Found 167 exhaustive multi-processor unit tests files, of those with a + threshold of 500 msecs. 11 passed the 3% tolerance benchmark test, and 3 failed. + +Benchmark install date: Thu Jun 4 13:26:55 MDT 2015 ++ +
+Note that only the unit tests that have an elapsed time of 500 msecs. or greater are listed. In addition, the date when +the benchmark install was completed is displayed. + +
+When a unit test run it benchmarked it is written to a directory such as + "BENCHMARKDIR/test/testg/Darwin.gfortran.64.mpich2.default/". +Therefore you can only compare unit tests elapsed between the identical configurations. + +
+To implement the benchmarking tool, the unit tests were modified to record the elapsed time of each PET. +The stdout file of each unit test has the following lines i.e. + +
+
+ESMF_GridItemUTest.stdout: PET 0 Test Elapsed Time 5.7840000000000007 msec. +ESMF_GridItemUTest.stdout: PET 1 Test Elapsed Time 5.7259999999999982 msec. +ESMF_GridItemUTest.stdout: PET 2 Test Elapsed Time 6.6200000000000010 msec. +ESMF_GridItemUTest.stdout: PET 3 Test Elapsed Time 5.7190000000000021 msec. ++ +
+The benchmarking tool uses the average of the four elapsed times to determine the test results +since the elapsed times of each PET can vary. + +
+ +
+BOE and EOE are used between text describing the example. BOC and EOC are used between +actual working code that appears in the Reference Manual. Below is an example of how +the tags are used: + +
+
+!-------------------------------- Example ----------------------------- +!>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>% +!BOE +!\subsubsection{Get Grid and Array and other information from a Field} +!\label{sec:field:usage:field_get_default} +! +! A user can get the internal {\tt ESMF\_Grid} and {\tt ESMF\_Array} +! from a {\tt ESMF\_Field}. Note that the user should not issue any destroy command +! on the retrieved grid or array object since they are referenced +! from within the {\tt ESMF\_Field}. The retrieved objects should be used +! in a read-only fashion to query additional information not directly +! available through the {\tt ESMF\_FieldGet()} interface. +! +!EOE + +!BOC + call ESMF_FieldGet(field, grid=grid, array=array, & + typekind=typekind, dimCount=dimCount, staggerloc=staggerloc, & + gridToFieldMap=gridToFieldMap, & + ungriddedLBound=ungriddedLBound, ungriddedUBound=ungriddedUBound, & + totalLWidth=totalLWidth, totalUWidth=totalUWidth, & + name=name, & + rc=rc) +!EOC + if(rc .ne. ESMF_SUCCESS) finalrc = ESMF_FAILURE + print *, "Field Get Grid and Array example returned" + + call ESMF_FieldDestroy(field, rc=rc) + if(rc .ne. ESMF_SUCCESS) finalrc = ESMF_FAILURE +!>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>% ++ +
+Note that any code or text that is not contained within the tag pairs does not appear in the +Reference Manual. + +
+Most examples can be run on multiple processors or a single processor. Those examples should +have the tag, "ESMF_EXAMPLE" as a comment in the body of the example file. If the example +can only run on multiple processors then use the tag, "ESMF_MULTI_PROC_EXAMPLE". + +
+ +
+ +
+System tests are written to test functionality that spans several +classes. The following areas should be addressed in system testing. + +
+ +
+The system tester should issue a test log after each software release is tested, +which is recorded on the Test and Validation web page. The test +log shall +include: a test ID number, a software release ID number, testing environment +descriptions, a list of test cases executed, results, and any unexpected +events. + +
+ +
+System tests should contain the following sections: + +
+Most system tests can be run on multiple processors or a single processor. Those system tests should +have the tag, "ESMF_SYSTEM_TEST" as a comment in the body of the system test. If the system test +can only run on multiple processors then use the tag, "ESMF_MULTI_PROC_SYSTEM_TEST". + +
+At the end of the system it is recommended that the ESMF_TestGlobal subroutine be used to gather +test results from all processors and print out a single PASS/FAIL message instead +of individual PASS/FAIL messages from all the processors. +After the test is written it must be documented on the ESMF Test & Validation +web page: + +
+
+http://www.earthsystemmodeling.org/developers/test/system/ ++ +
+ +
+ +
+See section for a complete discussion of the test harness. + +
+ +
+Consider another example similar to the previous one, where two descriptor strings +describing an ensemble regridding tests. The first uses the patch method and the +second uses bilinear interpolation. + +
+
+[ B1 G1; B2 G2 ] =P=> [ B1 G1; B2 G2 ] +[ B1 G1; B2 G2 ] =B=> [ B1 G1; B2 G2 ] ++
+Suppose the associated specifier files indicate that the source grid is rectilinear +and is 100 X 50 in size. The destination grid is also rectilinear and is 80 X 20 +in size. +Both grids are block distributed in two +ways, 1 X NPETS and NPETS X 1. And suppose that the first dimension of both the +source and destination grids are periodic. If the test succeeds for the bilinear +regridding, but fails for one of the patch regridding configurations, the reported results +could look something like + +
+
+SUCCESS: [B1 G1; B2 G2 ] =B=> [B1 G1; B2 G2 ] +FAILURE: [B1{1} G1{100}+P; B2{npets} G2{50} ] =P=> [B1{1} G1{80}+P; B2{npets} G2{20} ] + failure at line 101 of test.F90 +SUCCESS: [ B1{npets} G1{100} +P; B2{1} G2{50} ] =P=> [ B1{npets} G1{80}+P; B2{1} G2{20} ] ++ +
+The report indicates that all the test configurations for the bilinear regridding +are successful. This is indicated by the key word SUCCESS which is followed by the +successful problem descriptor string. Since all of the tests in the first case pass, +there is no need to include any of the specifier information. For the second +ensemble of tests, one configuration passed, while the other failed. In this case, +since there is a mixture of successes and failures, the report includes +specifier information for all configurations to help indicate the source of the +test failure. The supplemental information, while not a complete problem description +since it lacks items such as the physical coordinates of the grid and the nature of +the test field, includes information crucial to isolating the failed test. + +
+ +
+Use Test Cases are problems of realistic size created to test the ESMF +software. They were initiated when the ESMF team and its users saw that +often ESMF capabilities could pass simple system tests but would fail +out in the field, for real customer problems. UTCs have realistic +processor counts, data set sizes, and grid and data array sizes. UTCs are +listed on the Test & Validation page of the ESMF website. They +are not distributed with the ESMF software; instead they are stored in +a separate module in the main repository called use_test_cases. + +
+ +
+ESMF software is released in a beta form, as an Internal Release, +three months before it is publicly released. This gives users +a chance to test the software and report back any problems to +support. + +
+ +
+The purpose of regression testing is to reveal faults caused by new +or modified software (e.g. side effects, incompatibility between +releases, and bad bug fixes). +Regression tests regularly exercise all interfaces of the code on +all target platforms. +The regression test results for the last two weeks can be found +here. +This web page provides a complete color-coded current view of the state of the trunk ESMF software, sorting options by platform or compiler are provided. +A similiar test results web page for the branch is also available. +Clicking on any of the cells will display the specific test report for that day. +Hovering over the test name i.e., Blues gfortran, will reveal notes particular to that platform/compiler. Clicking on the test name, will take you to the home page of the platform. + +
+The platforms that run the regression tests, email the test results to a server that updates the test results web page. A script checks for test reports every 15 minutes, and updates the web page. The time of the last update appears on the web page. + +
+ +
+A tool was created to allow the developers to query the test results for a specific test for a specific date, as long as it is within two weeks of the current date. +The developer may send a query test results message to the following email address: esmftest@cgd.ucar.edu +The subject of the email must be exactly "Test_Results_Query". The body of the email message must be "Test:" followed by the test name and "Date" followed by the desired date. The format must be a three letter month and a number. If the date is 2 digits, greater than 9, then insert one space between the month and date e.g. Apr 25. If the day is a single digit insert two spaces, between the month and day e.g. Apr 4. + +
+
+Test:ESMF_FieldBundleSMMUTest.F90 +Date:Feb 8 + or +Date Feb 28 ++ +
+This mail box is checked every quarter hour on the quarter hour, the results are emailed to:esmf_test@cgd.ucar.edu. +The subject of the results email for this example would be: +
+ ESMF_FieldBundleSMMUTest.F90 test results for Feb 8 ++ +
+The body of the email would be as follows: + +
+
+ ESMF_Blues_PGI:PASS: mvapich2/g: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Blues_PGI:PASS: mvapich2/O: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Blues_PGI:CRASHED: mpich3/g: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Blues_PGI:PASS: mpich3/O: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Blues_PGI:PASS: openmpi/g: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Blues_PGI:PASS: openmpi/O: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Discover_g95:PASS: mvapich2/g: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Discover_g95:PASS: mvapich2/O: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Haumea_g95:PASS: mpich2/g: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Haumea_g95:PASS: mpich2/O: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Haumea_g95:PASS: mvapich2/g: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Haumea_g95:PASS: mvapich2/O: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Pluto_g95:FAIL: mpich2/g: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Pluto_g95:FAIL: mpich2/O: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Pluto_g95:FAIL: mvapich2/g: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 + ESMF_Pluto_g95:FAIL: mvapich2/O: src/Infrastructure/FieldBundle/tests/ESMF_FieldBundleSMMUTest.F90 ++ +
+Note that if the date of the query is the current day, the developer should query periodically during the day since +the test results are being updated as platforms report their test results. +If a test crashes it can be because another test hung and the test in question did not run. + +
+Another instance where this tool is useful is when a developer adds a new test, after the nightly tests run, the developer can run a query to quickly see the test results. + +
+ +
+As software development progresses, the documentation is updated, built and posted at +http://earthsystemmodeling.org/docs/nightly/develop/dev_guide/ +
+The documents are built daily in the early morning, the results of the builds are posted at +http://earthsystemmodeling.org/doc/ +
+These documents can be updated by the developers, by checking out the documents from the repository and submitting the edited files. To have the new version of the documents posted on the web, the developer must sent a request to the following email address: esmftest@cgd.ucar.edu. The subject of the email indicates which document to build and post. +The following is the list of subjects that have been implemented: + +
+ +
+ +
+We provide two types of tar files, the ESMF source and the shared +libraries of the supported platforms. Consequently, there are two test +procedures followed before placing the tar files on the ESMF download website. + +
+The Source Code Test Procedure is followed on all the supported +platforms for the particular release. + +
+ +
+The Shared Libraries Test Procedure is also followed on all supported +platforms for a release. + +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ +
+
+
+ +
+ +
+The following rules apply to the above: + +
+ +
+ +
+Advocates need to share the information they have received from their codes with the rest +of the Core team. This will be done by sending an email to esmf_support@ucar.edu with a +subject line labeled INFO: Code e.g. INFO: CCSM, INFO: GEOS-5. These messages will be +filed on the IMAP server (see above section) under the code referenced. All information +about a code that is general and not related to a specific support request will be archived +in this manner. + +
+ +
+ +
+ +
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/dev_guide/node6.html b/docs/nightly/fix/reconcile-info/dev_guide/node6.html new file mode 100644 index 000000000..d2e61aa24 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/dev_guide/node6.html @@ -0,0 +1,78 @@ + + + + + ++The ESMF source distribution contains a few executables that are built on top +of the ESMF library during installation. These executables are referred to as +apps. Apps are command line tools intended to be used by the end user of +ESMF. ESMF follows the GNU conventions for command line tools. There are +currently three mandatory command line options that every distributed app must +implement: + +
+
+--help Print a help message, documenting all of the available command line arguments and their usage. +--version Print the version of ESMF in long format and the copyright message. +-V Print just the version string of ESMF. ++ +
+
+The Test Harness is a flexible test control system intended to provide a thorough +parameter space exploration of remapping and redistribution of distributed arrays and fields. +The parameter space is defined through configuration files which are interpreted at +run time to perform the desired tests. + +
+The Test Harness is integrated into the Unit test framework, enabling +the Test Harness to be built and run as part of the Unit tests. The test results +are reported to a single standard-out file which is located with the unit test +results. + +
+The motivation for employing such a hierarchy configuration files is to allow a +high degree of customization of the test configurations by combining individual +specification files. Complex combinations of test cases are easily specified in high level terms. +Each class will have its own collection of specification files tailored to the needs of that class. + +
+ +
+There are three ways to invoke the test harness, as an integral part of running unit +tests; as a stand-alone test invoked through gmake; and as a standalone test invoked through the command line. + +
+Running the harness along with the unit tests provides +frequent regression testing of the redistribution and regridding features. + +
+Running the test harness +in stand alone mode using gmake is useful for isolating faults in failed test cases. + +
+Running the test harness from the command line provides the most control over Test Harness execution. +Understanding the underlying program allows the developer full access to test harness features. +This is useful in developing makefiles, scripts, and configuration files. + +
+ +
+The environment variables currently defined are: + +
+The targets currently supported for the ESMF_TESTHARNESS_ARRAY variable are: + +
+The targets currently supported for the ESMF_TESTHARNESS_FIELD variable are: + +
+Each target selects the desired sequence of test cases for that target. +For example, a series of test cases could be developed to run on different days providing partial +test coverage on a particular day, but complete coverage over a week. +In this case, each day would have a separate target and the environment variable would be set for +that day's test case. + +
+An example of a test harness appears below. +
+RUN_ESMF_TestHarnessField_1: + \$(MAKE) TESTHARNESSCASE=field_1 NP=4 run_test_harness ++ +
+In this example, the test harness target is RUN_ESMF_TestHarnessField_1. This target will execute a +single test harness test case. Additional lines can be added if additional steps are desired. +The next section will describe the details of invoking a test case. + +
+ +
+For example, +
+gmake TESTHARNESSCASE=field_1 NP=4 run_test_harness ++will run the test harness test case, field_1 on 4 processors. + +
+Each test case is defeined by a series of configuration files in the +<classdir>/tests/harness_config directory. +All of the configuration files for a particular test case will be prefixed with +<casename>_ where <classname> is a unique name for the test. +The top level configuration file will have a suffix of _test.rc. +Thus, the top level configuration file for the field_1 test case will be +field_1_test.rc. + +
+The next section describes invoking the Test Harness from the Command Line. + +
+ +
+To run the executable, enter: +
+\<run path\>ESMF\_TestHarnessUTest \<cmd args\> +where, +\<run path\> is the path to the executable, +and \<cmd args\> are the optional command arguments + +The cmd args are as follows: +-path \<config path\> +-case \<case filename\> +-xml \<xml filename\> +-norun ++ +
+The path argument sets the path to the configuration files. All of the configuration files +for a testcase must reside in the same directory. If this argument is not present, the current working directory +will be used as the path. + +
+The case argument is the name of the top level configuration file. This is described in a later +section of this document. If this argument is not present, test_harness.rc will be used. + +
+The xml argument instructs the test harness to generate an XML test case summary file +in the current working directory. + +
+The norun argument instructs the test harness not to run the test cases. The configuration files will be parsed +and if selected, an XML file will be generated. The XML file can be post-processed to generate human +readable test configuration summary reports. + +
+If running under mpi, you would need to prefix this command with the proper mpirun command. + +
+The next section describes the format of the top level resource file. + +
+ +
+The top level configuration file specifies the test class, the +format for reporting the test results, and the location and file names containing +the problem descriptor files. + +
+Originally, the test harness had a single configuration file for each class and +supported only two test cases, a non-exhaustive case and an exhaustive case. +This turned out to be too restrictive and test cases are now selected through environment variables. +Unfortunately, some of the old constructs remain until the obsolete feature is removed. + +
+Currently, the test harness only uses the non-exhaustive test case for each configuration file. +So, referencing the example below, only the nonexhaustive tag is actually used by the test harness. + +
+Also note, that comments are preceded by the # sign, that single parameter values follow +a single colon : punctuation mark, while tables of multiple parameter values follow, +and are terminated by, a double set of colon :: punctuation marks. +This file is read by the ESMF_Config class methods, therefore must adhere +to their specific syntax requirements. +The entries can be in any order, but the name tags must be exact - including CAPITALIZATION. +While it is not strictly necessary, the file names are enclosed in quotation marks, +either single or double, to guarantee they are read correctly. +
+# Field test Harness Config file + +# test class +test_class: FIELD + +# report a summary of the test configurations before actually conducting tests +setup_report: TRUE + +# test result report - options are: +# test_report: FULL - full report presenting both success and failure configs +# test_report: FAILURE - report only failure configurations +# test_report: SUCCESS - report only successful configurations +# test_report: NONE - no report +test_report: FAILURE + +# descriptor file for the nonexhaustive case +nonexhaustive:: + 'nonexhaustive_descriptor.rc' +:: # end of list + +# descriptor files for the exhaustive case (obsolete, but keep in for awhile) +exhaustive:: + 'exhaustive_descriptor.rc' +:: # end of list ++ +
+The argument for the tag test_class: specifies the ESMF class to be tested. +Here it is Field.The tag setup_report: specifies if a setup report is sent to the test report. +The tag test_report: specifies the style of report to be constructed. +This report is appended to the standard-out file which is located with the Unit test results. +The tag nonexhaustive:: delimits a table which contains the file names of +problem descriptor files pertaining to the current test configuration. + +
+The tag exhaustive is obsolete and will be removed when time permits. It has been replaced with the Test Harness +environment variables which can select the desired test case from the available portfolio. + +
+ +
+The problem descriptor files contain descriptor strings that describe the family +of problems with the same memory topology, distribution, and grid association. +The files also contain the names of specifier files which complete the descriptions +contained within the descriptor strings. This structure allows a high level of customization of the test suite. + +
+The problem descriptor file contains only one table, again conforming to the ESMF_Config class standard. +The contents of the table must be delimited by the tag problem_descriptor_string::. +The first element on the line, enclosed by quotes, is the problem descriptor string itself. +Since the descriptor strings contain gaps and special characters, it is necessary +to enclose the strings in quotation marks to guarantee proper parsing. +The problem descriptor table may contain any number of descriptor strings, +up to the limit imposed by the ESMF_Config class, each on a new line. +Lines can be continued by use of an ampersand & as a continuation symbol +at the beginning of any continued line. +The syntax of the problem descriptor string follows the field taxonomy syntax. +The following is a basic redistribution example. +
+# Basic redistribution example +##################################### +problem_descriptor_string:: +'[B1G1;B2G2] --> [B1G1;B2G2]' -d Dist.rc -g Grid.rc +'[B1G1;B2G2] --> [B1G2;B2G1]' -d DistGrid.rc + & otherDistGrid.rc yetanotherDistGrid.rc + & -g Grid.rc anotherGrid.rc +:: # end of list ++In the above example, the two problem descriptor strings specify that a redistribution test +is to be conducted, indicated by the syntax ->, between a pair of rank two blocks of memory. +Following the problem descriptor string, are multiple flags and the names of specifier files. +Each flag indicates a portion of the configuration space which is defined by the contents +of the indicated specifier files. +
argument | +definition | +
-d | +DELayout/DistGrid specification | +
-g | +Grid specification | +
+ +
+For example + indicates that a 2D logically rectangular block of memory +is associated with a 2D grid in its natural order. +The signifier represents an undistributed tensor grid. +Reversing the grid signifiers indicates that the fastest varying dimension +is instead associated with the second grid dimension. +Specific information about the grid, such as its size, type, topology are left to be defined +by the specifier files. It is the associations between memory and the grid that are stressed with this syntax. + +
+To distribute the grid, a distribution signifier is needed. +The block distribution of each memory dimension is indicated by the signifier . +Therefore + signifies that a 3D logically rectangular block of memory, +which has a 3D associated grid, is distributed in its first two dimensions, and not its third. + +
+ +
+As an example, consider a block of memory. To associate a tensor grid with specific dimensions of that block, +the symbol is used with a numerical suffix to indicate a specific dimension of the grid. +The specific aspects of this grid are left undefined at this point, only the fact +that a particular dimension of a grid is associated with a particular dimension +of the memory block is implied by the grid syntax. + +
+The complete syntax for a tensor grid specification is + where + +
+To illustrate the use of this syntax consider the following example. +
+ [ G1 ; G2 + H{1:1} ] ++
+At times a memory location might have no grid association. +The symbol is used in this case as a place holder. For example, +
+ [ G2 ; G1 ; * ] ++
+In this example, the grid association has been reversed from from its natural order. +The first memory location is associated with the second grid dimension, +and the second memory location with the first grid dimension. + +
+ +
+As was mentioned before, the symbol is used as a place holder to indicate a lack of association. +If the third memory location of an undistributed block of memory has no grid association, it would look like this; +
+[ G1; G2; * ] ++
+[ B1 G1; B2 G2; * G3 ] ++
+Lastly, if the last memory location has no associations, it would look like; +
+[ B1 G1; B2 G2; * * ] ++
+ +
+
+ | Action | +
B | +first order bilinear interpolation | +
P | +patch recovery interpolation | +
+ | + |
C | +first order conservative interpolation | +
S | +second order conservative interpolation | +
N | +nearest neighbor distance weighted average interpolation | +
X | +unknown or user provided interpolation | +
+The problem descriptor string +
+ [B1 G1; B2 G2 ] --> [B1 G1; B2 G2 ] ++
+Alternatively the example +
+ [ B1 G1; B2 G2 ] =C=> [ B1 G1; B2 G2 ] ++
+ +
+ [ B1 G1; B2 G2 ] @{#,#} ++
+The stagger location key represents the location of a field with respect to the cell center location. It is indicated by relative cartesian coordinates of a unit square, cube etc. To illustrate this further, consider the example of a 2D grid. The cell is represented by a unit square with the xy axis placed at its center, with the positive x-axis oriented East and the positive y-axis oriented North. The actual values are suppressed, only the directions , and are used. This geometry is for reference purposes only, and does not literally represent the shape of an actual cell. + +
+The cell center, located at the origin of the cell, is indicated by . The corner of the cell is indicated by , where the ones have been dropped to just leave the plus signs. The cell face normal to the X axis (right wall) is indicated by , while the face normal to the Y axis ( top wall) is indicated by . This approach generalizes well to higher dimensions. +
argument | +definition | +
Center | +{ 0,0 } | +
Corner | +{ +,+ } | +
Face normal to X axis | +{+,0 } | +
Face normal to Y axis | +{0,+ } | +
+With these four locations, it is possible to indicate the standard Arakawa grid staggerings. A key of would be equivalent to an Arakawa A-grid, while a key of would represent an Arakawa B-grid. Components of the C and D grids would be indicated by wall positions and . +
Grid Stagger | +coordinates | +
A-grid | +{ 0,0 } | +
B-grid | +{ 1,1 } | +
C-grid & D-grid | +{ 0,1 } and { 1,0} | +
+For example, the string +
+[B1 G1; B2 G2 ] =C=> [B1 G1; B2 G2 ] @(+,+) ++indicates that a collection of regridding tests are to be run where a block distributed two dimensional field, is interpolated from one two dimensional grid onto a second two dimensional grid, using a first order conservative method. The source field data is located at the cell centers (an A-grid stagger location) and the destination field is to be located at north east corner (a B-grid stagger location). Additional information about the pair of grids and their distributions must be specified to run an actual test. + +
+This process generalizes to higher dimensions. Consider +
+[B1 G1; B2 G2 ; G3 ] =C=> [B1 G1; B2 G2 ; G3 ] @(+,+,+) ++indicates that a collection of regridding tests are to be run between a 3D source grid (cell centered) and a 3D destination grid where the field stagger location is the upper corner of the 3D cell (B-grid horizontally and top of the cell vertically). + +
+A further discussion on grid staggers can be found in section on the ESMF Grid class in the Reference manual. + +
+ +
+For example, in models with nested grids or which employ multi-grid methods, it is useful to have an indexed structure of logically rectangular blocks of memory, where each block is generally a different shape and size. Such a structure can be represented with parentheses as delimiters, such as +
+ ( tile , [ B1 G1; B2 G2 ] ) ++
+ +
+The nature of the grid specifier file varies depending on whether the test is a redistribution or a regridding. A redistribution test takes a field associated with a grid and rearranges it in processor space. So while a source and destination distribution are needed, only a single grid is necessary to conduct the test. A regridding test, on the other hand, takes a field associated with a source grid and interpolates it to a destination grid thaty is also part of a field. In this case both source and destination grids are needed. It is also assumed that a source and destination distribution is specified. +
Redistribution | +source grid | +
+ | source & destination distribution | +
Regridding | +source & destination grids | +
+ | source & destination distribution | +
+ +
+The first step of the grid generation is to generate a rectilinear grid of specified size, range of coordinates, and either uniform or gaussian spacing between the coordinates. If only a rectilinear grid needed, the grid generation is finished. If a curvilinear grid is desired, the rectilinear grid is taken as a base grid and its coordinates are smoothly stretched and/or shrunk according to an analytical function, to produce a curvilinear mesh according. + +
+ +
+
key word | +formula + | +
contracting | ++ | +
+ | + | +
expanding | ++ | +
+ | + | +
symmetric_sin | ++ | +
+ | + | +
asymmetric_sin | ++ | +
+ | + | +
+These four choices for equate into four options for analytically generated curvilinear grids. + +
+Examples of these four curvilinear grid options are plotted in figure . + +
+
|
+This adds up to a total of 2 types of rectilinear grids (uniform and gaussian), each with three options (no connection, spherical pole connection, and a periodic option). A large variety of grids can be formed by mixing and matching the grid types and options. For example a standard latitude-longitude grid on a sphere is formed by using the pair of grid types uniform_periodic and uniform_pole. A gaussian grid is formed with uniform_periodic and gaussian_pole. And a regional grid on a sphere, without periodicity, with uniform and uniform. A summary of the rectilinear grid types is given below. +
Rectilinear grid options | +|
grid type | +modifier | +
UNIFORM | +none | +
+ | _POLE | +
+ | _PERIODIC | +
GAUSSIAN | +none | +
+ | _POLE | +
+ | _PERIODIC | +
+The various curvilinear grid types are created in the same way of mixing and matching grid type options. A regional expanding grid is formed using the grid types expanding and expanding. Likewise a rotated regional grid is created by +using the grid types rotation_15degrees and rotation_15degrees to indicate the grid type. A summary of the curvilinear grid types is given below. +
Curvilinear grid options | +|
grid type | +modifier | +
CONTRACTING | +none | +
+ | _POLE | +
+ | _PERIODIC | +
EXPANDING | +none | +
+ | _POLE | +
+ | _PERIODIC | +
SYMMETRIC_SIN | +none | +
+ | _POLE | +
+ | _PERIODIC | +
ASYMMETRIC_SIN | +none | +
+ | _POLE | +
+ | _PERIODIC | +
rotation_15degrees | +none | +
rotation_30degrees | +none | +
rotation_30degrees | +none | +
+ +
parameters to define a grid for redistribution | +
Grid rank | +
Grid dimensions | +
Range of the coordinate axis | +
Coordinate units | +
+This is the information is provided by the redistribution grid specifier file. +An example of a redistribution grid specifier file is provided below. +
+# grid.rc +######################################## +map_type: REDISTRIBUTION + +# regular rectilinear Grid specification +map_redist:: +#rank spacing size range (min/max) units +# +2 'UNIFORM' 120 -3.14159 3.14159 'RAD' 'UNIFORM' 90 -1.57 1.57 'RAD' +# +2 'UNIFORM' 400 -180 180 'DEG_E' 'GAUSSIAN' 200 -88 88 'DEG_N' +:: ++
+The first piece of information required for the file is the map_type key. It should be set to REDISTRIBUTION to indicate that it is intended to define grids for a redistribution test. Next is a configuration table which specifies multiple grids. The specification can be stretched over multiple table lines by use of the continuation symbol . The order of information is as follows: +
parameters to define a grid for redistribution | +
Grid rank | +
Grid axis type | +
Grid size | +
Range of the coordinate axis | +
Coordinate units | +
+There are two 2D grids specified in the file. The first is a standard uniformly spaced latitude-longitude grid, where none of the grid coordinates has any topological connections. The horizontal coordinates are in radians. The second 2D grid is a gaussian spherical grid. The gaussian grid has a spherical topology and is in degrees. + +
+Four types of coordinate units are supported; degrees, radians, meters and kilometers. Each has multiple equivalent key words. +
Supported units | +|
name | +key word | +
Degrees | +DEGREES | +
+ | DEG | +
+ | DEG_E | +
+ | DEG_N | +
Radians | +RADIANS | +
+ | RAD | +
Meters | +METERS | +
+ | M | +
Kilometers | +KILOMETERS | +
+ | KM | +
+ +
parameters to define a grid for remapping | +
source and destination grid rank | +
source and destination grid axis type | +
source and destination grid dimensions | +
source and destination range of coordinate axis | +
source and destination coordinate units | +
test function with parameters to interpolate | +
+This information is provided by the regridding grid specifier file. +An example of a regridding grid specifier file is provided below. +
+# grid.rc +######################################## +map_type: REGRID + +################################################################################ +# grid | source | grid | grid | grid | units | destination | +# rank | tag | spacing | dimension | range | | tag | +################################################################################ +# Grid specification for regridding + +#rank spacing size range (min/max) units +map_regrid:: +# example of a pair of 2D periodic grids +2 SRC UNIFORM_PERIODIC 120 -3.14159 3.14159 RADIANS +& UNIFORM_POLE 90 -1.57 1.57 RADIANS +& DST UNIFORM_PERIODIC 120 -180 180 DEG_E +& GAUSSIAN_POLE 88 -88 88 DEG_N +& FUNCTION CONSTANT 2.1 0.1 END +:: ++
+The first piece of information required for the file is the map_type key. It should be set to REGRID to indicate that it is intended to define grids for a regridding test. Next is a configuration table which specifies multiple pairs of grids. The specification can be stretched over multiple table lines by use of the continuation symbol . The order of information is as follows: +
parameters to define a grid for reremapping | +
Grid rank | +
Source grid axis type | +
Source grid size | +
Source range of the coordinate axis | +
Source coordinate units | +
Destination grid axis type | +
Destination grid size | +
Destination range of the coordinate axis | +
Destination coordinate units | +
Test function and parameters | +
+The regridding grid specifier file contains a pair of 2D grids. The source grid is a standard latitude-longitude grid on a spherical topology. The destination grid is a spherical gaussian grid also on a spherical topology. The source grid is in radians, while the destination grid is in degrees. The test function is a periodic function of the grid coordinates. + +
+The one new piece of information for the regridding specifier files are the predefined test functions. The test functions provide a physical field to be interpolated and are generated as an analytical function of the grid coordinates. Supported options include: +
Test functions | ++ | |
name | +function | +parameters | +
constant | +set value at all locations | +value, relative error | +
coordinate | +set to a multiple of the coordinate values | +scale, relative error | +
spherical harmonic | +periodic function of the grid coordinates | +amplitudes and phases, relative error | +
+The CONSTANT value test function sets the field to the value of the first parameter following the name. The second value is the relative error threshold. For example, the test function specification: + +
+
+& FUNCTION CONSTANT 2.1 0.1 END ++
+indicates that the field is set to the constant value of , with a relative error threshold +of . This test function specification holds for grids of any rank. + +
+The COORDINATE test function sets the field to the value of the one of the grid coordinates multiplied by the value of the first parameter following the name. The second value is the relative error threshold. For example, the test function specification: + +
+
+& FUNCTION COORDINATEX 0.5 0.1 END ++
+indicates that the field is set to one half of the X coordinate values. For a 2D grid the coordinate options include COORDINATEX and COORDINATEY. For a 3D grid there is the additional option of COORDINATEZ. Again, the relative error threshold is . +This test function specification holds for grids of any rank. + +
+The SPHERICAL_HARMONIC test function sets the field to the periodic harmonic function + +. +The parameters follow the order + +
+
+& FUNCTION SPHERICAL_HARMONIC a kx b ly rel_error END ++
+This test function specification is only valid for 2D grids. + +
+ +
+Here is an example of a distribution specification file for block and block cyclic distributions. +
+################################################## +# descriptive | source | source | operator | destination | dest | operator | end +# string | tag | rank | & value | tag | rank | & value | tag +################################################## + +# table specifing 2D to 2D distributions +distgrid_block_2d2d:: + +# example with two fixed distribution sizes + '(1,2)-->(2,1)' 'SRC' 2 'D1==' 1 'D2==' 2 'DST' 2 'D1==' 2 'D2==' 1 'END' + +# example with one fixed and one variable distribution size + '(1,n)-->(n,1)' 'SRC' 2 'D1==' 1 'D2=*' 1 'DST' 2 'D1=*' 1 'D2==' 1 'END' + +# example with variable distribution sizes + '(2n,n/2)-->(n/2,2n)' 'SRC' 2 'D1=*' 2 'D2=*' 0.5 + & 'DST' 2 'D1=*' 0.5 'D2=*' 2 'END' + +# another example with variable distribution sizes + '(2n,n/2)-->(2n,(n/2)-1)' 'SRC' 2 'D1=*' 2 'D2=*' 0.5 + & 'DST' 2 'D1=*' 2 'D2=*' 0.5 'D2=+' 1 'END' +:: + +# table specifing 3D to 3D distributions +distgrid_block_3d3d:: + +# example with two fixed distribution sizes + '(1,2,1)-->(2,1,1)' 'SRC' 3 'D1==' 1 'D2==' 2 'D3==' 1 + & 'DST' 3 'D1==' 2 'D2==' 1 'D3==' 1 'END' +:: ++
parameters to define a grid distribution | +
Descriptive string | +
Source key | +
Source distribution rank | +
Source distribution axis and size for each dimension of the distribution | +
Destination key | +
Destination distribution rank | +
Destination grid size | +
Destination distribution axis and size for each dimension of the distribution | +
Termination key | +
+The second example, illustrates how to indicate a scalable distribution. Again the entry indicates that the first dimension of the distribution is set to one, but the entry has a different meaning. It takes the total number of PETs NPETS and scales it by one. Therefore the source distribution becomes +. It automatically scales with the number of PETs. Likewise, the destination distribution is set to +. + +
+The third example is completely dynamic. Since both and are scalable, each dimension starts with PETs, where is the square root of rounded down to the nearest integer. Therefore +. So if , Then . If then still equals . This base value is then modified by the indicated entries. In this case the source distribution is +, since the tag indicates that first dimension is the result of the base value being multiplied by two, and the second dimension is the result of the base value being multiplied by one half. Likewise, the destination distribution is set to +, no matter the number of . + +
+For a rank three scalable distribution, is the cube root of NPETS rounded down to the next integer. And so on for higher rank distributions. + +
+The fourth example illustrates the last option in the syntax. Again, since the distribution specifies two scalable distributions, is the square root of rounded down to the nearest integer. The source distribution is exactly the same as in the third example, but destination distribution has a new entry . The first dimension of the destination distribution is set to by the entry . the second dimension is first set to by the entry , but then modified further to by the entry . The resulting destination distribution is +. + +
+The syntax for modifying the size of the distribution space combines according to the order of the operations. The entries and , are not identical to and , which would result in a dimension of size . + +
+Three operations are supported: +
Distribution specification operations | ++ |
D# == | +specify a fixed value | +
D# =* | +multiply a base value by a constant | +
D# =+ | +add a constant to the base value | +
+ +
+ +
+Consider a problem descriptor string consisting of two descriptor strings describing an ensemble of remapping tests. +
+[ B1 G1; B2 G2 ] =C=> [ B1 G1; B2 G2 ] @{+,+} +[ B1 G1; B2 G2 ] =B=> [ B1 G1; B2 G2 ] @{+,+} ++
+Suppose the associated specifier files indicate that the source grid is rectilinear and is 100 X 50 in size. The destination grid is also rectilinear and is 80 X 20 in size. The remapping is conducted from the A-grid position of the source grid to the B-grid stagger of the destination grid. Both grids are block distributed in two ways, 1 X NPETS and NPETS X 1. And suppose that the first dimension of both the source and destination grids are periodic. If the test succeeds for the conservative remapping, but fails for one of the first order bilinear remapping configurations, the reported results +could look something like +
+SUCCESS: [B1 G1; B2 G2 ] =C=> [B1 G1; B2 G2 ] @{+,+} +FAILURE: [B1{1} G1{100}+P; B2{npets} G2{50} ] =B=> + [B1{1} G1{80}+P; B2{npets} G2{20} ] @{+,+} + failure at line 101 of test.F90 +SUCCESS: [ B1{npets} G1{100} +P; B2{1} G2{50} ] =B=> + [ B1{npets} G1{80}+P; B2{1} G2{20} ] @{+,+} ++
+[ B1{npets} G1{80}+P; B2{1} G2{20} ] @{+,+} ++
+The report indicates that all the test configurations for the conservative remapping are successful. This is indicated by the key word SUCCESS which is followed by the successful problem descriptor string. Since all of the tests in the first case pass,there is no need to include any of the specifier information. For the second ensemble of tests, one configuration passed, while the other failed. In this case, since there is a mixture of successes and failures, the report includes specifier information for all the configurations to help indicate the source of the test failure. + +
+The supplemental information, while not a complete problem description, since it lacks items such as the physical coordinates of the grid and the nature of the test field, includes information crucial to isolating the failed test. + +
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/dev_guide/node8.html b/docs/nightly/fix/reconcile-info/dev_guide/node8.html new file mode 100644 index 000000000..afa5c60b2 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/dev_guide/node8.html @@ -0,0 +1,4539 @@ + + + + + ++Code and documentation developed for the ESMF will follow conventions +for both style and content. The goal is to create software with a consistent +look and feel so that it is easier to read and maintain. + +
+Because much ESMF documentation is generated directly from source +code, code and documentation conventions are closely intertwined. + +
+ +
+ESMF maintains a set of templates for developing Fortran and
+C++ codes and their documentation. The documentation templates
+include requirements, design, and reference documents.
+These templates are bundled with the source distribution, in
+the following directory:
+
+
+$(ESMF_DIR)/scripts/doc_templates ++ +
+ +
+The do_newdoc script in the document templates package creates +a new document directory and populates it with the appropriate files. +The READMEs in the package describe the procedure for running the +script. + +
+ +
+The following scripts are included in the doc_templates package: +
+ +
+ +
+Software documentation for the last public release is at: +
+ http://www.earthsystemmodeling.org -> Users -> Documentation ++ +
+Software documentation for all releases is at: +
+ http://www.earthsystemmodeling.org -> Download -> View All Releases ++ +
+Documents are available to developers for editing through the +ESMF repository on the GitHub site. + +
+ +
+Documents will be available in both web-browsable (e.g. html) and +printer-friendly formats. They will be written in LATEX and based on a +set of templates. LATEX was chosen because: + +
+ +
+ +
+ +
+The following conventions for fonts and capitalization are used
+in this and other ESMF documents.
+
+
+
Style | +Meaning | +Example | +
italics | +documents | +ESMF Reference Manual | +
courier | +code fragments | +ESMF_TRUE | +
courier() | +ESMF method name | +ESMF_FieldGet() | +
boldface | +first definitions | +An address space is ... | +
boldface | +web links and tabs | +Developers tab on the website | +
Capitals | +ESMF class name | +DataMap | +
+ESMF class names frequently coincide with words commonly +used within the Earth system domain (field, grid, component, array, +etc.) The convention we adopt in this manual is that if a word is +used in the context of an ESMF class name it is capitalized, and +if the word is used in a more general context it remains in lower +case. We would write, for example, that an ESMF Field class +represents a physical field. + +
+Diagrams are drawn using the Unified Modeling Language (UML). UML +is a visual tool that can illustrate the structure of +classes, define relationships between classes, and describe sequences +of actions. A reader interested in more detail can refer to a +text such as The Unified Modeling Language Reference Manual. + [#!uml!#] + +
+ +
+General style recommendations for LATEX documentation include the +following: + +
+ +
+ +
+Performance reports should contain the following specific +information: + +
+ +
+ +
+ +
+
+
+
+
+
+ +
+A standard template for examples has not yet been created. + +
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+ +
+ +
+ESMF defines a set of standard methods and interface rules that +hold across the entire API. These are: + +
+ +
+
+
+
+
+
+
+
+ +
+ +
+ +
+ +
+ +
+The naming conventions listed here apply to arguments that appear in +ESMF public interfaces. It is nice if internal arguments also adhere +to these conventions, but not enforced as it is as the interface. + +
+ +
+The following table lists a set of standard terms that we use in ESMF. + +
+
Cell | +grid cell | +
Coord | +coordinate | +
Count | +count | +
Dim | +dimension, used for grids | +
Dst | +destination | +
List | +indicates that the quantity is an array | +
Local | +indicates that the quantity is associated with a PET or DE | +
Per | +per item | +
Rank | +data array dimension | +
Send | +send | +
Src | +source | +
Recv | +receive | +
+These are used in combination to create argument and variable names. +For example, localCellCountPerDimList is an array of counts, per +dimension, of the number of local grid cells. + +
+ +
+ +
+ +
+ +
+ +
+ type(ESMF_Field), intent(in) :: fieldList(:) ++ +
+ +
+ +
+ +
+Source and documentation files must contain the ESMF license and +copyright header: + +
+
+! Earth System Modeling Framework +! Copyright (c) 2002-2024, 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. ++ +
+ +
+example: +! TODO: add support for other data types (CMD 4/01). ++This will allow developers to 'grep' source files before software releases. + +
+ +
+
+#define ESMC_FILENAME "./src/Infrastructure/Attribute/src/ESMCI_Attribute.C" ++ +
+with the appropriate filename. Note that the path is relative to the ESMF +root directory. + +
+ +
+General style recommendations for source code include the following: + +
+ +
+ +
+ +
+ +
+The objectives of these conventions are: + +
+ +
+ +
+ESMF methods are classified into two categories: pre-review, and post-review. As of the version 3.0.1 release, *all* methods are pre-review. + +
+Reviews are expected to begin once conventions for framework behavior are sufficiently well-defined. To pass review, methods must have their basic functionality fully implemented. If any unimplemented options are present, they must be documented and must generate appropriate errors in order for the method to pass review. + +
+A pre-review method has its return code (rc) initialized to the value ESMF_RC_NOT_IMPL (not implemented). Possible sources of specific errors within the method, such as subroutine calls, generate local return codes (localrc). + +
+The localrc values are evaluated using the function ESMF_LogMsgFoundError(), which takes both the localrc and the rc as input arguments. If the localrc does not indicate an error, rc is output from ESMF_LogMsgFoundError() with the value it had going into the call, and the value of the function is .false.. If localrc does indicate an error, rc is set to the localrc value before being output from ESMF_LogMsgFoundError(), and the value of the function is .true.. + +
+The convention is to place ESMF_LogMsgFoundError() into a conditional statement that causes a return from the method, with the correctly set rc, when an error is found in localrc, e.g.: +
+if (ESMF_LogFoundError(localrc, <other args ...>, rc)) return ++Use of the ESMF_LogMsgFoundError() function is further described in the ESMF Reference Manual. + +
+Note that if no error is found, rc retains its ESMF_RC_NOT_IMPL status throughout the method. The developer must explicitly set the rc to ESMF_SUCCESS just before returning from any branch that is believed to be successful. + +
+The default rc value thus becomes ESMF_RC_NOT_IMPL for any code that is not explicitly marked as reaching success by the developer. Stub methods and incomplete branches can be handled very naturally this way - the developer simply does not set rc=ESMF_SUCCESS before returning. There are two differences in the treatment of pre-review and post-review methods: + +
+
+
+These conventions achieve the first three objectives above, namely producing appropriate error messages throughout a method's life cycle, with minimal developer effort. + +
+ +
+Under normal use - what a user will encounter by default - ESMF_RC_NOT_IMPL is treated as an error. However, through a special LogErr setting a developer who wishes to use stub methods and prototyping during code construction can equate ESMF_RC_NOT_IMPL with ESMF_SUCCESS. This achieves the fourth objective above, allowing for different user and developer modes of handling incomplete code. This is done by setting the errorMask argument in the ESMF_LogSet() call to ESMF_RC_NOT_IMPL, e.g.: + +
+
+call ESMF_LogSet(errorMask = /ESMF_RC_NOT_IMPL/) ++ +
+ +
+The following is an example of a pre-review method, sub(), that calls two subroutines internally, subsub1() and subsub2(). The subroutine sub() takes as input an integer argument that it can branch on and outputs a return code. Here branch==1 is fully implemented, branch==2 is incomplete, and other values of branch are not yet addressed. Several possible error scenarios are described following the code listing. + +
+
+subroutine sub(branch, rc) +integer :: branch +integer, optional :: rc +integer :: localrc ! local return code + +if (present(rc)) rc=ESMF_RC_NOT_IMPL +! ...code... +if (branch==1) then +call subsub1(localrc) +if (ESMF_LogFoundError(localrc, & + ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rc=rc)) then + ! ... any necessary garbage collection ... + return ! Return point 1 +endif ! ...fully implemented code... +if (present(rc)) rc=ESMF_SUCCESS +elseif (branch==2) then call subsub2(localrc) +if (ESMF_LogFoundError(localrc, & + ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rc=rc)) then + ! ... any necessary garbage collection ... + return ! Return point 2 +endif +! ...incomplete code... +end if + +end subroutine ++ +
+Note: This example is quite artificial, since simple branching like this would be better handled with a switch case statement that had a well-defined default. However, the control sequence shown better illustrates the sorts of errors that can occur in a real code with complex conditionals. + +
+Possible scenarios: + +
+
+
+
+
+
+This example is modeled on the pre-review example, but illustrates error handling for a post-review method. Here branch==1 is fully implemented, branch==2 is known to be incomplete, and other values of branch are cases that the developer and reviewers have missed. This is not what one would wish to see in reviewed code - ideally all cases should be implemented - but we cannot count on this. This example shows how deficiencies can most effectively be handled. + +
+The return code rc is now initialized to ESMF_RC_NOT_SET. The developer has recognized that the branch==2 code is incomplete and rc is set explicitly to ESMF_RC_NOT_IMPL before returning. + +
+
+subroutine sub(branch, rc) +integer :: branch +integer, optional :: rc +integer :: localrc ! local return code + +if (present(rc)) rc=ESMF_RC_NOT_SET +! ...code... +if (branch==1) then +call subsub1(localrc) +if (ESMF_LogFoundError(localrc, & + ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rc=rc)) then + ! ... any necessary garbage collection ... return ! Return point 1 +endif +! ...fully implemented code... +if (present(rc)) rc=ESMF_SUCCESS +elseif (branch==2) then call subsub2(localrc) +if (ESMF_LogFoundError(localrc, & + ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rc=rc)) then + ! ... any necessary garbage collection ... + return ! Return point 2 +endif +! ...incomplete code... +if (present(rc)) rc=ESMF_RC_NOT_IMPL end if +end subroutine +{ ++ +
+Possible scenarios: + +
+branch==1. Here the behavior is essentially the same as in scenarios 1 and 2. When there is an error in subsub1(), the returned rc from sub() has the error code subsub1() generated. When there is not an error in subsub1(), the returned rc from sub() is ESMF_SUCCESS. + +
+branch==2 and there is an error in subsub2(). The behavior here is analogous to scenario 3. The returned rc from sub() has the error code subsub2() generated. + +
+branch==2 and there is no error in subsub2(). The value of rc remains ESMF_RC_NOT_SET up to the point at which it is explicitly set to ESMF_RC_NOT_IMPL, and sub() ends. Method documentation is expected to explain the gap in functionality. + +
+any value where branch and branch (e.g. branch==0). Here rc is not explicitly set to a value before the branch returns, and so sub() returns with the default rc value of ESMF_RC_NOT_SET. The user can tell from this error code that the developer did not consider this either unimplemented code or successful code, and that there is an unexpected “hole” in the method's functionality. + +
+ +
+ +
+In Fortran code, the allocate and deallocate statements should +always have their success or failure checked by using stat= and checking +the value it returns. Since this value is defined by the Fortran +standard, and is not an ESMF return code, the alternative checking calls are +ESMF_LogFoundAllocError() and ESMF_LogFoundDeAllocError(). +To further distinguish the difference between a Fortran status return +and a ESMF return code, the local error variable should be named “memstat” +rather than “localrc”. + +
+
+ real, allocatable :: big_array(:,:) + integer :: memstat + ! ... + allocate (big_array(m,n), stat=memstat) + if (ESMF_LogFoundAllocError(memstat, & + ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rc=rc)) then + ! ... any necessary clean up + return + end if + ! ... use big_array for a while + deallocate (big_array, stat=memstat) + if (ESMF_LogFoundDeAllocError(memstat, & + ESMF_ERR_PASSTHRU, & + ESMF_CONTEXT, rc=rc)) then + ! ... any necessary clean up + return + end if ++ +
+In C++ code, where the new operator is used, allocation errors can +be caught by wrapping the allocation code inside a try block to catch +any exceptions. Multiple allocations may be wrapped inside a single block +in order to reduce the amount of checking code. + +
+
+#include "ESMCI.h" +//... +void alloc_func (int m, int n, int *rc) { +#undef ESMC_METHOD +#define ESMC_METHOD alloc_func + double *array1, *array2; + try { + array1 = new double[m]; + array2 = new double[n]; + } + catch (std::bad_alloc) { + // ... any necessary clean up + ESMC_LogDefault.MsgAllocError("allocating array1 and array2", + ESMC_CONTEXT, rc); + return; + } + // ... use array1 and array2 for a while + delete array2; + delete array1; +} ++ +
+In code which uses malloc() and free(), +the return value from malloc() may be tested against +NULL to determine if an error occurred. No checking is +possible with free(). In new code, the C++ new +operator and associated checking should be used. + +
+ +
+ +
+ +
+Currently not all Fortran compilers support the +automatic initialization of class components. However, +in the ESMF system this initialization is used for two +tasks. The first is the initialization of shallow class +components which need to be set before they're used +(e.g. flags). The second is the detection of invalid +(e.g. not yet created) deep class variables. In order +to handle these tasks in the absence of compiler +initialization a software based solution has been +developed. + +
+The software solution is based on the improbability of +an uninitialized variable containing a specific value. For +example, given a 64 bit integer variable x, the +probability of x containing the value 10 are approximately +1 in . This of course assumes that the value in +an uninitialized variable is a uniformly distributed random +variable, which is not necessarily true. However, the small probability +of a given value occurring is not an unreasonable assumption +given that the value is not pathological +(e.g. 0 or binary 111111..). The probability can +also be made as small as is necessary +by using larger precision types. + +
+Given the improbability of a specific value occurring in an +uninitialized variable, the task of initializing a shallow +class is implemented as follows. First, a non-pathological +value, ESMF_INIT_DEFINED, is chosen. Next, an integer +component, isInit, is added to the shallow class. +Finally, for every routine taking the shallow +class as an input variable, the component isInit is checked +against ESMF_INIT_DEFINED. If they don't match, then the variable +containing isInit is initialized, including setting isInit to +ESMF_INIT_DEFINED. If they do match, then with extremely high probability +the variable has already been initialized and nothing +need be done. This algorithm helps to ensure that the shallow +class is initialized before being used in the system. + +
+The task of detecting an invalid deep class is +implemented as follows. As before, we chose a value +ESMF_INIT_CREATED, and add the isInit component to the class +definition. Next, inside the constructors for +the class isInit is set to ESMF_INIT_CREATED, and +inside the destructors for the class isInit +is set to something other than ESMF_INIT_CREATED. +Finally, for every routine taking the deep class +as an input variable, the component isInit is +checked against ESMF_INIT_CREATED. If they match, then +nothing happens because with extremely high +probability the variable has been though the +constructor and thus is valid. If they don't match, +then the variable is invalid and an error occurs. +This allows invalid deep class variables to be detected +before being used in the system. + +
+In order to make the process of adding these non-compiler +based initialization tasks easier, a set of macros has been defined. +The following is a description of the procedures to use them. + +
+ +
+These changes should be added to all new F90 code in both the source +(/src) and interface (/interface) subdirectories of the classes. + +
+When adding code as a part of this task remember to use +the standard ESMF coding conventions. In particular, when adding +new routines remember to use the standard +ESMF protex style (BOP/EOP) subroutine description, like those that +appear in every other ESMF subroutine. For Validate use +the BOP/EOP tags for ESMF_TYPEGetInit and ESMF_TYPEInit +use the internal BOPI/EOPI tags. + +
+Some F90 source files are autogenerated. In this case, modify +the macro file which is used to create the autogenerated file. +The macro file is usually named something like ESMF_TypeMacos.h. +When modifying a macro file remember to end each line +with: @ To recognize when an F90 file is autogenerated +they usually have the line: <Created by maco - do not edit directly> +close to the beginning. There will also usually be a .cpp +file with the same name as the .F90 file. + +
+For the purposes of initialization standardization the +classes in the system have been divided into three types: shallow, deep, +and parameter. Shallow classes have little if any allocation and +can often be used right after declaration. An example of a shallow +class is ESMF_ArraySpec. Deep classes on the other hand have a lot of +allocated data and need to be constructed before being used. An example of +a deep class is ESMF_State. Parameter classes are +those which are used to add type checking to a set of parameter values. +This type of class is typically just a single integer wrapped in a Fortran type. +An example of a parameter class is ESMF_GridType. Both shallow and +deep classes are effected by the standardization, but parameter classes +are left unchanged. See section for a list of +ESMF classes and their classification. + +
+The instructions for the standardization have been broken +up by what to do for each module, what to do for each type of class, +and what to do for routines. + +
+ +
+When adding a new F90 module do the following: + +
+ +
+ use ESMF_InitMacrosMod ++ +
+
+ #include "ESMF.h" ++
+ +
+When adding a new shallow class definition perform the following steps: + +
+ +
+ use ESMF_UtilTypesMod ++ isn't in the list of used modules, then add it. + +
+
+
+ function ESMF_STYPEGetInit(s) + type(ESMF_STYPE), intent(in), optional :: s + ESMF_INIT_TYPE :: ESMF_STYPEGetInit + + if (present(s)) then + ESMF_STYPEGetInit=ESMF_INIT_GET(s) + else + ESMF_STYPEGetInit=ESMF_INIT_DEFINED + endif + + end function ESMF_STYPEGetInit ++ +
+
+
+ ! Comments describing validate (see ESMF_StateValidate for an example) + subroutine ESMF_STYPEValidate(s,rc) + type(ESMF_STYPE), intent(inout) :: s + integer, intent(out),optional :: rc + + ! check initialization status + ESMF_INIT_CHECK_SET_SHALLOW(ESMF_STYPEGetInit,ESMF_STYPEInit,s) + + ! return success + if (present(rc)) then + rc=ESMF_SUCCESS + endif + + end subroutine ESMF_STYPEValidate ++ +
+
+ public ESMF_STYPEInit + public ESMF_STYPEGetInit + public ESMF_STYPEValidate ++ to the PUBLIC MEMBER FUNCTION section. + +
+
+
+Here is an example illustrating the whole procedure:
+
+
+Starting with this shallow class definition: + +
+
+ module ESMF_ExampleMod + + type ESMF_Shallow + private + ... other components ... +#ifndef ESMF_NO_INITIALIZERS + integer :: num=0 + integer, pointer :: list(:) => Null() +#else + integer :: num + integer, pointer :: list(:) +#endif + end type + +! !PUBLIC TYPES: + public ESMF_Shallow + +! !PUBLIC MEMBER FUNCTIONS: + + contains + + ... other routines ... + + end module ESMF_ExampleMod ++ +
+The standardization procedure yields this:
+
(modified lines marked with *)
+
+
+
+ module ESMF_ExampleMod +* use ESMF_UtilTypesMod +* use ESMF_InitMacrosMod + + type ESMF_Shallow + private + ... other components ... +#ifndef ESMF_NO_INITIALIZERS + integer :: num=0 + integer, pointer :: list(:) => Null() +#else + integer :: num + integer, pointer :: list(:) +#endif +* ESMF_INIT_DECLARE + end type + +! !PUBLIC TYPES: + public ESMF_Shallow + +! !PUBLIC MEMBER FUNCTIONS: +* public ESMF_ShallowInit +* public ESMF_ShallowValidate +* public ESMF_ShallowGetInit + + contains + +* function ESMF_ShallowGetInit(s) +* type(ESMF_Shallow), intent(in), optional :: s +* ESMF_INIT_TYPE :: ESMF_ShallowGetInit +* +* if (present(s)) then +* ESMF_ShallowGetInit=ESMF_INIT_GET(s) +* else +* ESMF_ShallowGetInit=ESMF_INIT_DEFINED +* endif +* +* end function ESMF_ShallowGetInit +* +* subroutine ESMF_ShallowInit(s) +* type(ESMF_Shallow) :: s +* +* s%num=0 +* nullify(s%list) +* +* ESMF_INIT_SET_DEFINED(s) +* end subroutine ESMF_ShallowInit +* +* subroutine ESMF_ShallowValidate(s,rc) +* type(ESMF_Shallow), intent(inout) :: s +* integer, intent(out),optional :: rc +* +* ! check initialization status +* ESMF_INIT_CHECK_SET_SHALLOW(ESMF_ShallowGetInit,ESMF_ShallowInit,s) +* +* ! return success +* if (present(rc)) then +* rc=ESMF_SUCCESS +* endif +* +* end subroutine ESMF_ShallowValidate + + ... other routines ... + + end module ESMF_Shallow ++ +
+ +
+When adding a new deep class definition perform the following steps: + +
+ +
+ use ESMF_UtilTypesMod ++ isn't in the list of used modules, then add it. +
+ function ESMF_DTYPEGetInit(d) + type(ESMF_DTYPE), intent(in),optional :: d + ESMF_INIT_TYPE :: ESMF_DTYPEGetInit + + if (present(d)) then + ESMF_DTYPEGetInit=ESMF_INIT_GET(d) + else + ESMF_DTYPEGetInit=ESMF_INIT_CREATED + endif + + end function ESMF_DTYPEGetInit ++ +
+
+ ! Comments describing validate (see ESMF_StateValidate for an example) + subroutine ESMF_DTYPEValidate(d1,rc) + type(ESMF_DTYPE), intent(in) :: d1 + integer, intent(out),optional :: rc + + ! Check Init Status + ESMF_INIT_CHECK_DEEP(ESMF_DTYPEGetInit,d1,rc) + + ! Add other checks here + + ! If all checks passed return success + if (present(rc)) then + rc=ESMF_SUCCESS + endif + + end subroutine ESMF_DTYPEValidate ++ +
+
+ public ESMF_DTYPEGetInit + public ESMF_DTYPEValidate ++ to the PUBLIC MEMBER FUNCTION section. + +
+
+The following are the standard names for the subroutines +which set a class as created, set a class as deleted, and set the this +pointer, and get the this pointer: +
+ESMF_DTYPESetInitCreated +ESMF_DTYPESetInitDeleted +ESMF_DTYPESetThis +ESMF_DTYPEGetThis ++ +
+
+
+Here is an example illustrating the whole procedure:
+
+
+Starting with this deep type definition: + +
+
+ module ESMF_ExampleMod + + type ESMF_Deep + private + ... other components ... + end type + +! !PUBLIC TYPES: + public ESMF_Deep + +! !PUBLIC MEMBER FUNCTIONS: + + contains + + function ESMF_DeepCreate() + type(ESMF_Deep) :: ESMF_DeepCreate + + ... other create code ... + + end function ESMF_DeepCreate + + subroutine ESMF_DeepDestroy(d) + type(ESMF_Deep) :: d + + ... other create code ... + + end subroutine ESMF_DeepDestroy + + ... other routines ... + + end module ESMF_ExampleMod ++ +
+The standardization procedure yields this:
+
(modified lines marked with *)
+
+
+
+ module ESMF_ExampleMod +* use ESMF_UtilTypesMod +* use ESMF_InitMacrosMod + + type ESMF_Deep + private + ... other components ... +* ESMF_INIT_DECLARE + end type + +! !PUBLIC TYPES: + public ESMF_Deep + +! !PUBLIC MEMBER FUNCTIONS: +* public ESMF_DeepValidate +* public ESMF_DeepGetInit + + contains + +* function ESMF_DeepGetInit(d) +* type(ESMF_Deep), intent(in),optional :: d +* ESMF_INIT_TYPE :: ESMF_DeepGetInit +* +* if (present(d)) then +* ESMF_DeepGetInit=ESMF_INIT_GET(d) +* else +* ESMF_DeepGetInit=ESMF_INIT_CREATED +* endif +* +* end function ESMF_DeepGetInit +* +* subroutine ESMF_DeepValidate(d,rc) +* type(ESMF_Deep), intent(in) :: d +* integer, intent(out),optional :: rc +* +* ! Check Init Status +* ESMF_INIT_CHECK_DEEP(ESMF_DeepGetInit,d,rc) +* +* ! Add other checks here +* +* ! If all checks passed return success +* if (present(rc)) then +* rc=ESMF_SUCCESS +* endif +* +* end subroutine ESMF_DeepValidate + + function ESMF_DeepCreate() + type(ESMF_Deep) :: ESMF_DeepCreate + + ... other create code ... + +* ESMF_INIT_SET_CREATED(ESMF_DeepCreate) + + end function ESMF_DeepCreate + + subroutine ESMF_DeepDestroy(d) + type(ESMF_Deep) :: d + + ... other create code ... + +* ESMF_INIT_SET_DELETED(d) + + end subroutine ESMF_DeepDestroy + + ... other routines ... + + end module ESMF_ExampleMod ++ +
+ +
+When adding a new parameter class definition, don't add any initialization +standardization code. However, do add the new class to the class list in +section . + +
+ +
+When adding a new subroutine or function (both referred +to as 'routine' henceforth) perform the following steps: + +
+ +
+
+The initialization macros in 1. and 2. should be +added before any code which uses the types being checked. + +
+When adding the check macros to code there are a couple of issues +to keep in mind for compatibility with all compilers. First, +don't break up the macro across lines (e.g. using &). +Second, some compilers have a maximum line length. Occasionally, +the Deep class check macro will expand to larger than this +length, if you find that this is occurring with a particular +line use the ESMF_INIT_CHECK_DEEP_SHORT macro instead. +It takes exactly the same parameter list as the normal deep class +check macro, but expands to a much shorter line. + +
+Here is an example illustrating this procedure:
+
+
+Starting with this routine: + +
+
+ subroutine ESMF_EXAMPLE(s1,d1,s2,d2,d3,rc) + type(ESMF_Shallow1), intent(in) :: s1 + type(ESMF_Shallow2), intent(out) :: s2 + type(ESMF_Deep1),intent(in) :: d1 + type(ESMF_Deep2),intent(inout) :: d2 + type(ESMF_Deep3),intent(out) :: d3 + integer :: rc + .... local variable declarations ... + + ! initialize return code + rc=ESMF_FAILURE + + ...... rest of subroutine code.... + + end subroutine ESMF_Example ++ +
+The standardization yields this:
+
(modified lines marked with *)
+
+
+
+ subroutine ESMF_EXAMPLE(s1,d1,s2,d2,d3,rc) +* type(ESMF_Shallow1), intent(inout) :: s1 + type(ESMF_Shallow2) :: s2 + type(ESMF_Deep1) :: d1 + type(ESMF_Deep2),intent(inout) :: d2 + type(ESMF_Deep3),intent(out) :: d3 + integer :: rc + .... other local variable declarations ... + + ! initialize return code + rc=ESMF_FAILURE + +* ! check variables +* ESMF_INIT_CHECK_DEEP(ESMF_Deep1GetInit,d1,rc) +* ESMF_INIT_CHECK_DEEP(ESMF_Deep2GetInit,d2,rc) +* +* ESMF_INIT_CHECK_SET_SHALLOW(ESMF_Shallow1GetInit,ESMF_Shallow1Init,s1) +* ESMF_INIT_CHECK_SET_SHALLOW(ESMF_Shallow2GetInit,ESMF_Shallow2Init,s2) + + ...... rest of subroutine code.... + + end subroutine ESMF_Example ++ +
+ +
+CAUTION: The following lists are very much outdated!!! + +
+
Class | +Type | +Fortran | +ESMF | +
ESMF_Alarm | +Deep | +public | +public | +
ESMF_AlarmList_Flag | +Parameter | +public | +public | +
ESMF_Array | +Deep | ++ | + |
ESMF_ArrayBundle | +Deep | ++ | + |
ESMF_ArraySpec | +Shallow | ++ | + |
ESMF_Attribute | +Shallow | ++ | + |
ESMF_Base | +Deep | ++ | + |
ESMF_BaseTime | +Shallow | ++ | + |
ESMF_CWrap | +Deep | ++ | + |
ESMF_Calendar | +Deep | ++ | + |
ESMF_CalKind_Flag | +Parameter | ++ | + |
ESMF_Clock | +Deep | ++ | + |
ESMF_CommHandle | +Deep | ++ | + |
ESMF_CommTable | +Deep | ++ | + |
ESMF_CompClass | +Deep | ++ | + |
ESMF_CompType_Flag | +Parameter | ++ | + |
ESMF_Config | +Deep | ++ | + |
ESMF_ConfigAttrUsed | +Shallow | ++ | + |
ESMF_Context_Flag | +Parameter | ++ | + |
ESMF_CoordOrder | +Parameter | ++ | + |
ESMF_CplComp | +Deep | ++ | + |
ESMF_DELayout | +Deep | ++ | + |
ESMF_DataHolder | +Shallow | ++ | + |
ESMF_DataValue | +Ignore | ++ | + |
ESMF_Decomp_Flag | +Parameter | ++ | + |
ESMF_Direction_Flag | +Parameter | ++ | + |
ESMF_DistGrid | +Deep | ++ | + |
ESMF_Field | +Deep | ++ | + |
ESMF_FieldBundle | +Deep | ++ | + |
ESMF_FieldBundleDataMap | +Shallow | ++ | + |
ESMF_FieldBundleType | +Deep | ++ | + |
ESMF_FieldDataMap | +Shallow | ++ | + |
ESMF_FieldType | +Deep | ++ | + |
ESMF_Fraction | +Shallow | ++ | + |
ESMF_Grid | +Deep | ++ | + |
ESMF_GridComp | +Deep | ++ | + |
ESMF_GridStatus_Flag | +Parameter | ++ | + |
ESMF_Index_Flag | +Parameter | ++ | + |
ESMF_InterfaceInt | +Ignore | ++ | + |
+
Class | +Type | +Fortran | +ESMF | +
ESMF_LOGENTRY | +Shallow | ++ | + |
ESMF_LocalArray | +Deep | ++ | + |
ESMF_Log | +Shallow | ++ | + |
ESMF_LogKind_Flag | +Parameter | ++ | + |
ESMF_Logical | +Ignore | ++ | + |
ESMF_Mask | +Shallow | ++ | + |
ESMF_LogMsg_Flag | +Parameter | ++ | + |
ESMF_NeededFlag | +Parameter | ++ | + |
ESMF_ObjectID | +Shallow | ++ | + |
ESMF_Pin_Flag | +Parameter | ++ | + |
ESMF_PhysGrid | +Deep | ++ | + |
ESMF_Pointer | +Ignore | ++ | + |
ESMF_ReadyFlag | +Parameter | ++ | + |
ESMF_Reduce_Flag | +Parameter | ++ | + |
ESMF_Region_Flag | +Parameter | ++ | + |
ESMF_RegridMethod_Flag | +Parameter | ++ | + |
ESMF_RelLoc | +Parameter | ++ | + |
ESMF_ReqForRestartFlag | +Parameter | ++ | + |
ESMF_Route | +Deep | ++ | + |
ESMF_RouteHandle | +Deep | ++ | + |
ESMF_StaggerLoc | +Shallow | ++ | + |
ESMF_State | +Deep | ++ | + |
ESMF_StateClass | +Deep | ++ | + |
ESMF_StateItem | +Shallow | ++ | + |
ESMF_StateItem_Flag | +Parameter | ++ | + |
ESMF_StateIntent_Flag | +Parameter | ++ | + |
ESMF_Status | +Parameter | ++ | + |
ESMF_Sync_Flag | +Parameter | ++ | + |
ESMF_End_Flag | +Parameter | ++ | + |
ESMF_Time | +Shallow | ++ | + |
ESMF_TimeInterval | +Shallow | ++ | + |
ESMF_VM | +Deep | ++ | + |
ESMF_VMId | +Deep | ++ | + |
ESMF_VMPlan | +Deep | ++ | + |
ESMF_ValidFlag | +Parameter | ++ | + |
+ +
+ +
+ +
+The following tools and guidelines are in place in order to maintain the ESMF framework's portability and robustness, in light of the fact that neither the Fortran nor C++ standards require a fixed size for any given data type and/or kind. Please note that these guidelines pertain to the internal ESMF code, not to the user code that interfaces to it. + +
+ +
+ +
+Any occurrence of Fortran data kind parameters within ESMF code must be specified with ESMF parameters only. e.g. +
+ ESMF_KIND_I4 + ESMF_KIND_I8 + ESMF_KIND_R4 + ESMF_KIND_R8 ++These are internally defined such that the size of the data they describe is the number at the end of the parameter. e.g. in + +
+
+ integer(ESMF_KIND_I8) :: someInteger ++someInteger is an 8 byte integer in any platform. + +
+Kind of literal constants: + +
+Only the ESMF kind parameters listed above are allowed when specifying the kind of literal Fortran constants. e.g. + +
+
+ real(ESMF_KIND_R8) :: a,b + a=b*0.1_ESMF_KIND_R8 ++ +
+In the example above 0.1_ESMF_KIND_R8 is a literal constant of kind ESMF_KIND_R8 and value 0.1. + +
+This means that any other syntax, such as: +
+ a=b*0.1d0 + a=b*0.1_8 ++is NOT to be used. + +
+ESMF_KIND_I, ESMF_KIND_R: Note that the ESMF_TypeKind_Flag parameters: ESMF_KIND_I and ESMF_KIND_R are defined for use in user code only. They are handles offered to the user for ESMF internal default kinds and not to be used internally in the ESMF framework. + +
+Real Data: + +
+ real(ESMF_KIND_R<n>) :: RealVariable ++ +
+where is the size in bytes of the memory occupied by each real datum. Allowed values of n are those that correspond to supported type/kind data, e.g. +
+ real (ESMF_KIND_R8) :: a,b ++ declares a and b to be 8 byte reals + +
+
+
+Integer Data: + +
+The standards for integer data differ between integers that store user data and integers that do not. + +
+Routines with user integer data arguments (e.g. integer arrays), must be overloaded for all integer data kinds supported. These will be declared as +
+ integer(ESMF_KIND_I<n>) ++where denotes data size in byte units. + +
+Integers that do not represent user data must generally be declared without a specific kind (see the section below on Default Type Representation). Possible exceptions to this rule follow on items (3) and (4) below. + +
+Care should be exercised to insure that integer arguments to intrinsic Fortran functions are of the correct kind (usually default). Likewise, argument parameters to VM routines should be of default kind. + +
+In the case where a specific kind is required for integer ESMF routine arguments, such as occurs in TimeMgr routines, the requirement must be clearly documented (as noted above, ESMF kind parameters are to be used to specify the kind). + +
+Default Type Representation: + +
+Default Integer Data Internal to the ESMF: + +
+Internally in the ESMF framework, all integer data intended to be of default kind must be declared without specifying their kind, e.g. +
+ subroutine ESMF_SomeRoutine(foo) + integer :: foo ++This is for clarity purposes, as well as to minimize the overall size of the framework. + +
+ESMF_KIND_I must not be used to declare data internally within ESMF. + +
+To provide some background, the handle ESMF_KIND_I is provided to aid users who want to insure that their integer user code matches the kind of ESMF internal default integer data. It is particularly useful when user code is compiled with integer autopromotion. User code that calls ESMF routines with internal default integer arguments could declare those integers to be of kind=ESMF_KIND_I, e.g. +
+ program myUserCode + integer(ESMF_KIND_I) :: my_foo + call ESMF_SomeRoutine(my_foo) ++ +
+Logical Data: + +
+The standards for logical data differ between logicals which are used as dummy arguments in user-callable entry points, and those which need to be passed +to ESMF C++ routines. + +
+Routines with user logical data arguments use default kind arguments: +
+ logical :: isActive ++ +
+Local logicals within Fortran code also generally use the default Fortran logical data type. + +
+ESMF defines a ESMF_Logical derived type for use when passing logical values between Fortran and C++ code. The constants ESMF_TRUE and +ESMF_FALSE are available, and must be used to ensure compatibility with the C++ code. + +
+For convenience, defined assignment operators are available which convert between Fortran logical and the ESMF_Logical derived type. +Finally, there are .eq. and .ne. operators defined to compare ESMF_Logical values. + +
+
+ subroutine ESMF_SomeRoutine(myFlag) + use ESMF + implicit none + + logical, intent(inout) :: myFlag + + type(ESMF_Logical) :: myFlag_local + + myFlag_local = myFlag ! Defined assignment + if (myFlag_local .eq. ESMF_TRUE) then ! Use of .eq. operator + call c_ESMC_SomeCRoutine (myFlag_local) ! Pass to C++ + else + call c_ESMC_OtherCRtoutine (myFlag_local) + end if + myFlag = myFlag_local ! Defined assignment + end subroutine ++ +
+ +
+ESMF C datatypes are also declared with the property that their size remains constant across platforms. This convention is set in order to make ESMF more robust in terms of portability, as well as for the correct matching of Fortran-C routine interfaces. They have a direct size correspondence to their Fortran counterparts. Their names are: + +
+
+ ESMC_I4 (=) integer type of size 4 bytes + ESMC_I8 (=) integer type of size 8 bytes + ESMC_R4 (=) floating point type of size 4 bytes + ESMC_R8 (=) floating point type of size 8 bytes ++ +
+e.g. +
+ ESMC_R4 someFloat; ++here someFloat is a 4 byte floating point in any platform. + +
+Real Data: + +
+ ESMC_R<n> RealVariable; ++ where is the size in bytes of the memory occupied by each real datum. (Allowed values of n are those that correspond to supported type/kind data). e.g. +
+ ESMC_R8 a,b; ++ which declares a and b to be 8 byte reals. + +
+
+Integer Data: + +
+
+Boolean Data: + +
+
+
+ void fortran_caller(bool &myFlag) { + ESMF_Logical myFlag_local; + + myFlag_local = myFlag; + if (myFlag_local == ESMF_TRUE) + ESMF_SomeFortranRoutine (&myFlag_local); // Pass to Fortran + else + ESMF_OtherFortranRtoutine (&myFlag_local); + + myFlag = myFlag_local; + } ++ +
+ +
+An enumerated parameter in C++ and a corresponding sequence parameter in Fortran are provided in order to identify the type-and-kind of data being processed in various ESMF routines. There is a one to one correspondence between the Fortran sequence and the C++ enumerated type. They are mostly used as a tool to customize code for a specific data type and kind, and to insure the correct handling of user data across Fortran-C interfaces. + +
+In Fortran this sequenced type's name is ESMF_TypeKind_Flag. + +
+The ESMF_TypeKind_Flag parameter names declared are: + +
+
+ ESMF_TYPEKIND_I4 (4 byte integer) + ESMF_TYPEKIND_I8 (8 byte integer) + ESMF_TYPEKIND_R4 (4 byte floating point) + ESMF_TYPEKIND_R8 (8 byte floating point) ++ +
+The following are supported for user interface use only (they are not to be used internally in the ESMF framework): +
+ ESMF_TYPEKIND_I (labels integer_not_autopromoted data) + ESMF_TYPEKIND_R (labels real_not_autopromoted data) ++ +
+Fortran ESMF_TypeKind_Flag parameters mostly appear in calls to C routines that create or manipulate arrays, fields, or bundles. e.g. +
+ .... + ESMF_TypeKind_Flag :: tk + ... + !-set tk + ... + call FTN_X(c_ESMC_VMAllFullReduce( ..., tk, ... ) + ... + ... ++Likewise in C the enumerated type's name is ESMC_TypeKind_Flag. + +
+The ESMC_TypeKind_Flag parameter names declared are: +
+ ESMC_TYPEKIND_I4 (4 byte integer) + ESMC_TYPEKIND_I8 (8 byte integer) + ESMC_TYPEKIND_R4 (4 byte floating point) + ESMC_TYPEKIND_R8 (8 byte floating point) ++ +
+In C, ESMC_TypeKind_Flag parameters are used to tailor computation to the type and kind of user data arguments being processed. e.g +
+ void FTN_X(c_esmc_vmallfullreduce)(.., ESMC_TypeKind_Flag *dtk, ..,int *rc){ + ..... + switch (*dtk){ + case ESMC_TYPEKIND_I4: + .... + break; + case ESMC_TYPEKIND_R4: + .... + break; + case ESMC_TYPEKIND_R8: + ... + break; + default: + .... + } + ... ++ +
+ +
+There must be a one to one correspondence of Fortran and C arguments as illustrated in the table below. So for example, if a Fortran routine calls a C method that expects an argument of type ESMC_I4, the argument in the Fortran call should be declared to be an integer of kind=ESMF_KIND_I4. +
+ integer(ESMF_KIND_I4) <--> ESMC_I4 [4 bytes] + integer(ESMF_KIND_I8) <--> ESMC_I8 [8 bytes] + real(ESMF_KIND_R4) <--> ESMC_R4 [4 bytes] + real(ESMF_KIND_R8) <--> ESMC_R8 [8 bytes] + integer <--> int + type(ESMF_Logical) <--> ESMC_Logical + etc. ++Also, ESMF_TypeKind_Flag and ESMC_TypeKind_Flag values are set to have matching values. That is: +
+ ESMF_TYPEKIND_I<n> = ESMC_TYPEKIND_I<n> + ESMF_TYPEKIND_R<n> = ESMC_TYPEKIND_R<n> ++ +
+Character strings: + +
+When passing character strings to subprograms, most Fortran compilers pass +'hidden' string length arguments by value after all of the user-supplied arguments. +Each hidden argument corresponds to each character string that is passed. +Because of varying compiler support of 32-bit vs 64-bit string lengths, +the ESMCI_FortranStrLenArg macro is used in C++ code to specify the +data type of the hidden arguments. + +
+For input arguments is usually convenient to copy the Fortran string into a +C++ string. The ESMC_F90lentrim procedure provides a common way +to obtain the length of the Fortran string - while ignoring trailing blanks. +It is analogous to the Fortran len_trim intrinsic function. + +
+
+ void FTN_X(c_esmc_somecode) ( + const char *name1, // in - some name in a character string + const char *name2, // in - some other name + int *rc, // out - return code + ESMCI_FortranStrLenArg name1_l, // in - hidden length of name1 + ESMCI_FortranStrLenArg name2_l) { // in - hidden length of name2 + + string name1_local = string (name1, ESMC_F90lentrim (name1, name1_l)); + string name2_local = string (name2, ESMC_F90lentrim (name2, name2_l)); + ... + } ++ +
+Likewise, when C++ code needs to pass a character string to Fortran code, +passing the string itself is performed by it address. The hidden length +argument uses the standard string length method: + +
+
+ FTN_X(f_esmf_somef90code) ( + name1_local.c_str(), + name2_local.c_str(), + &localrc, + (ESMCI_FortranStrLenArg) name1_local.length(), + (ESMCI_FortranStrLenArg) name2_local.length()) ++ +
+Note that when an array of characters is passed, the hidden string size is +that of an individual array element. The size of each dimension of the array +should be explicitly passed through separate arguments. Thus, in the following +declaration, the hidden argument would have a value of 32. The dimensions, 20 +and 30, would need to be separately passed: + +
+
+ character(32) :: char_array(20,30) + : + call c_esmc_something ( & + char_array, size (char_array,1), size (char_array, 2), & + localrc) ++ +
+ +
+ +
+ +
+Optional arguments in the public ESMC interface are implemented using the +variable-length argument list functionality provided by <stdarg.h>. +The <stdarg.h> header contains a set of macros which allows portable +functions that accept variable-length argument lists (also known as variadic +functions) to be written. Variadic functions are declared with an ellipsis in +place of the last parameter and must have at least one named (fixed) parameter. +A typical example of such a function is printf which is declared as + +
+
+ int printf(char *fmt, ...). ++ +
+The following type and macros are provided by <stdarg.h> for processing +variable-length argument lists. + +
+In order to correctly retrieve arguments from the variable argument list it is +necessary to know the type of each argument. In order to correctly terminate +parsing the variable argument list it is also necessary to know the number of +arguments in the list. Since the number of arguments and their types +are not known at compile time the best one can do is establish a convention +such that the caller will provide type and length information about the variable +argument list. The convention, however, is not a guarantee that the caller does +not mistakenly specify the types or number of arguments. +The scanf and printf functions do this by having +the last fixed argument be a character (format) string in which the caller +specifies the types (for example, "%f%d%s" for each argument in the +variable argument list. Although, the format string specifies the number of +expected arguments there is no actual "termination-flag" inserted at the end of +the variable argument list. If the caller incorrectly specifies the in the format +string more arguments than are actually provided then the function will likely +access invalid sections of memory while parsing the variable argument list. +Unless this error is trapped by the system the function will unwittingly process +erroneous data. + +
+ +
+The following conventions are established for the public ESMC optional argument
+API. The "class" associated with this API is called ESMC_Arg and its
+header files are located in Infrastructure/Util/include. The public
+optional argument API for a class is provided by the public header for that class
+together with ESMC_Arg.h. Macros for internal processing of optional
+arguments are provided by the ESMCI_Arg.h header.
+Each ESMC class has a set of named optional arguments associated with its
+methods. Associated with each optional argument of a class is a unique (within
+the class) optional argument identifier (id) of type
+ESMCI_ArgID. The optional argument list provided by
+the caller must consist of a sequence of argument identifier and argument
+(id, arg) pairs. The optional argument list must be terminated
+by the global identifier ESMCI_ArgLastID.
+The ESMC_ArgLast macro is provided by ESMC_Arg.h for the
+user to indicate the end of an optional argument list.
+
+
+
+The global identifier ESMCI_ArgBaseID is the starting identifier for +local (class) optional argument identifiers. ESMCI_ArgBaseID +establishes a set of global optional argument identifiers, such that, the global +set does not intersect with any class identifier set. +The optional argument identifier list for a class will be declared in the public +header for that class. The naming convention for optional argument identifiers +is +
+ ESMCI_<ClassName>Arg<ArgName>ID ++where ClassName is the +name of the class and ArgName is the name of the optional argument with +the first letter capitalized. The optional argument identifier list is declared +as enumeration constants with the first identifier set equal to +ESMCI_ArgBaseID. Here is an example for a class called "Xclass". +
+ // Optional argument identifier list for the ESMC_Xclass API. + enum { + ESMCI_XclassArgAoptID = ESMCI_ArgBaseID, // ESMC_I1 + ESMCI_XclassArgBoptID, // ESMC_I4 + ESMCI_XclassArgCoptID, // ESMC_R4 + ESMCI_XclassArgDoptID, // ESMC_R8 + ESMCI_XclassArgEoptID, // ESMC_Fred + }; ++ +It is helpful for the class developer to list the data type of +each optional argument (as a comment) with its associated id. +
+The ESMCI_Arg(ID,AR) internal macro (declared in ESMC_Arg.h) +is provided for casting an optional argument and its associated id into +the required sequence for passing to functions. +
+ #define ESMCI_Arg(ID,ARG) ((ESMCI_ArgID)ID),(ARG) ++ +Each class will use this internal macro in its public header to declare +user macros for the class specific optional arguments. +The naming convention for class specific optional argument expansion macros +is +
+ ESMC_<ClassName>Arg<ArgName>(ARG) ++where ClassName is the +name of the class and ArgName is the name of the optional argument with +the first letter capitalized. The argument of the macro is the actual caller +provided optional argument. Here is an example of how the macros are used for +the class "Xclass". +
+ // Argument expansion macros for the ESMC_Xclass API. + #define ESMC_XclassArgAopt(ARG) ESMCI_Arg(ESMCI_XclassArgAoptID,ARG) + #define ESMC_XclassArgBopt(ARG) ESMCI_Arg(ESMCI_XclassArgBoptID,ARG) + #define ESMC_XclassArgCopt(ARG) ESMCI_Arg(ESMCI_XclassArgCoptID,ARG) + #define ESMC_XclassArgDopt(ARG) ESMCI_Arg(ESMCI_XclassArgDoptID,ARG) + #define ESMC_XclassArgEopt(ARG) ESMCI_Arg(ESMCI_XclassArgEoptID,ARG) ++ +Here is an example call, with properly specified optional arguments, to a class +function. The function has three named (fixed) arguments. +
+ rc = ESMC_XclassFunc(fixedArg1,fixedArg2,fixedArg3, + ESMC_XclassArgAopt(aOptArg), + ESMC_XclassArgCopt(cOptArg), + ESMC_XclassArgDopt(dOptArg), + ESMC_ArgLast) ++ +
+ +
+Internal macros for processing the optional argument list are declared in +ESMCI_Arg.h. These macros provide a consistent internal interface to +the macros defined in stdarg.h. What follows is a description of each +macro available to a class developer. + +
+ +
+The following type specific ESMCI_ArgGet macros are provided for
+returning optional argument values. These macros correctly account for the
+forced type conversions described above. In each macro, AP is the
+optional argument list pointer.
+
+
+Internal macros for returning standard C (non-pointer) types.
+
+ #define ESMCI_ArgGetChar(AP) (char)va_arg(AP,int) + #define ESMCI_ArgGetShort(AP) (short)va_arg(AP,int) + #define ESMCI_ArgGetInt(AP) (int)va_arg(AP,int) + #define ESMCI_ArgGetLong(AP) (long)va_arg(AP,long) + #define ESMCI_ArgGetLongLong(AP) (long long)va_arg(AP,long long) + #define ESMCI_ArgGetFloat(AP) (float)va_arg(AP,double) + #define ESMCI_ArgGetDouble(AP) (double)va_arg(AP,double) ++ +Internal macros for returning defined ESMC types. +
+ #define ESMCI_ArgGetI1(AP) (ESMC_I1)va_arg(AP,int) + #define ESMCI_ArgGetI2(AP) (ESMC_I2)va_arg(AP,int) + #define ESMCI_ArgGetI4(AP) (ESMC_I4)va_arg(AP,int) + #define ESMCI_ArgGetI8(AP) (ESMC_I8)va_arg(AP,ESMC_I8) + #define ESMCI_ArgGetR8(AP) (ESMC_R8)va_arg(AP,double) + #define ESMCI_ArgGetR4(AP) (ESMC_R4)va_arg(AP,double) ++ +Special internal macro for returning strings. +
+ #define ESMCI_ArgGetString(AP) va_arg(AP,char*) ++ +General internal macro for returning all non-converted types. +
+ #define ESMCI_ArgGet(AP,TYPE) va_arg(AP,TYPE) ++ +TYPE is the expected type of returned argument. + +
+ +
+Each class function with optional arguments will declare an optional argument +list pointer and optional argument list id. +
+ ESMCI_ArgList argPtr; // optional argument list pointer + ESMCI_ArgID argID; // optional argument list id ++ +
+Parsing the optional argument list consists of three distinct phases: initializing +the argument list pointer, retrieving each argument in succession based on its +id, and finalizing the argument list pointer. The block for retrieving +arguments must first retrieve an argument id. If that id is +not ESMCI_ArgLastID and is in the set of valid ids for that function, +then the argument is retrieved using a type-appropriate ESMCI_ArgGet +macro. The following example code should be considered as "template" code for +parsing an optional argument list. +
+ // parse the optional argument list: + ESMCI_ArgStart(argPtr,ifix); + while ( (argID = ESMCI_ArgGetID(argPtr)) != ESMCI_ArgLastID ) { + switch ( argID ) { + case ESMCI_XclassArgAoptID: + aOpt = ESMCI_ArgGetI1(argPtr); + break; + case ESMCI_XclassArgBoptID: + bOpt = ESMCI_ArgGetI4(argPtr); + break; + case ESMCI_XclassArgCoptID: + cOpt = ESMCI_ArgGetR4(argPtr); + break; + case ESMCI_XclassArgDoptID: + dOpt = ESMCI_ArgGetR8(argPtr); + break; + case ESMCI_XclassArgEoptID: + eOpt = ESMCI_ArgGet(argPtr,ESMC_Fred); + break; + default: + ESMC_LogDefault.MsgFoundError(ESMC_RC_OPTARG_BAD, "", &rc); + return rc; + } // end switch (argID) + } // end while (argID) + ESMCI_ArgEnd(argPtr); ++ +
+Prior to actually parsing the optional argument list a function must check the +list for proper specification. This is done by using a code block similar to the +parsing block shown above. The difference is that in this case the +ESMCI_ArgGet macros are only used to increment the argument list pointer. +
+ // check the optional argument list: + ESMCI_ArgStart(argPtr,lastFixed); + while ( (argID = ESMCI_ArgGetID(argPtr)) != ESMCI_ArgLastID ) { + switch ( argID ) { + case ESMCI_XclassArgAoptID: ESMCI_ArgGetI1(argPtr); break; + case ESMCI_XclassArgBoptID: ESMCI_ArgGetI4(argPtr); break; + case ESMCI_XclassArgCoptID: ESMCI_ArgGetR4(argPtr); break; + case ESMCI_XclassArgDoptID: ESMCI_ArgGetR8(argPtr); break; + case ESMCI_XclassArgEoptID: ESMCI_ArgGet(argPtr,ESMC_Fred); break; + default: + ESMC_LogDefault.MsgFoundError(ESMC_RC_OPTARG_BAD, "", &rc); + return rc; + } // end switch (argID) + } // end while (argID) + ESMCI_ArgEnd(argPtr); ++ +
+The following example shows how an optional argument list check block can be +structured to handle an optional argument whose type is call dependent. In this +case the type of the dValue optional argument depends on the value of the +ESMC_TypeKind_Flag argument tk (which is the last fixed argument). +
+ // check the optional argument list: + ESMCI_ArgStart(argPtr,tk); + while ( (argID = ESMCI_ArgGetID(argPtr)) != ESMCI_ArgLastID ) { + switch ( argID ) { + case ESMCI_ConfigArgCountID: ESMCI_ArgGetInt(argPtr); break; + case ESMCI_ConfigArgLabelID: ESMCI_ArgGetString(argPtr); break; + case ESMCI_ConfigArgDvalueID: + switch ( tk ) { + case ESMC_TYPEKIND_I4: ESMCI_ArgGetI4(argPtr); break; + case ESMC_TYPEKIND_I8: ESMCI_ArgGetI8(argPtr); break; + case ESMC_TYPEKIND_R4: ESMCI_ArgGetR4(argPtr); break; + case ESMC_TYPEKIND_R8: ESMCI_ArgGetR8(argPtr); break; + case ESMC_TYPEKIND_LOGICAL: ESMCI_ArgGetInt(argPtr); break; + case ESMC_TYPEKIND_CHARACTER: ESMCI_ArgGetString(argPtr); break; + } // end switch (tk) + break; + default: + ESMC_LogDefault.MsgFoundError(ESMC_RC_OPTARG_BAD, "", &rc); + return rc; + } // end switch (argID) + } // end while (argID) + ESMCI_ArgEnd(argPtr); ++ +
+ +
+ +
+ +
+The makefiles use GNU standard target names when possible. +The default rule is to remake the ESMF library. Targets exist +to build the unit and system tests, the examples, the demos, +and to run them together or individually. Targets also exist +to build the documentation and create pdf and html versions. +For more details on targets, refer to the README file in the top +level ESMF directory, and also the ESMF User's Guide. + +
+ +
+The unit tests, the system tests, the examples, and the demos all share +a common set of targets. The following target list illustrates the +options for the examples. The names unit_tests, system_tests, +demos, and all_tests can be substituted wherever examples +occurs. +
+ +
build/common.mk ++The rules exist +as pattern rules and are controlled by the variables set in a doc +directory's makefile. The pattern rules will build .tex from source code +and .pdf, .dvi and html files from .ctex files. + +
+Variables that can be set in the individual doc/makefiles are called +"makefile variables". These are: +
+Document file dependencies are set with: +
+The makefiles targets work from both local directory and from ESMF_DIR: +
+ +
+At the 'src' level, parallel to Infrastructure, Superstructure, and doc, +is another include directory. This is for private include files which are +ESMF-wide. These might include system-wide architecture dependent +#defines constants, etc. + +
+Below the Superstructure & Infrastructure level are the individual +component levels (TimeMgr, Field, Component, etc). Under each of these +directories is an include directory for the component specific include +files. + +
+ +
+ +
+ +
+Fortran allows the creation of generic subprogram names via the +INTERFACE facility. This lets the caller use a simplified +single name for a call. Then, based on the callers actual argument list, +the compiler will choose an appropriate specific routine to perform +the task. + +
+When several specific variants of a generic call exist, and only +differ in minor ways, for example by ESMF object type, it can be +desirable to have the variants generated from a single definition. +This allows improvements in the reliability and maintainability of +the code. Feature code can be added in a single place, and all +of the specific routines will automatically incorporate the new code. + +
+By convention, generic ESMF Fortran code uses the GNU C preprocessor +macro facility to generate specific routines. These routines generally +differ only in the type, kind, and rank of the dummy arguments. The +internal code is otherwise identical. + +
+When writing a cpp macro, the definition must be 'one line' long. +Since coding an entire subprogram requires many lines to implement, +a backslash character is used at the end of each line to concatenate +multiple lines from the input file into a single, very long, preprocessor +line. After macro expansion, each preprocessor line needs to be +converted into a sequence of Fortran statements. So again by +convention, at-sign characters, @, are used as the second-to-last +character in each line. After cpp has been run, the long lines from +the result are split at the @ characters by converting them to newline +characters. The tr command is used for this translation. + +
+ESMF Fortran files which need to be preprocessed in this manner use +the file name suffix .cppF90. This triggers the makefile system +to use the following sequence when processing the file: + +
+ +
+
+ +
+
+
+
+
+
+A simple example of generic code written in this style is: + +
+
+ module ESMF_Example_mod + use ESMF + implicit none + +! The following header needs to be preprocessed by the compiler, +! not the first cpp pass. So use a caret as the first character, +! rather than a pound-sign. + +^include "my_header.inc" + +! Define a generic name with three specific routines + + interface ESMF_generic_name + module procedure ESMF_ArraySpecifc + module procedure ESMF_FieldSpecfic + module procedure ESMF_MeshSpecific + end interface + + contains + +! Define a macro for expansion. Each line is terminated with a +! @\ sequence. Also note the use of ## for concatenation +! and # for stringization. + +#define MySpecificMacro(mclass, mthis) \ + subroutine mclass##Specific (mthis, rc) @\ + type(mclass), intent(inout) :: mthis @\ + integer, optional :: rc @\ + @\ + print *, |class = |, #mclass @\ + @\ + if (present (rc)) rc = ESMF_SUCCESSFUL @\ + @\ + end subroutine mclass##Specfic @\ + +! Expand macro for a few classes + +MySpecificMacro(ESMF_Array, array) +MySpefificMacro(ESMF_Field, field) +MySpecificMacro(ESMF_Mesh, mesh) + +end module ESMF_Example_mod ++ +
+Character string concatenation via the Fortran concatenation operator // +can be problematic due to the first pass preprocessing treating it as a C++ inline +comment. An alternative is to use the ESMF_StringConcat function. + +
+ +
+Rather than putting architecture names in all the source files, there will +be an ESMF-wide file which contains sections like this: +
+ #ifdef sgi + #define HAS_VFORK 0 + #define BCOPY_FASTER 1 + #define FOPEN_3RD_ARG 1 + #endif + + #ifdef sun + #define HAS_VFORK 1 + #define BCOPY_FASTER 0 + #define FOPEN_3RD_ARG 1 + #endif +This allows system-dependent code to be bracketed with +meaningful names: + +
+
+ + #if HAS_VFORK + vfork(); + #else + fork(); + exec(); + #endif ++and not an endless string of architecture names. + +
+ +
+ +
+ESMF supports autopromotion of user code with respect to integer and real data types. This is data that a user would put in an array or field. By autopromotion we mean compiling user code with , or similar options on those platforms where these options are available. If a code is compiled with autopromotion, user data will be processed correctly by ESMF. That is because user data arguments in ESMF calls already are overloaded for all TKR(type-kind-rank). It is important to note that ESMF itself must not be compiled with autopromotion flags. + +
+The ESMF API distinguishes four different flavors of integer and real arguments: + +
+The ESMF API handles integer user data by overloading for TKR. The ESMF API handles real user data by overloading for TKR. The ESMF API handles integer parameters by using the system's default integer type. The ESMF API handles real parameters by explicitly specifying a kind. + +
+As a result of the ESMF API conventions the autopromotion of integer and real user data is automatically handled within ESMF. + +
+Integer parameters that are arguments to ESMF calls must be protected against integer autopromotion by explicitly specifying their kind as ESMF_KIND_I in the user code. + +
+The safest way to handle real parameters is for the user to specify their explicit kind as expected by the API. However, the user may choose to omit the kind specifier for reasons of convenience. This however will make their code vulnerable with respect to autopromotion and make the user code less portable, breaking it where the system default real kind does not match the ESMF API. + +
+The requirements for safe interfacing of autopromoted user code with ESMF are as follows: + +
+ ... + + integer, dimension(:), pointer :: intptr !User data arg. + !->No need for + !kind specifier. + + integer(ESMF_KIND_I), dimension(3) :: counts ! Integer + ! parameter + + integer(ESMF_KIND_I), dimension(3) :: lbounds ! Integer + ! parameter + + integer(ESMF_KIND_I), dimension(3) :: ubounds ! Integer + ! parameter + + integer(ESMF_KIND_I) :: rc ! Integer + ! parameter + ... + call ESMF_LocalArrayCreate(array, counts, intptr, & + lboounds, ubounds, rc) ++ +
+
+ ... + type(ESMF_Clock) :: clock + real(ESMF_KIND_R8) :: runTimeStepCount + integer(ESMF_KIND_I) :: rc + ... + call ESMF_ClockGet(clock, runTimeStepCount, rc) ++
+e.g. In the following code excerpt ESMF_TypeKindFind() is used to determine at runtime the correct ESMF_TypeKind_Flag parameter to use in the ESMF_ArraySpecSet() routine in preparation for creation of an ESMF Array that will store integer data that may or may not be autopromoted. +
+ ... + integer :: iScalar + ... + type(ESMF_TypeKind_Flag) myTypeKind + myTypeKind= ESMF_TypeKindFind(iScalar) + call ESMF_ArraySpecSet(arrayspec, rank, myTypeKind, rc) ++
+ +
+We considered the possibility of expanding autopromotion support to ESMF routine integer parameter arguments, in addition to those storing user data. Two options were considered as explained below. The reasons why we decided against such support, after discussion with the ESMF community, are as follows: + +
+Rejected Options: + +
+We considered and rejected two alternate options for autopromotion support. Here we illustrate with an example their impact on both the user code and the ESMF code. Note that this routine is overloaded for data arrays for all TKR supported and thus supports both real and integer autopromotion of user data. + +
+1st option: support autopromotion of integers (options sizes 4 or 8 bytes) as long as all integer parameter arguments are of the same kind. + +
+2nd option: support autopromotion of integers (options sizes 4 or 8 bytes). Mixed integer argument kinds. + +
+For our example we use a call to ESMF_LocalArrayCreate() in each of the 2 option scenarios. In reading these example scenarios please keep in mind that ESMF code will not be compiled with autopromotion. + +
+That is because only user code autopromotion is being considered. Thus the following statement could have different meaning if it is found within ESMF than in user code: +
+ integer :: foo + + In ESMF-------------------------------- ===> foo is of default + integer kind/size. + + In User code compiled with autopromotion ==> foo is an integer + of kind/size + determined by + autopromotion flag. ++ +
+With 1st Option: + +
+
+ USER CODE: + ---- ----- + ... + integer, dimension(:), pointer :: intptr + integer , dimension(3) :: counts + integer , dimension(3) :: lbounds + integer , dimension(3) :: ubounds + integer :: rc + ... + ... + call ESMF_LocalArrayCreate(array, counts, intptr, & + lboounds, ubounds, rc) ++ +
+Changes in ESMF: + +
+The routine would need to be further overloaded in order to insure that all integer parameter call arguments (counts, lbounds, ubounds, and rc), are typecast to default integer inside the method (note that ESMF kind can be of size 4 or 8). It would be something like this: +
+ + subroutine ESMF_LocalArrayCreate(array, counts, intptr,.... & + lbounds, ubounds, rc) + ...... + integer(<esmfKind>) , intent(in), optional :: counts, & + lbounds, ubounds + integer(<esmfKind>), intent(out), optional :: rc + integer :: counts_noAP, lbounds_noAP, ubounds_noAP, rc_noAP + + if (PRESENT(counts)) counts_noAP=counts + if (PRESENT(lbounds)) lbounds_noAP=lbounds + if (PRESENT(ubounds)) ubounds_noAP=ubounds + ... + .... + if (PRESENT(rc)) rc=rc_nonAP + return ++ +
+With = ESMF_KIND_I4 in one copy and ESMF_KIND_I8 in the other. The number of copies of the routine will increase from 42 to 84. + +
+*(Note that in this particular routine, overloading is problematic because all the integer parameters are optional) + +
+With 2nd Option: +
+ USER CODE: + ---- ----- + ... + integer, dimension(:), pointer :: intptr + integer(ESMF_KIND_I4) , dimension(3) :: counts + integer(ESMF_KIND_I8), dimension(3) :: lbounds + integer , dimension(3) :: ubounds + integer :: rc + ... + ... + call ESMF_LocalArrayCreate(array, counts, intptr, & + lboounds, ubounds, rc) ++Changes in ESMF: + +
+The routine would need to be further overloaded to support call arguments counts, lbounds, ubounds, and rc each being of either 4-byte or 8-byte size. In order to provide for all possible combinations of data sizes for these 4 integer parameters, the number of overloads would increase from 42 to +, which explains why support of this option is not practical. + +
+ +
+ +
+ +
+ +
+ +
+
+ +
+ +
+ +
+ESMF is written in a combination of C/C++ and Fortran. +Techniques used in ESMF for interfacing C/C++ and Fortran codes +are described in the ESMF Implementation Report[#!bib:ESMFimplrep!#], +which is available via the Users tab on the ESMF website. These +techniques, which address issues of memory allocation, passing +objects across language boundaries, handling optional arguments, +and so on, are general and have been applied to multiple projects. + +
+We distinguish between these techniques and the conventions used +by the ESMF project when interfacing C/C++ and Fortran. These +conventions, which represent specific implementation choices, +require additional input and explanation, and this section in +the Guide is currently incomplete. The list below outlines +the topics that we intend to address: + +
+ +
+ +
+It is often necessary for C++ code to call Fortran code where optional arguments are +used. By convention, most Fortran compilers use a C NULL for the argument address +to indicate that the optional argument is missing. + +
+The following Fortran subroutine has optional arguments. Note that Fortran 77 style +adjustable size array dimensioning is used for array b: + +
+
+ subroutine f_ESMF_SomeProcedure (a, b, b_size, rc) + implicit none + real, intent(in), optional :: a + integer, intent(in) :: b_size + real, intent(out), optional :: b(b_size) + integer, intent(out), optional :: rc + + if (present (a)) then + ... = a + end if + ... + if (present (b)) then + b(i) = ... + end if + ... + if (present (rc)) then + rc = localrc + end if + end subroutine f_ESMF_SomeProcedure ++ +
+When calling the above from C++, NULL can be used to indicate missing arguments: + +
+
+ extern "C" { + FTN_X(f_esmf_someprocedure)(float &a, float &b, int &b_size, int &rc); + } + ... + // array b not present, so use NULL. + int b_size = 0; + FTN_X(f_esmf_someprocedure)(&a, NULL, &b_size, &rc); + ... + // array b is present. Pass size and address. + float *b = new float[20]; + int b_size = 20; + FTN_X(f_esmf_someprocedure)(&a, b, &b_size, &rc); ++ +
+ +
+This standard is derived from the GFDL Flexible + Modeling System Developers' + Manual +and the +coding standard for the NCAR Community Atmospheric + Model(CAM) +developed by Jim Rosinski. Other documents containing coding +conventions include the "Report on Column Physics Standards" +(http://nsipp.gsfc.nasa.gov/infra/) +and "European Standards For Writing and Documenting Exchangeable +Fortran 90 Code" +(http://nsipp.gsfc.nasa.gov/infra/eurorules.html). + +
+The conventions assume the use of embedded documentation extractor +ProTeX. + +
+ +
+
+ +
+
+The use of preprocessor directives in ESMF is permitted under the +following conditions: + +
+ +
+
+filename.f - fixed format, no preprocessing. +filename.F - free format, no preprocessing. + + +filename.f90 - fixed format, with preprocessing. +filename.F90 - free format, with preprocessing. ++
+
+
+
+implicit none ++ +
+in the module header, and every variable explicitly declared. + +
+There are a few restrictions on the length of a character variable: + +
+ +
+
+
+ +
+
+
+subroutine advection(flag) +integer, intent(in) :: flag +... +if( flag.EQ.1 )then + call upwind_advection( ... ) +else if( flag.EQ.2 )then + call smolar_advection( ... ) +... +endif +end subroutine advection +... +call advection(1) ++ +
+is discouraged. This should instead be written as: + +
+
+integer, parameter :: UPWIND=1, SMOLAR=2 +... +subroutine advection(flag) +integer, intent(in) :: flag +... +if( flag.EQ.UPWIND )then + call upwind_advection( ... ) +else if( flag.EQ.SMOLAR )then + call smolar_advection( ... ) +... +endif +end subroutine advection +... +call advection(UPWIND) ++ +
+
+ +
+
+ +
+
+
+module & + module_name +use & + module_name ++ +
+is forbidden. + +
+
+
+use & + module_name ++ +
+This is to be consistent with the dependency analysis performed by + mkmf outlined above. +
+
+ +
+Style is somewhat personal, and it would be needlessly restrictive to +attempt to impose style requirements. These are recommendations which +we believe will lead to pleasant encounters with clear, legible and +understandable code. The only style requirement we place is that of +consistency: a single code unit is required to be rigorous in +using the author's preferred set of stylistic attributes. It is not +onerous to follow a style: modern editors have many language-aware +features designed to produce a consistent, customizable style. + +
+Style recommendations include the following: + +
+ +
+ +
+ +
+Example: + +
+The header file for an ESMC_Widget is as follows: +
+**file ESMCI_Widget.h +// Internal Widget esmf class +#ifndef ESMCI_Widget_h +#define ESMCI_Widget_h + +namespace ESMCI { + +class Widget { +public: +Widget(); +~Widget(); +void Manufacture(); +}; + +} // namespace ESMCI ++ +
+The implementation file is: +
+***file ESMCI_Widget.C +#include <ESMCI_Widget.h> + +namespace ESMCI { + +Widget::Widget() { +... +} +Widget::~Widget() { +... +} +void Widget::Manufacture() { +... +} + +} // namespace ESMCI ++ +
+Lastly, when this object is used from C interface code, the following constructs are used: + +
+
+*** file ESMC_SomeInterface_F.C +#include <ESMCI_Widget.h> + +extern "C" { +// this cannot be in the ESMCI namespace, else it would change the +// linkage. We have two choices: 1) add using namespace ESMCI and +// then use Widget, else 2) qualify Widget, ESMCI::Widget +void FTN(c_esmc_someinterface)( +ESMCI::Widget **wptr, int *rc){ +#undef ESMC_METHOD +#define ESMC_METHOD "c_esmc_someinterface()" +if (rc!=NULL) +*rc = ESMC_RC_NOT_IMPL; + +..... +(*wptr)->Manufacture(); + +} + +} // extern "C" ++ +
+
+
+ +
+ +
+ +
+We provide two types of releases, public and internal, with similar tagging conventions. + +
+ +
+ +
+ +
+ +
+The ESMF team will adopt the Climate and Forecast (CF) Metadata
+conventions. These are available at:
+
+http://www.unidata.ucar.edu/software/netcdf/conventions.html
+
+ +
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/dev_guide/node9.html b/docs/nightly/fix/reconcile-info/dev_guide/node9.html new file mode 100644 index 000000000..3b0988f95 --- /dev/null +++ b/docs/nightly/fix/reconcile-info/dev_guide/node9.html @@ -0,0 +1,425 @@ + + + + + ++ +
+The ESMF Release Schedule is generated by the Change Review Board (CRB) (see section 2.3) +as the main outcome of its quarterly meetings. The release schedule is posted on the ESMF website home page +under Quick Links. + +
+ +
+The Task List +is used +to archive past, current, and future development tasks. It's updated by the Core Team +Manager during and after quarterly CRB meetings. The CRB bases the Release Schedule +on the Task List. The Task List is browsable by anyone and is located at +http://www.sourceforge.net/projects/esmf (click on Tasks). + +
+ +
+SourceForge provides the development team with a set of trackers. Current trackers are +Support Requests, Bugs, Feature Requests, Application Issues, and Operations. These are +described in more detail in section . + +
+An item entered into a tracker is called a ticket. Tickets are assigned a unique +number and can move from tracker to tracker. Tickets may be opened in response to a customer +request or as a result of some finding or need of the development team. + +
+The process for handling customer requests is located in Section . + +
+All trackers categorize requests similarly. Pull down menus can assign various criteria +including Assignee, Status (Open, Closed, etc.), Category (Array, Regrid, etc.), and Group +(Bug, Feature Request, etc.) Tickets can be sorted and viewed based on these criteria and +can be moved from one tracker to another. For example a ticket may start out as a support +request and be moved to the bug tracker for resolution. To move a ticket, simply change +the type using the type pull down menu. + +
+ +
+The SourceForge trackers allow the user to set the priority of a ticket. Priority nine is used +to label tickets that are associated with a task scheduled for release on the Task List. +These are the only tickets that should be labeled at this level. Priority levels one through +five can be used by individual developers to prioritize tickets that are not associated with +any upcoming release. + +
+ +
+
+Examples:
+
+
+ +
+The following guidelines should be used when determining ticket completion times: + +
+ +
+ +
+An estimated time to completion should be placed at the end of any ticket title labeled with +the LONG: key. If the time includes a design phase, this should be included in the +total estimate e.g. (7) equals 3 weeks design plus 4 additional weeks for completion. + +
+ +
+The tasks in the Task List are usually associated with +one or more items in the Feature Request, Bug, and Support Request +trackers. In order to cross-reference items, developers should label +both the item on the Task List and tracker tickets with a +unique key. The key should describe the task, be unique, and be followed by a +colon. Careful placement of keys will allow the CRB to quickly visualize +through the search mechanism all tasks necessary for a new release. The key +is highlighted in the example below: + +
+ +
+
+In Task List: STDIZE_INIT: Standardize Initialization Behavior
+
+
+
+In Bug Tracker:
+
+
+ +
+
+
+
+
+ +
+The Integrator is responsible for tracking various aspects of the +ESMF project to measure the implementation and testing progress. + +
+ +
+ +
+ +
+
+The graphs are a monthly breakdown from January 1, 2002 to the present. + +
+ +
+ +
+ +
+ + +esmf_support@ucar.edu + + + diff --git a/docs/nightly/fix/reconcile-info/dev_guide/prev.png b/docs/nightly/fix/reconcile-info/dev_guide/prev.png new file mode 100644 index 000000000..e60b8b407 Binary files /dev/null and b/docs/nightly/fix/reconcile-info/dev_guide/prev.png differ diff --git a/docs/nightly/fix/reconcile-info/dev_guide/prev_g.png b/docs/nightly/fix/reconcile-info/dev_guide/prev_g.png new file mode 100644 index 000000000..ac6f0bceb Binary files /dev/null and b/docs/nightly/fix/reconcile-info/dev_guide/prev_g.png differ diff --git a/docs/nightly/fix/reconcile-info/dev_guide/up.png b/docs/nightly/fix/reconcile-info/dev_guide/up.png new file mode 100644 index 000000000..3937e168f Binary files /dev/null and b/docs/nightly/fix/reconcile-info/dev_guide/up.png differ diff --git a/docs/nightly/fix/reconcile-info/dev_guide/up_g.png b/docs/nightly/fix/reconcile-info/dev_guide/up_g.png new file mode 100644 index 000000000..fb36cf765 Binary files /dev/null and b/docs/nightly/fix/reconcile-info/dev_guide/up_g.png differ