Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve MultiMat Sphinx documentation #1476

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file added src/axom/multimat/docs/sphinx/figures/mapping.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 29 additions & 2 deletions src/axom/multimat/docs/sphinx/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,33 @@ Multimat User Guide
====================

Axom's MultiMat component is a data management library for multimaterial field data
within multiphysics simulation codes.
within multiphysics simulation codes. Simulation codes use materials to overlay extra
parts and details onto a mesh without requiring those features to be modeled
conformally. Instead of using cells to model the part geometry, the geometry is
instead represented using materials and volume fractions. The method for adding
such details is often called *"shaping"* and it is covered in Axom's
:doc:`Klee <../../../../axom/klee/docs/sphinx/index>` and :doc:`Quest <../../../../axom/quest/docs/sphinx/index>`
components.

We are working on documentation for this component.
In addition to representing materials on a mesh, MultiMat is used to define
fields on the mesh, and over material subsets. This enables fields to contain multiple
values where needed for mixed-material cells. MultiMat supports flexible data mappings,
layouts, and dense vs sparse field storage, allowing field data to occupy less memory
than would otherwise be necessary.



API Documentation
-----------------

Doxygen generated API documentation can be found here: `API documentation <../../../../doxygen/html/coretop.html>`_
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This links to the top of core instead of multimat. Maybe the last bit needs to be multimattop.html?
Doxygen multimat page: https://axom.readthedocs.io/en/feature-whitlock-multimat_documentation/doxygen/html/multimattop.html

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks - fixed it.



.. toctree::
:caption: Contents
:maxdepth: 1

multimat_materials
multimat_field_concepts
multimat_using_fields
multimat_dynamic_mode
49 changes: 49 additions & 0 deletions src/axom/multimat/docs/sphinx/multimat_dynamic_mode.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
.. ## Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and
.. ## other Axom Project Developers. See the top-level LICENSE file for details.
.. ##
.. ## SPDX-License-Identifier: (BSD-3-Clause)

******************************************************
Dynamic Mode
******************************************************

The distribution of materials in MultiMat is controlled by the
Cell-Material Relation (CMR). For many MultiMat use cases, this is set
once (static mode) and then fields are defined on the MultiMat object. MultiMat
also supports a dynamic mode that permits materials to move around in the mesh.

When creating a MultiMat object using the default constructor, it will default
to static mode using ``CELL_DOM`` data layout with sparse data. The data layout
argument later impacts the ``addEntry()`` and ``removeEntry()`` methods that modify
the MultiMat object's CMR in dynamic mode. For those methods, when MultiMat is
created with a ``CELL_DOM`` data layout, it means that the first argument to
``addEntry()`` will be a cell number and the second will be a material number.

To convert the MultiMat object to dynamic mode, call the ``convertToDynamic()``
method. This method changes some internal representations (including field
organization) to better support dynamic modifications of the CMR. For example,
when changing to dynamic mode, ``SPARSE`` fields are converted to ``DENSE``
so further changes do not require field data to be reallocated/reorganized
again. The CMR is modfified using calls to the ``addEntry()`` and ``removeEntry()``
BradWhitlock marked this conversation as resolved.
Show resolved Hide resolved
methods.

.. code-block:: cpp

constexpr int nmats = 3;
constexpr int ncells = 9;

axom::multimat::MultiMat mm;

// Multimat initialization omitted

// Switch to dynamic mode
mm.convertToDynamic();

// Add material 2 in zone 3 that was not there before.
mm.addEntry(3, 2);

// Remove material 1 in zone 5
mm.removeEntry(5, 1);

// Volume fraction updates omitted (iterate Volfrac field, set new values)

118 changes: 118 additions & 0 deletions src/axom/multimat/docs/sphinx/multimat_field_concepts.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
.. ## Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and
.. ## other Axom Project Developers. See the top-level LICENSE file for details.
.. ##
.. ## SPDX-License-Identifier: (BSD-3-Clause)

******************************************************
Field Concepts
******************************************************

Fields are data that are defined over a mesh, typically with one or more values
per cell. Fields can be scalar, indicating 1-component per cell - or they can
contain multiple components as with vector data (2+ components per cell). This
section talks about important MultiMat field concepts that determine where fields
live on the mesh and how their data are organized in memory.

#######################
Field Mapping
#######################

MultiMat is associates materials with cells in a mesh, possibly subdividing cells.
MultiMat includes the concept of field *mapping*, which is where on the mesh the
field data live. Fields can be defined over the cells, which is how most simulations
think about cell-centered fields. With MultiMat, fields can also be defined over
the materials, allowing for compact storage of material-level data. Fields can
also be defined over the cells/material pairs from the Cell-Material Relation (CMR),
allowing fields to have data values for each material in a cell.

.. figure:: figures/mapping.png
:figwidth: 800px

Diagram showing field mapping concept.

