The C++ ELEMENTS library is a collection of sub-libraries to support implementing a diverse range of numerical methods on low and high-order meshes. The ELEMENTS library can be used for research and development of both continuous and discontinuous finite element methods, as well as, finite volume methods to solve a diverse range of partial differential equations. The ELEMENTS library includes the following sub-libraries: MATAR contains the routines to support dense and sparse matrices and arrays, SLAM contains the interfaces to solvers, linear algebra, and mathematical routines or external packages (e.g., Trilinos), elements contains the mathematical functions to support a large range of elements types including serendipity elements, SWAGE contains the routines and data-structures to support unstructured arbitrary-order 3D meshes that move or remain stationary, and geometry combines together SWAGE and elements. The ELEMENTS libary is designed to support Lagrangian (mesh moves) solid dynamics and mechanics codes, Eulerian (mesh is stationary) fluid dynamics codes, and many other code applications.
Fig. Code structure layout
Fig. A high-order 3D mesh deforming in the Taylor-Green vortex
The MATAR sub-library is designed for dense and sparse data representations, and follows the data-oriented programming approach for highly efficient calculations. MATAR leverages Kokkos for performance portability over diverse architectures. The data representations developed in MATAR and the numerical tools in ELEMENTS are designed for performance, portability, and productivity (i.e., ease of use). MATAR is stored in a separate repository as it can aid many applications, as such, it is included as a GitHub submodule in the ELEMENTS repository.
The SLAM sub-libary is a soon to be released capability to seemlessly allow users to solve linear systems (dense or sparse), to perform linear algebra opperations, or to apply mathematical opperators to data stored in MATAR. A prototype of SLAM exists and is being developed.
A mesh is composed of non-overlapping elements, where the elements sub-library contains the mathematical functions to support a very broad range of element types including:
- linear, quadratic, and cubic serendipity elements in 2D and 3D;
- arbitrary-order tensor product elements in 2D and 3D;
- arbitrary-order spectral elements; and
- a linear 4D element.
The elements sub-library has functions to calculate quantities that are commonly used in finite element methods (both continuous and discontinous) such as a basis function, gradient of a basis function, the Jacobian matrix, the inverse Jacobian matrix, the determinant of the Jacobian matrix, and a physical position inside the element, to name a few examples. The elements sub-library also supports both Gauss-Legendre and Gauss-Lobatto quadrature rules up to 8 quadrature points in each coordinate direction.
The SWAGE sub-library contains a large suite of mesh data structures, a rich set of index spaces for different geometric entities, and many connectivity arrays between the various index spaces. This library supports both unstructured linear and arbitrary-order meshes. SWAGE is designed to support a diverse range of methods that arise in computational physics and engineering.
Fig. A mesh with cubic serendipity elements
The geometry sub-library combines SWAGE with elements to deliver the required capabilities to implement a large range of numerical methods on unstructured linear or high-order meshes.
The examples folder contains a simple code to calculate an average from the
cells to nodes and then back. A figures folder within the examples folder
contains diagrams to illustrate, for instance, the code project layout,
geometric index spaces, and various capabilties supported by the ELEMENTS
library. When beginning your exploration of ELEMENTS, the file
/examples/average/test/average.cpp
is a good place to start seeing how all the
pieces fit together. See the README in the examples folder for additional
information. Additionally, the Fierro project https://github.com/lanl/Fierro
shows a much more comprehensive usage.
To clone the ELEMENTS repository, enter
git clone https://github.com/lanl/ELEMENTS.git
at the command line. Next, make sure to pull the MATAR submodule by entering
git submodule update --init
To build ELEMENTS in place, simply enter
cmake .; make
at the command line from the top-level directory in your local ELEMENTS repository.
To build ELEMENTS in a separate build directory, create the build directory somewhere in your filesystem. For example, you might enter
mkdir build; cd build
You might also create a configuration script like, for example,
#!/bin/bash
ELEMENTS_DIR=/path/to/local/elements/repository
cmake \
-DCMAKE_INSTALL_PREFIX=`pwd` \
-DCMAKE_BUILD_TYPE=Debug \
-DENABLE_BLAS_LAPACK=ON \
-DENABLE_VTK=ON \
-DVTK_DIR=/path/to/vtk/installation
${ELEMENTS_DIR}
where the CMake installation directory is configured to be the directory in which the configuration script is run (in this example, the build/
directory created above).
(The example configuration above compiles ELEMENTS with the optional BLAS/LAPACK and VTK dependencies.)
Then enter
./my_config.sh; make
at the command line (assuming you named your configuration script my_config.sh
).
There is an additional cmake flag that is experimental at this time:
-DVTK_DIR=${HOME}/packages/vtk/build-9.0 \
VTK is only required to read VTK meshes and is not required to write VTK output.
To install the ELEMENTS libraries and header files (with an in-place build or otherwise), enter
make install
at the command line. This will copy the ELEMENTS libraries to the directory
specified by the CMAKE_INSTALL_PREFIX
variable. In particular, the libraries
will be copied to a lib/
subdirectory and the header files will be copied to a
include/
subdirectory. If the install prefix is not specified in a
configuration file, CMake will use the default, which on Linux is /usr/local/
and the copy will require administrative privileges.
Warning: if linking against the libelements
library, you must define a global
variable elem
that specifies the class of element.
If ELEMENTS is installed as a library via make install
, using it is straightforward. In a cmake
build system, something like the following will be necessary. In an appropriate
CMakeLists.txt add:
# Add the ELEMENTS include directory and find the appropriate libraries
include_directories(${ELEMENTS_DIR}/include)
find_library(COMMON_LIBRARY NAMES common HINTS ${ELEMENTS_DIR}/lib)
find_library(ELEMENTS_LIBRARY NAMES elements HINTS ${ELEMENTS_DIR}/lib)
find_library(GEOMETRY_LIBRARY NAMES geometry HINTS ${ELEMENTS_DIR}/lib)
find_library(SWAGE_LIBRARY NAMES swage HINTS ${ELEMENTS_DIR}/lib)
# Make includes and linking work
# For an executable named "Average"
add_executable(Average ${Average_SRC_CXX})
target_link_libraries (Average ${COMMON_LIBRARY})
target_link_libraries (Average ${ELEMENTS_LIBRARY})
target_link_libraries (Average ${GEOMETRY_LIBRARY})
target_link_libraries (Average ${SWAGE_LIBRARY})
and on the command line for cmake add :
cmake \
-D ELEMENTS_DIR=/path/to/ELEMENTS \
...
Where /path/to/ELEMENTS
should be
the directory immediately containing /include
and /lib
.
@article{MOORE2019100257,
title = "{ELEMENTS: A high-order finite element library in C++}",
journal = {SoftwareX},
volume = {10},
pages = {100257},
year = {2019},
issn = {2352-7110},
doi = {https://doi.org/10.1016/j.softx.2019.100257},
url = {https://www.sciencedirect.com/science/article/pii/S235271101930113X},
author = {Jacob L. Moore and Nathaniel R. Morgan and Mark F. Horstemeyer},
keywords = {Element Library, C++, High-order elements, Spectral elements, Serendipity elements}