-
Notifications
You must be signed in to change notification settings - Fork 4
/
mesh.cpp
130 lines (115 loc) · 5.64 KB
/
mesh.cpp
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
121
122
123
124
125
126
127
128
129
130
#include "mesh.h"
using namespace Mesh;
void mesh::infos(void) const
{
std::cout << "mesh:\n";
std::cout << " nodes: " << getNbNodes() << '\n';
std::cout << " faces: " << fac.size() << '\n';
std::cout << " tetraedrons: " << tet.size() << '\n';
std::cout << " total volume: " << vol << '\n';
}
void mesh::updateNodes(Eigen::Ref<Eigen::VectorXd> X, const double dt)
{
const unsigned int NOD = node.size();
for (unsigned int i = 0; i < NOD; i++)
{ node[i].make_evol(X(i)*gamma0, X(NOD + i)*gamma0, dt); }
}
double mesh::avg(std::function<double(Nodes::Node, Nodes::index)> getter /**< [in] */,
Nodes::index d /**< [in] */) const
{
double sum = std::transform_reduce(EXEC_POL, tet.begin(), tet.end(), 0.0, std::plus{},
[getter, &d](Tetra::Tet const &te)
{
Eigen::Matrix<double,Tetra::NPI,1> val;
te.interpolation(getter, d, val);
return te.weight.dot(val);
});
return sum / vol;
}
double mesh::doOnNodes(const double init_val, const Nodes::index coord,
std::function<bool(double, double)> whatToDo) const
{
double result(init_val);
std::for_each(node.begin(), node.end(),
[&result, coord, whatToDo](Nodes::Node const &n)
{
double val = n.p(coord);
if (whatToDo(val, result)) result = val;
});
return result;
}
void mesh::indexReorder(std::vector<Tetra::prm> const &prmTetra)
{
std::set<Facette::Fac> sf; // implicit use of operator< redefined in class Fac
std::for_each(tet.begin(), tet.end(), [this,&sf](Tetra::Tet const &te)
{
const int ia = te.ind[0];
const int ib = te.ind[1];
const int ic = te.ind[2];
const int id = te.ind[3];
sf.insert(Facette::Fac(node, 0, te.idxPrm, {ia, ic, ib} ));
sf.insert(Facette::Fac(node, 0, te.idxPrm, {ib, ic, id} ));
sf.insert(Facette::Fac(node, 0, te.idxPrm, {ia, id, ic} ));
sf.insert(Facette::Fac(node, 0, te.idxPrm, {ia, ib, id} ));
}); // end for_each
std::for_each(fac.begin(), fac.end(), [this, &prmTetra, &sf](Facette::Fac &fa)
{
int i0 = fa.ind[0], i1 = fa.ind[1], i2 = fa.ind[2];
std::set<Facette::Fac>::iterator it = sf.end();
for (int perm = 0; perm < 2; perm++)
{
for (int nrot = 0; nrot < 3; nrot++)
{
Facette::Fac fc(node, 0, 0, {0, 0, 0} );
fc.ind[(0 + nrot) % 3] = i0;
fc.ind[(1 + nrot) % 3] = i1;
fc.ind[(2 + nrot) % 3] = i2;
it = sf.find(fc);
if (it != sf.end()) break;
}
if (it != sf.end())
{ // found
Eigen::Vector3d p0p1 = node[it->ind[1]].p - node[it->ind[0]].p;
Eigen::Vector3d p0p2 = node[it->ind[2]].p - node[it->ind[0]].p;
// fa.Ms will have the magnitude of first arg of copysign, with second arg sign
fa.dMs = std::copysign( prmTetra[it->idxPrm].J/mu0,
p0p1.dot(p0p2.cross(fa.calc_norm())) ); // carefull, calc_norm computes the normal to the face before idx swap
}
std::swap(i1, i2); // it seems from ref archive we do not want to swap
// inner fac indices but local i1 and i2
fa.n = fa.calc_norm(); // update normal vector
} // end perm
}); // end for_each
}
void mesh::sortNodes(Nodes::index long_axis)
{
// Sort the nodes along this axis, indirectly through an array of indices.
std::vector<int> permutation(node.size());
std::iota(permutation.begin(), permutation.end(), 0);
std::sort(permutation.begin(), permutation.end(),
[this, long_axis](int a, int b)
{ return node[a].p(long_axis) < node[b].p(long_axis); });
node_index.resize(node.size());
for (size_t i = 0; i < node.size(); i++)
node_index[permutation[i]] = i;
// Actually sort the array of nodes.
std::vector<Nodes::Node> node_copy(node);
for (size_t i = 0; i < node.size(); i++)
node[i] = node_copy[permutation[i]];
// Update the indices stored in the elements.
std::for_each(tet.begin(), tet.end(),
[this](Tetra::Tet &tetrahedron)
{
tetrahedron.ind[0] = node_index[tetrahedron.ind[0]];
tetrahedron.ind[1] = node_index[tetrahedron.ind[1]];
tetrahedron.ind[2] = node_index[tetrahedron.ind[2]];
tetrahedron.ind[3] = node_index[tetrahedron.ind[3]];
});
std::for_each(fac.begin(), fac.end(),
[this](Facette::Fac &facette)
{
facette.ind[0] = node_index[facette.ind[0]];
facette.ind[1] = node_index[facette.ind[1]];
facette.ind[2] = node_index[facette.ind[2]];
});
}