+--------------------+----------------------------------------------------------+
| FieldMapping | Meaning |
+====================+==========================================================+
| PER_CELL | The field contains up to ncells*ncomponents values (for |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: A space before and after the * in this table and elsewhere may make the sizing dimensions more clear.
(ncells * ncomponents versus ncells*ncomponents).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added spaces.

| | dense storage) and there are ncomponents values per cell.|
| | For scalars *ncomponents* is 1 so the field length is |
| | ncells. |
+--------------------+----------------------------------------------------------+
| PER_MAT | The field contains nmats*ncomponents values and there |
| | are ncomponents values per material. This mapping allows |
| | fields to be defined over the entire material region and |
| | any cell that uses the material inherits the per-material|
| | field value, allowing for very compact storage of |
| | material-level properties. |
+--------------------+----------------------------------------------------------+
| PER_CELL_MAT | The field contains up to ncells*nmats*ncomponents (for |
| | dense storage). This mapping allows materials within a |
| | cell to have their own unique values, which makes them |
| | useful for tracking data at a sub-cell level. |
+--------------------+----------------------------------------------------------+

#######################
Data Layout
#######################

Simulation codes contain a variety of algorithms that may have a preference for how
data are arranged in memory to ensure good performance. MultiMat supports
fields with a ``PER_CELL_MAT`` mapping and there are two ways to organize such data.
Fields are said to be **Cell-Dominant** (``CELL_DOM``) if they are stored such that
each cell stores all of its material data to memory before proceeding to data for
the next cell. Fields are **Material-Dominant** (``MAT_DOM``) if the data for all
cells that use the material is stored before proceeding to the next material.
The data layout for multi-material data can be thought of as 2 nested for-loops where
the outer loop is the dominant loop. For example, if iterating over materials and
then cells, the data are stored using ``MAT_DOM`` layout.

+--------------------+----------------------------------------------------------+
| DataLayout | Meaning |
+====================+==========================================================+
| CELL_DOM | Data are stored for each cell and then for each material |
| | like this *(c=cell, m=material)*: |
| | |
| | ``{c0m0, c0m1, c0m2, ..., c1m0, c1m1, c1m2, ...}`` |
+--------------------+----------------------------------------------------------+
| MAT_DOM | Data are stored for each material and then for each cell |
| | like this *(c=cell, m=material)*: |
BradWhitlock marked this conversation as resolved.
Show resolved Hide resolved
| | |
| | ``{m0c0, m0c1, m0c2, m0c3, ... , m1c0, m1c1, m1c2, ...}``|
+--------------------+----------------------------------------------------------+

#######################
Sparsity Layout
#######################

Sparsity primarily concerns fields with ``PER_CELL_MAT`` mapping. When initializing
the MultiMat object, the CMR indicates how materials are distributed
over the mesh. It is completely acceptable for materials to skip over certain cells,
which makes sense if we think about materials as a way to divide up the mesh into
various regions or parts. There are ncells*nmats pairs of data that could be entered
for MultiMat fields. For ``DENSE`` fields, the field must contain ncells*nmats values,
with values present for cell/material pairs even where the material is not present.
BradWhitlock marked this conversation as resolved.
Show resolved Hide resolved
This is an easy way to specify the data but it wastes memory due to the extra values
that do nothing other than keep the rectangular shape of the data array.

For large meshes, compressing out unnecessary values can save a lot of memory. MultiMat
supports a ``SPARSE`` layout that does not include any unnecessary values. Going back
to the CMR as a matrix of true/false values, one must only provide field values for
BradWhitlock marked this conversation as resolved.
Show resolved Hide resolved
``SPARSE`` data where the CMR contains true values.


.. figure:: figures/sparsity.png
:figwidth: 800px

Mixed-material volume fraction field with both DENSE and SPARSE representations.



+--------------------+----------------------------------------------------------+
| SparsityLayout | Meaning |
+====================+==========================================================+
| DENSE | Data are provided for all ncells*nmats pairs, even if |
| | there is no cell/material that is valid. |
+--------------------+----------------------------------------------------------+
| SPARSE | Data are provided for only the cell/material pairs that |
| | are valid according to the CMR. |
+--------------------+----------------------------------------------------------+
120 changes: 120 additions & 0 deletions src/axom/multimat/docs/sphinx/multimat_materials.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
.. ## Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and
.. ## other Axom Project Developers. See the top-level LICENSE file for details.
.. ##
.. ## SPDX-License-Identifier: (BSD-3-Clause)

******************************************************
Materials
******************************************************

MultiMat defines materials over the cells in a mesh. This section describes how to
use the MultiMat object to define materials.

#######################
Cell Material Relation
#######################

