-
Notifications
You must be signed in to change notification settings - Fork 5
Mesh
Defined in header "allscale/api/user/data/mesh.h"
The type for representing the topological information of a hierarchical mesh:
template<
typename NodeKinds, // < list of node types in each level
typename EdgeKinds, // < list of edge types connecting nodes within levels
typename Hierarchies = hierarchies<>, // < list of edge types connecting nodes between adjacent levels
unsigned Levels = 1, // < number of levels in the hierarchy
unsigned PartitionDepth = 0 // < number of partitioning level
>
class Mesh;
The Mesh
data structure consists of nodes which are connected by edges. The Mesh
additionally features different levels. Nodes on adjacent levels can be connected using hierarchies. Edges only connect nodes on the same level. Therefore each node and edge is at exactly one level.
edge
is the base type of edges connecting nodes of kind A
with nodes of kind B
on the same level.
All edges in the Mesh
data structure inherit from edge
and connect nodes of type A
(src_node_kind
) with nodes of type B
(trg_node_kind
).
template<typename A, typename B>
struct edge {
using src_node_kind = A;
using trg_node_kind = B;
};
hierarchy
is the base type of edges connecting nodes of kind A
with nodes of kind B
on adjacent levels.
Just like for the edge
base type, the hierarchy
base type connects nodes of types A
and B
but the nodes are connected on adjacent levels.
template<typename A, typename B>
struct hierarchy {
using parent_node_kind = A;
using child_node_kind = B;
};
NodeRef
is the type used for addressing nodes within meshes.
Whenever you create a new node this will be the type to identify the node.
template<typename Kind, unsigned Level = 0>
struct NodeRef;
NodeList
is the type used for iterating over lists of nodes, e.g. a list of adjacent nodes:
template<typename Kind,unsigned Level>
using NodeList = utils::range<const NodeRef<Kind,Level>*>;
Member type | Definition |
---|---|
topology_type |
detail::MeshTopologyData<nodes<NodeKinds...>,edges<EdgeKinds...>,hierarchies<Hierarchies...>,Levels> |
partition_tree_type |
detail::PartitionTree<nodes<NodeKinds...>,edges<EdgeKinds...>,hierarchies<Hierarchies...>,Levels,PartitionDepth> |
template<typename NodeKind,typename ValueType,unsigned Level = 0> mesh_data_type
|
MeshData<NodeKind,ValueType,Level,partition_tree_type> |
builder_type |
MeshBuilder<nodes<NodeKinds...>,edges<EdgeKinds...>,hierarchies<Hierarchies...>,Levels> |
Member function | Description |
---|---|
Mesh(Mesh&&) |
Move constructor |
Mesh& operator=(Mesh&&) |
Move assignment |
const topology_type& getTopologyData() const |
Read access to the topology data |
const partition_tree_type& getPartitionTree() const |
Read access to the partition tree |
template<typename Kind,unsigned Level = 0> std::size_t getNumNodes() const
|
Get number of nodes of type Kind on Level
|
template<typename EdgeKind, typename A, unsigned Level, typename B = typename EdgeKind::trg_node_kind> NodeList<B,Level> getSinks(const NodeRef<A,Level>& a) const
|
Get all sinks with a as source |
template<typename EdgeKind, typename A, unsigned Level, typename B = typename EdgeKind::trg_node_kind> NodeRef<B,Level> getSink(const NodeRef<A,Level>& a) const
|
Get sink of edges with source a if there is only a single edge |
template<typename EdgeKind, typename B, unsigned Level, typename A = typename EdgeKind::src_node_kind> NodeList<A,Level> getSources(const NodeRef<B,Level>& b) const
|
Get all sources with a as sink |
template<typename EdgeKind, typename B, unsigned Level, typename A = typename EdgeKind::src_node_kind> NodeRef<A,Level> getSource(const NodeRef<B,Level>& b) const
|
Get source of edges with sink a if there is only a single edge |
template<typename EdgeKind, typename A, unsigned Level, typename B = typename EdgeKind::trg_node_kind> getNeighbor(const NodeRef<A,Level>& a) const
|
Get neighbor of a
|
template<typename Hierarchy, typename A, unsigned Level, typename B = typename Hierarchy::parent_node_kind> NodeRef<B,Level+1> getParent(const NodeRef<A,Level>& a) const
|
Get parent nodes of a
|
template<typename Hierarchy, typename A, unsigned Level, typename B = typename Hierarchy::child_node_kind> NodeList<B,Level-1> getChildren(const NodeRef<A,Level>& a) const
|
Get child notes of a
|
template<typename Kind, unsigned Level = 0, typename Body> void forAll(const Body& body) const
|
Call body for each node of Kind on Level
|
template<typename Kind, unsigned Level = 0, typename Body> detail::scan_reference pforAll(const Body& body)
|
Call body for each node of Kind on Level in parallel |
template<typename Kind, unsigned Level = 0, typename MapOp, typename ReduceOp, typename InitLocalState, typename ReduceLocalState> typename utils::lambda_traits<ReduceLocalState>::result_type preduce(const MapOp& map, const ReduceOp& reduce, const InitLocalState& init, const ReduceLocalState& exit) const
|
Apply the preduce operator to nodes of Kind on Level
|
template<typename Kind, unsigned Level = 0, typename MapOp, typename ReduceOp, typename InitLocalState> typename utils::lambda_traits<ReduceOp>::result_type preduce(const MapOp& map, const ReduceOp& reduce, const InitLocalState& init) const
|
Apply the preduce operator to nodes of Kind on Level with default ReduceLocalState operator |
template<typename Kind, unsigned Level = 0, typename MapOp, typename ReduceOp> typename utils::lambda_traits<ReduceOp>::result_type preduce(const MapOp& map, const ReduceOp& reduce) const
|
Apply the preduce operator to nodes of Kind on Level with default ReduceLocalState and InitLocalState operator |
template<typename NodeKind, typename T, unsigned Level = 0> MeshData<NodeKind,T,Level,partition_tree_type> createNodeData() const
|
Create node data |
template<typename NodeKind, typename T, unsigned N, unsigned Level = 0> std::array<MeshData<NodeKind,T,Level,partition_tree_type>, N> createNodeDataArray() const
|
Create array of node data |
template<typename ... Properties> MeshProperties<Levels,partition_tree_type,Properties...> createProperties() const
|
Create properties |
The MeshBuilder
is a utility to construct meshes.
template<
typename NodeKinds, // < list of node types in each level
typename EdgeKinds, // < list of edge types connecting nodes within levels
typename Hierarchies = hierarchies<>, // < list of edge types connecting nodes between adjacent levels
unsigned Levels = 1 // < number of levels in the hierarchy
>
class MeshBuilder;
Member type | Definition |
---|---|
template<unsigned PartitionDepth> mesh_type
|
Mesh<nodes<NodeKinds...>,edges<EdgeKinds...>,hierarchies<Hierarchies...>,Levels,PartitionDepth> |
Member function | Description |
---|---|
template<typename Kind,unsigned Level = 0> NodeRef<Kind,Level> create()
|
Create a new node of Kind at Level
|
template<typename Kind,unsigned Level = 0> NodeRange<Kind,Level> create(unsigned num)
|
Create num new node of Kind at Level
|
template<typename EdgeKind, typename NodeKindA, typename NodeKindB, unsigned Level> void link(const NodeRef<NodeKindA,Level>& a, const NodeRef<NodeKindB,Level>& b)
|
Link two nodes on the same level |
template<typename HierarchyKind, typename NodeKindA, typename NodeKindB, unsigned LevelA, unsigned LevelB> void link(const NodeRef<NodeKindA,LevelA>& parent, const NodeRef<NodeKindB,LevelB>& child
|
Link two nodes on adjacent levels in the hierarchies |
template<typename Partitioner, unsigned PartitionDepth = 0> mesh_type<PartitionDepth> build(const Partitioner& partitioner) const &
|
Partition using the partitioner
|
template<unsigned PartitionDepth = 0> mesh_type<PartitionDepth> build() const &
|
Partition using the NaiveMeshPartitioner
|
template<typename Partitioner, unsigned PartitionDepth = 0> mesh_type<PartitionDepth> build(const Partitioner& partitioner) &&
|
Partition using the partitioner
|
template<unsigned PartitionDepth = 0> mesh_type<PartitionDepth> build() const &&
|
Partition using the NaiveMeshPartitioner
|
MeshProperties
is a container for a collection of mesh properties. A mesh property is a value associated to a certain kind of node on each level of a mesh. The MeshProperties
container allows multiple properties to be managed within a single, consistent entity. To create an instance, the factory function createProperties
of the Mesh
structure has to be utilized.
The base type for mesh property kinds:
template<typename NodeKind, typename ValueType>
struct mesh_property {
using node_kind = NodeKind;
using value_type = ValueType;
};
Member function | Description |
---|---|
template<typename Property, unsigned Level = 0> MeshData<typename Property::node_kind,typename Property::value_type,Level,PartitionTree>& get()
|
Read and write access to Property at Level
|
template<typename Property, unsigned Level = 0> const MeshData<typename Property::node_kind,typename Property::value_type,Level,PartitionTree>& get() const
|
Read access to Property at Level
|
template<typename Property, unsigned Level = 0> typename Property::value_type& get(const NodeRef<typename Property::node_kind,Level>& node)
|
Read and write access to Property for node at Level
|
template<typename Property, unsigned Level = 0> const typename Property::value_type& get(const NodeRef<typename Property::node_kind,Level>& node const
|
Read access to property Property for node at Level
|
// define 'object' types
struct Cell {};
// define 'relations'
struct Cell2Cell : public data::edge<Cell,Cell> {};
// and 'hierarchies'
struct Cell2Child : public data::hierarchy<Cell,Cell> {};
// cell properties
struct CellVolume : public data::mesh_property<Cell,double> {};
// -- MeshBuilder --
data::MeshBuilder<
data::nodes<Cell>, // < list of node types in each level
data::edges<Cell2Cell>, // < list of edge types connecting nodes within levels
data::hierarchies<Cell2Child>, // < list of edge types connecting nodes between adjacent levels
2 // < 2 layers in the hierarchy
> mesh_builder;
// create two cells on layer 0
auto c1 = mesh_builder.create<Cell,0>();
auto c2 = mesh_builder.create<Cell,0>();
// create a cell on layer 1
auto c3 = mesh_builder.create<Cell,1>();
// link second layer
mesh_builder.link<Cell2Cell>(c1,c2);
mesh_builder.link<Cell2Cell>(c2,c1);
// link hierarchy
mesh_builder.link<Cell2Child>(c3,c1);
mesh_builder.link<Cell2Child>(c3,c2);
// -- Mesh --
// build mesh
auto mesh = mesh_builder.build();
// check relations per level
assert_eq(1, mesh.getSinks<Cell2Cell>(c1).size());
assert_eq(1, mesh.getSinks<Cell2Cell>(c2).size());
assert_eq(c2, mesh.getSink<Cell2Cell>(c1));
assert_eq(c1, mesh.getSink<Cell2Cell>(c2));
// check reverse look-ups
assert_eq(1, mesh.getSources<Cell2Cell>(c1).size());
assert_eq(1, mesh.getSources<Cell2Cell>(c2).size());
assert_eq(c2, mesh.getSource<Cell2Cell>(c1));
assert_eq(c1, mesh.getSource<Cell2Cell>(c2));
// -- MeshProperties --
auto properties = mesh.createProperties<CellVolume>();
// -- initialize property --
// initialize layer 1
mesh.pforAll<Cell,1>([&](auto c) {
properties.get<CellVolume>(c) = 0.;
});
// initialize layer 0
mesh.pforAll<Cell,0>([&](auto c) {
properties.get<CellVolume>(c) = 2.;
auto p = mesh.getParent<Cell2Child>(c);
properties.get<CellVolume>(p) += 2.;
});
mesh.pforAll<Cell,0>([&](auto c) {
assert_eq(2., properties.get<CellVolume>(c));
});
// set volume = 1 for all children cells of c3
auto children = mesh.getChildren<Cell2Child>(c3);
for(auto& c : children) {
properties.get<CellVolume>(c) = 1.;
}
// check if volume is set correctly
mesh.pforAll<Cell,0>([&](auto c) {
assert_eq(1., properties.get<CellVolume>(c));
});
mesh.pforAll<Cell,1>([&](auto c) {
assert_eq(4., properties.get<CellVolume>(c));
});
Part of the AllScale project - http://www.allscale.eu