🔪 Decomposition
Partitioning
The idea of partitioning the domain is encapsulated within the
Domain
trait which is only responsible for the
partitioning process into multiple SubDomains
.
Within these smaller regions of space, all update steps are handled locally.
This also means that every aspect will be implemented on the SubDomain
level rather than on
the Domain
level.
The Domain
trait exposes the decompose
method
which is the single function that is responsible for the decomposition process.
fn decompose(
self,
n_subdomains: core::num::NonZeroUsize,
cells: Ci,
) -> Result<DecomposedDomain<Self::SubDomainIndex, S, C>, DecomposeError>;
It takes a current instance of a domain and the number of subdomains which should be generated.
Note that this method is not required to actually generate the exact amount but can opt to provide a
number which is lower than that of n_subdomains
.
This may be the case if a particular domain can not be divided arbitrarily often.
The resulting type is a
DecomposedDomain
which serves as a
simple container holding all information about the created subdomains and their neighbor status.
However this type is not used directly but only serves as an intermediate construct.
The chili backend (for example) will immediately use the entries to spawn
individual threads for each entry of the index_subdomain_cells
field of the DecomposedDomain
.
SubDomains
The SubDomain
trait is the basic interface
for constructing a well-defined net of subdomains.
We assume that we can split our domain into small chunks which are represented by the associated
type SubDomain::VoxelIndex
.
Each subdomain consists of multiple such indices and contains knowledge about neighboring indices
even though they might live in different subdomains.
Thus it is not trivial to build a domain which satisfies this condition.
The chili backend wraps the SubDomain
type and also stores additional
information needed for storing intermediate information and numerical solving of the system.
Implementation
It is not recommended to start implementing a completely new domain from the ground up.
Instead, users are encouraged to rely on existing functionality first as explained in the
building-blocks guide.
This guide also explains how to adapt existing domains to new mechanical representations of cells.
To view an example of an implementation, we refer to the
CartesianCuboid
struct.