Skip to content
Martin Hartl edited this page Dec 1, 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 base type of edges connecting nodes of kind A with nodes of kind B on the same level:

template<typename A, typename B>
struct edge {
    using src_node_kind = A;
    using trg_node_kind = B;
};

The base type of edges connecting nodes of kind A with nodes of kind B on adjacent levels:

template<typename A, typename B>
struct hierarchy {
    using parent_node_kind = A;
    using child_node_kind = B;
};

The constructor for the list of node kinds to be included in a mesh structure:

template<typename ... Nodes>
struct nodes {
    enum { size = sizeof...(Nodes) };
};

The constructor for the list of edge kinds to be included in a mesh structure:

template<typename ... Edges>
struct edges {
    enum { size = sizeof...(Edges) };
};

The constructor for the list of hierarchies to be included in a mesh structure:

template<typename ... Hierarchies>
struct hierarchies {
    enum { size = sizeof...(Hierarchies) };
};

The type used for addressing nodes within meshes:

template<typename Kind, unsigned Level = 0>
struct NodeRef;

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 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>
std::enable_if_t<std::is_same<A,typename EdgeKind::src_node_kind>::value,NodeRef<B,Level>>
getNeighbor(const NodeRef<A,Level>& a) const
Get sources if a is a sink
template<typename EdgeKind, typename A, unsigned Level, typename B = typename EdgeKind::trg_node_kind>
std::enable_if_t<std::is_same<A,typename EdgeKind::src_node_kind>::value,NodeList<B,Level>>
getNeighbors(const NodeRef<A,Level>& a) const
Get source if a is a sink
template<typename EdgeKind, typename A, unsigned Level, typename B = typename EdgeKind::src_node_kind>
std::enable_if_t<std::is_same<A,typename EdgeKind::trg_node_kind>::value,NodeRef<B,Level>>
getNeighbor(const NodeRef<A,Level>& a) const
Get sinks if a is a source
template<typename EdgeKind, typename A, unsigned Level, typename B = typename EdgeKind::src_node_kind>
std::enable_if_t<std::is_same<A,typename EdgeKind::trg_node_kind>::value,NodeList<B,Level>>
getNeighbors(const NodeRef<A,Level>& a) const
Get sink if a is a source
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 Kind and level Level
template<typename Kind, unsigned Level = 0, typename Body>
detail::scan_reference pforAll(const Body& body)
Call body for each node of kind Kind and level 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 Kind on level 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 Kind on level 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 Kind on level 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 with kind Kind at level Level
template<typename Kind,unsigned Level = 0>
NodeRange<Kind,Level> create(unsigned num)
Create num new node with kind Kind at level 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