-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathUpward.h
120 lines (101 loc) · 3.12 KB
/
Upward.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// SPDX-FileCopyrightText: 2017 Technical University of Munich
//
// SPDX-License-Identifier: BSD-3-Clause
/**
* @file
* This file is part of PUML
*
* For conditions of distribution and use, please see the copyright
* notice in the file 'COPYING' at the root directory of this package
* and the copyright notice at https://github.com/TUM-I5/PUMGen
*
* @author Sebastian Rettenberger <[email protected]>
*/
#ifndef PUML_UPWARD_H
#define PUML_UPWARD_H
#include <algorithm>
#include <cassert>
#include <cstring>
#include <vector>
#include <iterator>
#include "PUML.h"
#include "Topology.h"
namespace PUML {
class Upward {
public:
/**
* Returns all local cell ids for a face
*
* @param puml The PUML mesh
* @param cell The face for which the cells should be returned
* @param lid The local ids of the cells
*/
template <TopoType Topo>
static void cells(const PUML<Topo>& puml, const typename PUML<Topo>::face_t& face, int* lid) {
memcpy(lid, face.m_upward, 2 * sizeof(int));
}
template <TopoType Topo, bool M = false>
static void faces(const PUML<Topo>& puml,
const typename PUML<Topo>::edge_t& edge,
std::vector<int>& lid) {
merge<M>(lid, edge.m_upward);
}
template <TopoType Topo, bool M = false>
static void cells(const PUML<Topo>& puml,
const typename PUML<Topo>::edge_t& edge,
std::vector<int>& lid) {
std::vector<int> faceIds;
faces(puml, edge, faceIds);
std::vector<int> cellIds;
for (int faceId : faceIds) {
int tmp[2];
cells(puml, puml.faces()[faceId], tmp);
const unsigned int c = (tmp[1] < 0 ? 1 : 2);
std::vector<int> merged;
std::set_union(cellIds.begin(), cellIds.end(), tmp, tmp + c, std::back_inserter(merged));
std::swap(merged, cellIds);
}
if (M) {
merge<true>(lid, cellIds);
} else {
std::swap(lid, cellIds);
}
}
template <TopoType Topo, bool M = false>
static void edges(const PUML<Topo>& puml,
const typename PUML<Topo>::vertex_t& vertex,
std::vector<int>& lid) {
merge<M>(lid, vertex.m_upward);
}
template <TopoType Topo, bool M = false>
static void cells(const PUML<Topo>& puml,
const typename PUML<Topo>::vertex_t& vertex,
std::vector<int>& lid) {
std::vector<int> edgeIds;
edges(puml, vertex, edgeIds);
std::vector<int> cellIds;
for (int edgeId : edgeIds) {
merge<true>(cellIds, puml.edges()[edgeId].m_upward);
}
if (M) {
merge<true>(lid, cellIds);
} else {
std::swap(lid, cellIds);
}
}
private:
template <bool M>
static void merge(std::vector<int>& res, const std::vector<int>& v);
};
template <>
inline void Upward::merge<false>(std::vector<int>& res, const std::vector<int>& v) {
res = v;
}
template <>
inline void Upward::merge<true>(std::vector<int>& res, const std::vector<int>& v) {
std::vector<int> tmp;
std::set_union(v.begin(), v.end(), res.begin(), res.end(), std::back_inserter(tmp));
std::swap(tmp, res);
}
} // namespace PUML
#endif // PUML_UPWARD_H