Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
PolyhedralMesh.cpp
Go to the documentation of this file.
1#include <PolyhedralMesh.h>
2#include <MeshModule.h>
3namespace model
4{
5 template <int dim>
6 Eigen::Matrix<double, dim, 1> PolyhedralFaceIncidence<dim>::outNormal(size_t regionID) const
7 requires(dim == 3)
8 {
9 const auto owner = face.lock();
10 if (!owner || !owner->parents.count(regionID))
11 {
12 throw std::runtime_error("Face incidence does not belong to this region");
13 }
14 return owner->outNormal(regionID);
15 }
16 template <int dim>
18 requires(dim == 3)
19 {
20 const auto owner = face.lock();
21 if (!owner || !owner->parents.count(regionID))
22 {
23 throw std::runtime_error("Face incidence does not belong to this region");
24 }
25 std::shared_ptr<Polyhedron<dim, 2>> other;
26 for (const auto &entry : edge->parents)
27 {
28 const auto candidate = entry.second.lock();
29 if (candidate && candidate != owner && candidate->parents.count(regionID))
30 {
31 if (other)
32 {
33 throw std::runtime_error("Non-manifold grain edge");
34 }
35 other = candidate;
36 }
37 }
38 if (!other)
39 {
40 throw std::runtime_error("Open grain boundary edge");
41 }
42 return other->perimeter.at(edge->faceIncidences.at(other->key));
43 }
44 template <> void PolyhedralMesh<3>::orientMeshFaces()
45 {
46 for (const auto &entry : factory<2>())
47 {
48 const auto &face = entry.second;
49 Eigen::Vector3d area = Eigen::Vector3d::Zero();
50 const auto origin = face->perimeter.front().source()->position;
51 for (const auto &incidence : face->perimeter)
52 {
53 area += (incidence.source()->position - origin).cross(incidence.sink()->position - origin);
54 }
55 if (area.dot(face->asPlane().unitNormal) < 0)
56 {
57 std::reverse(face->perimeter.begin(), face->perimeter.end());
58 for (auto &incidence : face->perimeter)
59 {
60 incidence.reversed = !incidence.reversed;
61 }
62 }
63 for (size_t k = 0; k < face->perimeter.size(); ++k)
64 {
65 face->perimeter[k].index = k;
66 face->perimeter[k].edge->faceIncidences.at(face->key) = k;
67 }
68 }
69 }
70 template <> void PolyhedralMesh<3>::validate() const
71 {
72 validateLevel<3>();
73 for (const auto &entry : factory<2>())
74 {
75 const auto &face = *entry.second;
76 if (face.simplices().empty())
77 {
78 continue; // Topology-only input has no underlying mesh geometry.
79 }
80 for (const auto &parent : face.parents)
81 {
82 const auto region = parent.second.lock();
83 for (const auto &incidence : face.perimeter)
84 {
85 const auto other = incidence.otherFace(region->key);
86 const auto otherOwner = other.face.lock();
87 if (incidence.sink() != incidence.next().source() || incidence.next().prev().edge != incidence.edge)
88 {
89 throw std::runtime_error("Disconnected polyhedral perimeter");
90 }
91 const bool flipped = face.regionIDs.first != int(region->key);
92 const bool otherFlipped = otherOwner->regionIDs.first != int(region->key);
93 if ((incidence.reversed != flipped) == (other.reversed != otherFlipped))
94 {
95 throw std::runtime_error("Inconsistent oriented grain incidences");
96 }
97 }
98 }
99 }
100 }
101 template struct PolyhedralFaceIncidence<3>;
102 template class PolyhedralMesh<3>;
103} // namespace model
const Polyhedron< dim, dim - 1 > & face(size_t id) const
const PolyhedronFactory< dim, order > & factory() const
const Polyhedron< dim, dim > & region(size_t id) const
std::weak_ptr< Polyhedron< dim, 2 > > face
Definition Polyhedron.h:45
Eigen::Matrix< double, dim, 1 > outNormal(size_t regionID) const
PolyhedralFaceIncidence otherFace(size_t regionID) const
std::shared_ptr< Polyhedron< dim, 1 > > edge
Definition Polyhedron.h:46
int parent
int k
REAL area