In scientific computing, systems of partial differential equations (PDEs) are solved on computers. One of the most widely used methods to solve PDEs numerically is to solve over discrete neighborhoods or "elements" of the domain. Popular discretization methods include Finite Difference (FD), Finite Element (FE), and Finite Volume (FV). These methods require the decomposition of the domain into a discretized representation, which is referred to as a "mesh". The mesh is one of the fundamental types of data linking the various tools in the analysis process (mesh generation, analysis, visualization, etc.). Thus, the representation of mesh data and operations on those data play a very important role in PDE-based simulations.
MOAB is a component for representing and evaluating mesh data. It is part of the Scalable Interfaces for Geometry and Mesh based Applications (SIGMA) toolkit [1]. MOAB can store structured and unstructured mesh, consisting of elements in the finite element "zoo", along with polygons and polyhedra. The functional interface to MOAB is simple, consisting of only four fundamental data types. This data is quite powerful, allowing the representation of most types of metadata commonly found on the mesh. Internally, MOAB uses array-based storage for fine-grained data, which in many cases provides more efficient access, especially for large portions of mesh and associated data. MOAB is optimized for efficiency in space and time, based on access to mesh in chunks rather than through individual entities, while also versatile enough to support individual entity access. MOAB is also unique in that it maintains a completely parallel view of the mesh database so that queries to traverse the cells and manipulation of the grid in memory is scalable in parallel.
The MOAB data model consists of the following four fundamental types: mesh interface instance, mesh entities (vertex, edge, tri, etc.), sets, and tags. Entities are addressed through handles rather than pointers, to allow the underlying representation of an entity to change without changing the handle to that entity. Sets are arbitrary groupings of mesh entities and other sets. Sets also support parent/child relationships as a relation distinct from sets containing other sets. The directed graph provided by set parent/child relationships is useful for embedding graphs whose nodes include collections of mesh entities; this approach has been used to represent a wide variety of application-specific data, including geometric model topology, processor partitions, and various types of search trees. Tags are named data which can be assigned to the mesh as a whole, individual entities, or sets. Tags are a mechanism for attaching data to individual entities, and sets are a mechanism for describing relations between entities; the combination of these two mechanisms is a powerful yet simple interface for representing metadata or application-specific data.
Various mesh-related tools are provided with MOAB or can be used directly with MOAB. These tools can be used for mesh format translation (mbconvert), mesh skinning (Skinner class), solution transfer between meshes (MBCoupler tool), ray tracing and other geometric searches (OrientedBoxTreeTool, AdaptiveKDTree), visualization (vtkMOABReader tool), mesh optimization/smoothing (Mesquite interfaces), and relation between mesh and geometric models (the separately-packed Lasso tool). These tools are described later in this document.
MOAB is written in the C++ programming language, with applications interacting with MOAB mostly through its moab::Interface class. All of the MOAB functions and classes are isolated in and accessed through the moab namespace1. The remainder of this report gives class and function names without the "moab::" namespace qualification; unless otherwise noted, the namespace qualifier should be added to all class and function names referenced here. MOAB also implements the iMOAB interface, which is a language-agnostic, lightweight interface that can be called directly from C, C++, Fortran, and Python. Almost all of the functionality in MOAB can be accessed through the iMOAB interface. MOAB is developed and supported on the Linux and MacOS operating systems, as well as various HPC operating systems. MOAB can be used on parallel computing systems as well, including laptops, workstations, clusters and high-end petascale/exascale parallel systems (e.g., NERSC-Perlmutter, OLCF-Frontier, ALCF-Aurora). MOAB is released under a standard LGPL open source software license.
MOAB is used in several ways in various applications. MOAB serves as the underlying mesh data representation in several scientific computing applications [2], [3], [4], [5], [6]. MOAB can also be used as a mesh format translator, using readers and writers included in MOAB. MOAB has also been used as a bridge to couple results in multi-physics analysis and to link these applications with other mesh services [7] in order to consistently solve problems at scale.
The remainder of this guide is organized as follows. Section 2, "Getting Started", provides a few simple examples of using MOAB to perform simple tasks on a mesh. Section 3 discusses the MOAB data model in more detail, including some aspects of the implementation. Section 4 summarizes the MOAB function API and related mesh services. Section 5 describes some of the tools included with MOAB, and the implementation of mesh readers/writers for MOAB. Section 6 describes how to build MOAB-based applications. Section 7 contains a detailed description of the iMOAB mesh interface and its capabilities. Sections 8 and 9 discuss MOAB's representations of structured and spectral element meshes, respectively. Section 10 gives helpful hints for accessing MOAB in an efficient manner from applications. Section 11 discusses parallel computing capabilities in MOAB. Section 12 covers advanced features including mesh quality assessment, remapping, and coupling. Section 13 gives a conclusion and future plans for MOAB development. Section 14 gives references cited in this report.
Several other sources of information about MOAB may also be of interest to readers. Meta-data conventions define how sets and /or tags are used together to represent various commonly-used simulation constructs in MOAB [8]. MOAB also has an active mailing list [9] to provide guidance and encourage discussions about usage and development of algorithms using MOAB. A separate mailing list [10] for MOAB-related release announcements and future guidance may also be subscribed by users. Potential users are encouraged to interact with the MOAB team using these mailing lists, and watch the SIGMA website [1] for updates.
1 Non-namespaced names are also provided for backward compatibility, with the "MB" prefix added to the class or variable name.
The MOAB data model describes the basic types used in MOAB and the language used to communicate that data to applications. This chapter describes that data model, along with some of the reasons for some of the design choices in MOAB.
MOAB is written in C++. The primary interface with applications is through member functions of the abstract base class Interface. The MOAB library is created by instantiating Core, which implements the Interface API. Multiple instances of MOAB can exist concurrently in the same application; mesh entities are not shared between these instances2. MOAB is most easily viewed as a database of mesh objects accessed through the instance. No other assumptions explicitly made about the nature of the mesh stored there; for example, there is no fundamental requirement that elements fill space or do not overlap each other geometrically.
2 One exception to this statement is when the parallel interface to MOAB is used; in this case, entity sharing between instances is handled explicitly using message passing. This is described in more detail in Section 11 of this document.
MOAB represents the following topological mesh entities: vertex, edge, triangle, quadrilateral, polygon, tetrahedron, pyramid, prism, knife, hexahedron, polyhedron. MOAB uses the EntityType enumeration to refer to these entity types (see Table 1). This enumeration has several special characteristics, chosen intentionally: the types begin with vertex, entity types are grouped by topological dimension, with lower-dimensional entities appearing before higher dimensions; the enumeration includes an entity type for sets (described in the next section); and MBMAXTYPE is included at the end of this enumeration, and can be used to terminate loops over type. In addition to these defined values, the an increment operator (++) is defined such that variables of type EntityType can be used as iterators in loops. MOAB refers to entities using "handles". Handles are implemented as long integer data types, with the four highest-order bits used to store the entity type (mesh vertex, edge, tri, etc.) and the remaining bits storing the entity id. This scheme is convenient for applications because:
This handle implementation is exposed to applications intentionally, because of optimizations that it enables, and is unlikely to change in future versions.
| MBVERTEX = 0 | MBPRISM |
| MBEDGE | MBKNIFE |
| MBTRI | MBHEX |
| MBQUAD | MBPOLYHEDRON |
| MBPOLYGON | MBENTITYSET |
| MBTET | MBMAXTYPE |
| MBPYRAMID |
MOAB defines a special class for storing lists of entity handles, named Range. This class stores handles as a series of (start_handle, end_handle) subrange tuples. If a list of handles has large contiguous ranges, it can be represented in almost constant size using Range. Since entities are typically created in groups, e.g. during mesh generation or file import, a high degree of contiguity in handle space is typical. Range provides an interface similar to C++ STL containers like std::vector, containing iterator data types and functions for initializing and iterating over entity handles stored in the range. Range also provides functions for efficient Boolean operations like subtraction and intersection. Most API functions in MOAB come in both range-based and vector-based variants. By definition, a list of entities stored in an Range is always sorted, and can contain a given entity handle only once. Range cannot store the handle 0 (zero).
Typical usage of an Range object would look like:
Here, the range is iterated similar to how std::vector is iterated.
The term adjacencies is used to refer to those entities topologically connected to a given entity, e.g. the faces bounded by a given edge or the vertices bounding a given region. The same term is used for both higher-dimensional (or bounded) and lower-dimensional (or bounding) adjacent entities. MOAB provides functions for querying adjacent entities by target dimension, using the same functions for higher- and lower-dimension adjacencies. By default, MOAB stores the minimum data necessary to recover adjacencies between entities. When a mesh is initially loaded into MOAB, only entity-vertex (i.e. "downward") adjacencies are stored, in the form of entity connectivity. When "upward" adjacencies are requested for the first time, e.g. from vertices to regions, MOAB stores all vertex-entity adjacencies explicitly, for all entities in the mesh. Non-vertex entity to entity adjacencies are never stored, unless explicitly requested by the application.
In its most fundamental form, a mesh need only be represented by its vertices and the entities of maximal topological dimension. For example, a hexahedral mesh can be represented as the connectivity of the hex elements and the vertices forming the hexes. Edges and faces in a 3D mesh need not be explicitly represented. We refer to such entities as "AEntities", where 'A' refers to "Auxiliary", "Ancillary", and a number of other words mostly beginning with 'A'. Individual AEntities are created only when requested by applications, either using mesh modification functions or by requesting adjacencies with a special "create if missing" flag passed as "true". This reduces the overall memory usage when representing large meshes. Note entities must be explicitly represented before they can be assigned tag values or added to entity sets (described in following Sections).
Entity sets are also known as "mesh sets", or when the context is clear, not to be confused with std::set, just "sets". Entity sets are used to store arbitrary collections of entities and other sets. Sets are used for a variety of things in mesh-based applications, from the set of entities discretizing a given geometric model entity to the entities partitioned to a specific processor in a parallel finite element application. MOAB entity sets can also store parent/child relations with other entity sets, with these relations distinct from contains relations. Parent/child relations are useful for building directed graphs with graph nodes representing collections of mesh entities; this construct can be used, for example, to represent an interface of mesh faces shared by two distinct collections of mesh regions. MOAB also defines one special set, the "root set" or the interface itself; all entities are part of this set by definition. Defining a root set allows the use of a single set of MOAB API functions to query entities in the overall mesh as well as its subsets.
MOAB entity sets can be one of two distinct types: list-type entity sets preserve the order in which entities are added to the set, and can store a given entity handle multiple times in the same set; set-type sets are always ordered by handle, regardless of the order of addition to the set, and can store a given entity handle only once. This characteristic is assigned when the set is created, and cannot be changed during the set's lifetime.
MOAB provides the option to track or not track entities in a set. When entities (and sets) are deleted by other operations in MOAB, they will also be removed from containing sets for which tracking has been enabled. This behavior is assigned when the set is created, and cannot be changed during the set's lifetime. The cost of turning tracking on for a given set is sizeof(EntityHandle) for each entity added to the set; MOAB stores containing sets in the same list which stores adjacencies to other entities.
Using an entity set looks like the following:
Entity sets are often used in conjunction with tags (described in the next section), and provide a powerful mechanism to store a variety of meta-data with meshes.
Applications of a mesh database often need to attach data to mesh entities. The types of attached data are often not known at compile time, and can vary across individual entities and entity types. MOAB refers to this attached data as a "tag". Tags can be thought of loosely as a variable, which can be given a distinct value for individual entities, entity sets, or for the interface itself. A tag is referenced using a handle, similarly to how entities are referenced in MOAB. Each MOAB tag has the following characteristics, which can be queried through the MOAB interface:
The storage type determines how tag values are stored on entities.
MOAB also supports variable-length tags, which can have a different length for each entity they are assigned to. Variable length tags are stored similarly to sparse tags.
The data type of a tag can either be one understood at compile time (integer, double, entity handle), in which case the tag value can be saved and restored properly to/from files and between computers of different architecture (MOAB provides a native HDF5-based save/restore format for this purpose; see Section 4.6). The opaque data type is used for character strings, or for allocating "raw memory" for use by applications (e.g. for storage application-defined structures or other abstract data types). These tags are saved and restored as raw memory, with no special handling for endian or precision differences.
An application would use the following code to attach a double-precision tag to vertices in a mesh, e.g. to assign a temperature field to those vertices:
The semantic meaning of a tag is determined by applications using it. However, to promote interoperability between applications, there are a number of tag names reserved by MOAB which are intended to be used by convention. Mesh readers and writers in MOAB use these tag conventions, and applications can use them as well to access the same data. Ref. [1] maintains an up-to-date list of conventions for meta-data usage in MOAB.
This section describes the design philosophy behind MOAB, and summarizes the functions, data types and enumerated variables in the MOAB API. A complete description of the MOAB API is available in online documentation in the MOAB distribution [11].
MOAB is designed to operate efficiently on collections of entities. Entities are often created or referenced in groups (e.g. the mesh faces discretizing a given geometric face, the 3D elements read from a file), with those groups having some form of temporal or spatial locality. The interface provides special mechanisms for reading data directly into the native storage used in MOAB, and for writing large collections of entities directly from that storage, to avoid data copies. MOAB applications structured to take advantage of that locality will typically operate more efficiently.
MOAB has been designed to maximize the flexibility of mesh data which can be represented. There is no explicit constraint on the geometric structure of meshes represented in MOAB, or on the connectivity between elements. In particular, MOAB allows the representation of multiple entities with the same exact connectivity; however, in these cases, explicit adjacencies must be used to distinguish adjacencies with AEntities bounding such entities.
The number of vertices used to represent a given topological entity can vary, depending on analysis needs; this is often the case in FEA. For example, applications often use "quadratic" or 10-vertex tetrahedral, with vertices at edge midpoints as well as corners. MOAB does not distinguish these variants by entity type, referring to all variants as "tetrahedra". The number of vertices for a given entity is used to distinguish the variants, with canonical numbering conventions used to determine placement of the vertices [12]. This is similar to how such variations are represented in the Exodus [13] and Patran [14] file formats. In practice, we find that this simplifies coding in applications, since in many cases the handling of entities depends only on the number of corner vertices in the element. Some MOAB API functions provide a flag which determines whether corner or all vertices are requested.
The MOAB API is designed to balance complexity and ease of use. This balance is evident in the following general design characteristics:
Interface::INTERSECT or Interface::UNION). This operation is applied to the results of the query, often eliminating the need for code the application would need to otherwise implement. For example, to find the set of vertices shared by a collection of quadrilaterals, the application would pass that list of quadrilaterals to a request for vertex adjacencies, with Interface::INTERSECT passed for the Boolean flag. The list of vertices returned would be the same as if the application called that function for each individual entity, and computed the intersection of the results over all the quadrilaterals. Applications may also input non-empty lists to store the results, in which case the intersection is also performed with entities already in the list. In many cases, this allows optimizations in both time and memory inside the MOAB implementation.Since these objectives are at odds with each other, tradeoffs had to be made between them. Some specific issues that came up are:
3 This convention applies only to query functions; attempts to add or subtract entities to/from the interface using set-based modification functions, or to add parents or children to the interface set, will fail.
4 This design choice was made to minimize the number of functions in the API, while preserving the ability to input single entities. The tradeoff is that single entities must be passed as pointers, which can be confusing to some users.
This section provides a comprehensive overview of the MOAB function API and the related mesh services that are available with MOAB. The MOAB API is designed to provide efficient access to mesh data while maintaining flexibility for various application needs.
The MOAB API is organized into several functional categories:
The core MOAB API provides fundamental operations on mesh entities:
get_entities_by_type(): Retrieve entities of a specific typeget_entities_by_dimension(): Retrieve entities of a specific dimensionget_connectivity(): Get vertex connectivity for entitiesget_coords(): Get coordinates for verticescreate_vertices(): Create new verticescreate_elements(): Create new elementscreate_meshset(): Create a new entity setadd_entities(): Add entities to a setremove_entities(): Remove entities from a setget_entities_by_handle(): Get entities in a setadd_parent_child(): Establish parent-child relationshipstag_get_handle(): Get or create a tagtag_set_data(): Set tag values on entitiestag_get_data(): Get tag values from entitiestag_delete(): Delete a tagtag_get_length(): Get tag size informationget_adjacencies(): Get adjacent entitiesget_entities_by_handle(): Get entities in a setget_entities_by_type_and_tag(): Get entities by type and tag valuesMOAB provides several mesh-related services and tools that extend its core functionality:
MOAB includes comprehensive support for mesh format conversion through the mbconvert tool and built-in readers/writers:
MOAB provides tools for analyzing mesh properties and quality:
Tools for modifying and manipulating meshes:
Efficient spatial search and query capabilities:
Tools for coupling different mesh-based applications:
Tools for visualizing mesh data:
Integration with the Mesquite library for mesh quality:
Here are some common examples of using the MOAB API:
When using the MOAB API, consider the following performance guidelines:
MOAB uses a comprehensive error handling system:
MOAB comes with a comprehensive set of tools and utilities for mesh processing and analysis.
The mbconvert tool provides format conversion capabilities:
MOAB provides several visualization tools:
MOAB provides various mesh analysis capabilities:
This section describes how to build applications that use MOAB, including compilation, linking, and deployment considerations.
MOAB applications require the following for compilation:
The recommended way to build MOAB applications is using CMake:
MOAB has several optional dependencies:
When linking MOAB applications:
Considerations for deploying MOAB applications:
The iMOAB interface provides a lightweight, language-agnostic C/Fortran interface to MOAB that exposes the underlying MOAB Interface object so that queries can be made seamlessly. This interface is designed to be simple, efficient, and portable across different programming languages and computing platforms. The iMOAB interface is the recommended approach for applications that need to integrate MOAB functionality across multiple programming languages or require a simplified interface to MOAB's capabilities.
The iMOAB interface follows several key design principles:
The iMOAB interface provides comprehensive access to MOAB's capabilities:
iMOAB provides native bindings for C and Fortran programming languages:
Note: MOAB itself provides Python bindings through the pymoab package, which is separate from the iMOAB interface.
Here are examples of using iMOAB in C and Fortran:
C Example:**
Fortran Example:**
iMOAB provides comprehensive support for parallel computing:
iMOAB supports advanced MOAB features:
MOAB provides comprehensive support for structured meshes through the ScdInterface class. This section describes the structured mesh capabilities and usage.
MOAB represents structured meshes using a parametric (i,j,k) coordinate system:
Structured meshes can be created using the ScdInterface:
MOAB provides various operations on structured meshes:
MOAB provides specialized support for spectral element methods, which are commonly used in high-order finite element applications.
Spectral elements are high-order finite elements that use specific quadrature points:
MOAB provides several tools for working with spectral elements:
This section provides guidelines for optimizing MOAB performance in your applications.
MOAB provides comprehensive support for parallel computing, enabling scalable mesh operations on distributed memory systems. This section describes the parallel computing capabilities and best practices for using MOAB in parallel applications.
MOAB's parallel architecture is based on the following principles:
The ParallelComm class provides the core parallel communication functionality:
MOAB supports efficient parallel I/O operations:
MOAB provides several tools for parallel mesh operations:
MOAB provides several advanced features that extend its capabilities beyond basic mesh operations.
MOAB integrates with the Mesquite library to provide comprehensive mesh quality assessment and improvement:
MOAB provides advanced remapping capabilities, particularly for climate science applications:
MOAB provides tools for coupling multiple physics applications:
MOAB provides efficient spatial query capabilities:
MOAB provides specialized support for spectral element methods:
MOAB integrates the Verdict library to provide comprehensive mesh quality assessment capabilities. Verdict calculates various quality metrics for different element types, helping users assess and improve mesh quality.
Verdict is a library used to calculate metrics on the following type of elements:
Verdict calculates individual or multiple metrics on a single element. The v_*_quality(...) functions allow for efficient calculations of multiple metrics on a single element. Individual metrics may be calculated on a single element as well.
The v_*_quality functions take the following parameters:
All other functions take these parameters below and return the calculated metric value:
In order to use v_*_quality functions you must know how to set the bitfield argument correctly. To calculate aspect ratio, condition number, shape and shear metrics on a triangle, set the "metrics_request_flag" like so:
The bitwise field can also be set for many metrics at once using #defined numbers. V_HEX_ALL, V_HEX_DIAGNOSTIC, V_TRI_ALGEBRAIC are examples.
Below is an example of how to use Verdict's functions:
Verdict provides a comprehensive set of quality metrics for each element type:
Hexahedral Metrics:**
Shear, shape, relative size, distortion
Tetrahedral Metrics:**
Shape, relative size, distortion
Quadrilateral Metrics:**
Relative size, distortion
Triangular Metrics:**
MOAB continues to evolve to meet the needs of the scientific computing community. Current development efforts focus on:
MOAB's open-source development model encourages community contributions and ensures that the library remains responsive to user needs. The active development community and comprehensive documentation make MOAB an excellent choice for mesh-based scientific computing applications.
[1] Mahadevan, Vijay S., Iulian Grindeanu, Rajeev Jain, Patrick Shriwise, Navamita Ray, Paul Wilson, Tautges, Timothy J., "SIGMA -- MOAB.", URL: http://sigma.mcs.anl.gov/
[2] Mahadevan, Vijay S., Iulian Grindeanu, Robert Jacob, and Jason Sarich. "Improving climate model coupling through a complete mesh representation: a case study with E3SM (v1) and MOAB (v5. x).", Geosci. Model Dev. Discuss., https://doi.org/10.5194/gmd-2018-280, in review, 2018.
[3] Mahadevan, Vijay S., Elia Merzari, Timothy Tautges, Rajeev Jain, Aleksandr Obabko, Michael Smith, and Paul Fischer. "High-resolution coupled physics solvers for analysing fine-scale nuclear reactor design problems." Philosophical Transactions of the Royal Society A: Mathematical, Physical and Engineering Sciences 372, no. 2021 (2014): 20130381.
[4] Yan, Mi, Kirk Jordan, Dinesh Kaushik, Michael Perrone, Vipin Sachdeva, Timothy J. Tautges, and John Magerlein. "Coupling a basin modeling and a seismic code using MOAB." Procedia Computer Science 9 (2012): 986-993.
[5] Jacob, Robert, Jayesh Krishna, Xiabing Xu, Tim Tautges, Iulian Grindeanu, Rob Latham, Kara Peterson et al. "ParNCL and ParGAL: Data-parallel tools for postprocessing of large-scale Earth science data." Procedia Computer Science 18 (2013): 1245-1254.
[6] Bohm, Tim D., Mohamed E. Sawan, Steve T. Jackson, and Paul PH Wilson. "Detailed nuclear analysis of ITER ELM coils." Fusion Engineering and Design 87, no. 5-6 (2012): 657-661.
[7] Tautges, Timothy J., and Alvaro Caceres. "Scalable parallel solution coupling for multiphysics reactor simulation." In Journal of Physics: Conference Series, vol. 180, no. 1, p. 012017. IOP Publishing, 2009.
[8] Tautges, Timothy J. "MOAB-SD: integrated structured and unstructured mesh representation." Engineering With Computers 20, no. 3 (2004): 286-293.
[9] MOAB Users and Developers Email List., moab-dev@mcs.anl.gov.
[10] MOAB Announcement Email List., moab-announce@mcs.anl.gov.
[11] MOAB online documentation., http://ftp.mcs.anl.gov/pub/fathom/moab-docs/index.html
[12] T.J. Tautges, “Canonical numbering systems for finite-element codes,” Communications in Numerical Methods in Engineering, vol. Online, Mar. 2009.
[13] L.A. Schoof and V.R. Yarberry, EXODUS II: A Finite Element Data Model, Albuquerque, NM: Sandia National Laboratories, 1994.
[14] M. PATRAN, “PATRAN User’s Manual,” 2005.
[15] VisIt User's Guide.