Skip to content
Martin Hartl edited this page Dec 19, 2017 · 2 revisions

allscale::api::user::data::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 types of Mesh

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 functions of Mesh

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

MeshBuilder

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 types of MeshBuilder

Member type Definition
template<unsigned PartitionDepth>
mesh_type
Mesh<nodes<NodeKinds...>,edges<EdgeKinds...>,hierarchies<Hierarchies...>,Levels,PartitionDepth>

Member functions of MeshBuilder

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

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 functions of MeshProperties

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

Examples

// 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));
});
Clone this wiki locally