The distribution of materials over the mesh is determined using the **Cell-Material Relation** *(CMR)*.
If a mesh has *N* cells and *M* materials then each cell can have *M* possible values
if it contains all of the possible materials. There is a total of N*M values if each
cell contains all materials. There are multiple ways to specify the CMR to MultiMat. A
BradWhitlock marked this conversation as resolved.
Show resolved Hide resolved
static material decomposition is described here, though the CMR can also be built
:doc:`dynamically <multimat_dynamic_mode>`. The easiest method for defining the CMR is
to provide a bool vector containing true/false values for whether a cell/material
combination is valid.

.. figure:: figures/relation.png
:figwidth: 800px

Diagram showing mixed-material mesh with CELL_DOM and MAT_DOM ways of defining the Cell-Material Relation.

The following code shows how to initialize a MultiMat object with 9 cells and 3 materials
and build the CMR by populating a bool vector that is given to the MultiMat object.
In the following example, the relation is expressed using a **Cell-Dominant**
data layout (``CELL_DOM``). This means that the data will be arranged such that all material
values for cell 0 are given, followed by all of the material values for cell 1, until all
cells have provided their flags. The bool vector contains *true* if a material is present
in a cell and *false* if the material is not present. This CMR vector is essentially
a mask for which cell/material combinations are valid. Data can also be transposed
into a **Material-Dominant** data layout (``MAT_DOM``) in which the materials are
iterated first, followed by cells that use the current material.

.. code-block:: cpp

constexpr int nmats = 3;
constexpr int ncells = 9;

// Create the MultiMat object
axom::multimat::MultiMat mm;
mm.setNumberOfMaterials(nmats);
mm.setNumberOfCells(ncells);

// Cell-Dominant data layout
int rel[9][3] = {{1,1,0},
{1,1,1},
{0,1,1},
{1,1,1},
{0,1,1},
{0,0,1},
{0,1,1},
{0,0,1},
{0,0,1}};
std::vector<bool> relation(ncells * nmats, false);
for(int c = 0; c < ncells; c++)
{
for(int m = 0; m < nmats; m++)
{
relation[c * nmats + m] = rel[c][m] > 0;
}
}
mm.setCellMatRel(relation, axom::multimat::DataLayout::CELL_DOM);


#######################
Volume Fractions
#######################

The CMR determines how materials are allocated to each cell but it does not determine
how much of each material is present in the cell. Volume fractions determine how much of each material
exists in each cell and is given as a percentage. If a cell contains materials A and B

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider rephrasing to "The CMR determines which materials are present in each cell; volume fractions determine how much of each material is present in each cell." This shortens the first two sentences to one sentence with two parallel phrases: to me, this helps with clarity. Also, I don't think you need "given as a percentage," since the next sentence gives an example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

at 20% and 80%, respectively, then the volume fractions for those materials in the
cell are: *0.2* and *0.8*. Note that the sum of volume fractions in a cell must equal 1
to account for all of the cell. Volume fractions must be provided for every valid

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will multimat itself object if the volume fractions don't sum to 1? Is there a consistency check for this error mode, or will it just wait until it bites your algorithm?

Copy link
Member Author

@BradWhitlock BradWhitlock Dec 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't enforce it really, but it will flag the error if MultiMat::isValid() is called. I added a statement to this effect.

cell/material pair in the CMR and they must be specified using the same data layout
as data in the CMR.

.. figure:: figures/volume_fractions.png
:figwidth: 600px

Diagram showing mixed-material mesh with volume fractions shown in CELL_DOM table.

Volume fractions are stored in MultiMat as a field and fields have an added concept
of sparsity. Fields can provide data for every possible cell/material pair; this is
called a dense field. Dense fields are easy to understand since they have values for
every cell/material pair and they take more memory since zeroes must be provided even
for invalid cell/material pairs. Fields can also be sparse, which eliminates the zeroes
where a material does not exist.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: rephrase to "Dense fields are easy to understand: they have values for every cell/material pair. Dense fields store zeros for cells where a material is not present. Fields can also be sparse, saving memory by eliminating the zeros where a material does not exist."

(I think both "zeros" and "zeroes" are correct. Not sure on that.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.


Volume fraction data are provided to MultiMat wrapped in an ``axom::ArrayView`` object,
which provides the default values for the volume fractions. The *ArrayView* is passed
to MultiMat using the ``setVolfracField()`` method. The following example shows how to
pass a dense volume fraction field to MultiMat. Note the zeroes where the material is
not present. After adding volume fractions, the MultiMat object is fully constructed
and it can be used to store field data.

.. code-block:: cpp

double volfracs[9][3] = {{0.9, 0.1, 0.},
{0.22, 0.5, 0.28},
{0., 0.3, 0.7},
{0.25, 0.5, 0.25},
{0., 0.05, 0.95},
{0., 0., 1.},
{0., 0.4, 0.6},
{0., 0., 1.},
{0., 0., 1.}};
axom::ArrayView<double> vfView(&volfracs[0][0], ncells * nmats);
mm.setVolfracField(vfView,
axom::multimat::DataLayout::CELL_DOM,
axom::multimat::SparsityLayout::DENSE);

Loading