7 #include "GmshConfig.h"
15 #if !defined(HAVE_MESH)
49 SVector3 h(p3.
x() - 0.5 * (p2.
x() + p1.
x()), p3.
y() - 0.5 * (p2.
y() + p1.
y()),
53 if(
dot(n, h) > 0)
return n;
61 auto it1 =
_fans.find(v1);
62 auto it2 =
_fans.find(v2);
74 if(aaa(it1->second._e1, e))
80 if(aaa(it2->second._e1, e))
87 if(aaa(it1->second._e1, e))
91 if(aaa(it2->second._e1, e))
98 if(N1 == 1 || N2 == 2) {
108 if(N1 == 2 || N2 == 1) {
124 else if(nbSides == 2) {
125 int i1 = 0, i2 = 1, j1 = 0, j2 = 1;
126 if(it1 !=
_fans.end()) {
127 i1 = aaa(it1->second._e1, e) ? 0 : N1 - 1;
128 i2 = !aaa(it1->second._e1, e) ? 0 : N1 - 1;
130 if(it2 !=
_fans.end()) {
131 j1 = aaa(it2->second._e1, e) ? 0 : N2 - 1;
132 j2 = !aaa(it2->second._e1, e) ? 0 : N2 - 1;
153 Msg::Error(
"Not yet Done in BoundaryLayerData nbSides = %d, ", nbSides);
161 std::vector<SVector3> &_dirs,
bool fan,
164 std::vector<SVector3> N1, N2;
165 for(
auto itm = _columns->
_normals.lower_bound(e1);
166 itm != _columns->
_normals.upper_bound(e1); ++itm)
167 N1.push_back(itm->second);
168 for(
auto itm = _columns->
_normals.lower_bound(e2);
169 itm != _columns->
_normals.upper_bound(e2); ++itm)
170 N2.push_back(itm->second);
171 if(N1.size() == N2.size()) {
172 for(std::size_t SIDE = 0; SIDE < N1.size(); SIDE++) {
174 SVector3 x = N1[SIDE] * 1.01 + N2[SIDE];
178 double d = fabs(
dot(N1[SIDE], N2[SIDE]));
180 double ct2 = cos(acos(d) / 2);
182 double fact = 1. / ct2;
189 double alpha1 = atan2(N1[SIDE].y(), N1[SIDE].x());
190 double alpha2 = atan2(N2[SIDE].y(), N2[SIDE].x());
191 double AMAX = std::max(alpha1, alpha2);
192 double AMIN = std::min(alpha1, alpha2);
194 if(alpha1 > alpha2) {
202 if(AMAX - AMIN >= M_PI) {
204 AMAX = AMIN + 2 * M_PI;
210 double frac = fabs(AMAX - AMIN) / M_PI;
214 int fanSize = fan ? n : 0;
215 _columns->
addFan(_myVert, ee[0], ee[1],
true);
216 for(
int i = -1; i <= fanSize; i++) {
217 double t = (double)(i + 1) / (fanSize + 1);
218 double alpha = t * AMAX + (1. - t) * AMIN;
219 SVector3 x(cos(alpha), sin(alpha), 0);
236 std::vector<SVector3> &_dirs)
238 std::vector<SVector3> N1, N2, N3;
239 for(
auto itm = _columns->
_normals.lower_bound(e1);
240 itm != _columns->
_normals.upper_bound(e1); ++itm)
241 N1.push_back(itm->second);
242 for(
auto itm = _columns->
_normals.lower_bound(e2);
243 itm != _columns->
_normals.upper_bound(e2); ++itm)
244 N2.push_back(itm->second);
245 for(
auto itm = _columns->
_normals.lower_bound(e3);
246 itm != _columns->
_normals.upper_bound(e3); ++itm)
247 N3.push_back(itm->second);
250 if(N1.size() == 2) {}
251 else if(N2.size() == 2) {
252 std::vector<SVector3> temp = N1;
258 else if(N3.size() == 2) {
259 std::vector<SVector3> temp = N1;
266 Msg::Error(
"Impossible boundary layer configuration");
268 if(
dot(N1[0], N2[0]) >
dot(N1[0], N3[0])) {
269 x1 = N1[0] * 1.01 + N2[0];
270 x2 = N1[1] * 1.01 + N3[0];
273 x1 = N1[1] * 1.01 + N2[0];
274 x2 = N1[0] * 1.01 + N3[0];
299 std::set<MVertex *> &_vertices,
300 std::set<MEdge, MEdgeLessThan> &allEdges,
301 std::multimap<MVertex *, MVertex *> &tangents)
305 std::vector<GEdge *>
const &embedded_edges = gf->
embeddedEdges();
306 edges.insert(
edges.begin(), embedded_edges.begin(), embedded_edges.end());
309 auto ite =
edges.begin();
310 while(ite !=
edges.end()) {
312 if(isEdgeOfFaceBL(gf, *ite, blf)) {
313 for(std::size_t i = 0; i < (*ite)->lines.size(); i++) {
314 MVertex *v1 = (*ite)->lines[i]->getVertex(0);
315 MVertex *v2 = (*ite)->lines[i]->getVertex(1);
316 allEdges.insert(
MEdge(v1, v2));
319 _vertices.insert(v1);
320 _vertices.insert(v2);
324 MVertex *v1 = (*ite)->lines[0]->getVertex(0);
325 MVertex *v2 = (*ite)->lines[0]->getVertex(1);
326 MVertex *v3 = (*ite)->lines[(*ite)->lines.size() - 1]->getVertex(1);
327 MVertex *v4 = (*ite)->lines[(*ite)->lines.size() - 1]->getVertex(0);
328 tangents.insert(std::make_pair(v1, v2));
329 tangents.insert(std::make_pair(v3, v4));
337 std::set<MEdge, MEdgeLessThan> &allEdges)
341 for(std::size_t i = 0; i < gf->
triangles.size(); i++) {
350 if(allEdges.find(me01) != allEdges.end()) {
351 SVector3 v01 = interiorNormal(p0, p1, p2);
352 _columns->
_normals.insert(std::make_pair(me01, v01));
356 if(allEdges.find(me02) != allEdges.end()) {
357 SVector3 v02 = interiorNormal(p0, p2, p1);
358 _columns->
_normals.insert(std::make_pair(me02, v02));
362 if(allEdges.find(me21) != allEdges.end()) {
363 SVector3 v21 = interiorNormal(p2, p1, p0);
364 _columns->
_normals.insert(std::make_pair(me21, v21));
369 static void addColumnAtTheEndOfTheBL(
GEdge *ge,
GVertex *gv,
374 std::vector<MVertex *> invert;
382 SVector3 t(v1->
x() - v0->
x(), v1->
y() - v0->
y(), v1->
z() - v0->
z());
387 _columns->
addColumn(t * -1.0, v1, invert);
399 double t_begin = bounds.
low();
400 double t_end = bounds.
high();
406 double x = (t - t_begin) / (t_end - t_begin);
407 double hWallLin = hWall_beg + x * (hWall_end - hWall_beg);
408 double hWall_mid = std::min(hWall_beg, hWall_end);
409 double hWallQuad = hWall_beg * (1 - x) * (1 - x) +
410 hWall_mid * 2 * x * (1 - x) + hWall_end * x * x;
412 hWall = 0 * hWallLin + 1 * hWallQuad;
424 if(nBL == 0)
return false;
427 bool addedAdditionalPoints =
false;
428 for(
int i = 0; i < nBL; ++i) {
431 if(bl_field ==
nullptr)
continue;
436 std::set<MVertex *> _vertices;
437 std::set<MEdge, MEdgeLessThan> allEdges;
438 std::multimap<MVertex *, MVertex *> tangents;
440 getEdgesData(gf, blf, _columns, _vertices, allEdges, tangents);
442 if(!_vertices.size())
continue;
444 getNormals(gf, blf, _columns, allEdges);
447 for(
auto it = _vertices.begin(); it != _vertices.end(); ++it) {
448 bool endOfTheBL =
false;
450 std::vector<MVertex *> columnEndOfBL;
452 std::vector<MVertex *> _connections;
453 std::vector<SVector3> _dirs;
458 (*it)->onWhat()->dim() == 0 && blf->
isFanNode((*it)->onWhat()->tag());
459 int fanSize = fan ? blf->
fanSize((*it)->onWhat()->tag()) : 0;
463 _connections.push_back(itm->second);
466 if(_connections.size() == 3) {
467 MEdge e1(*it, _connections[0]);
468 MEdge e2(*it, _connections[1]);
469 MEdge e3(*it, _connections[2]);
470 treat3Connections(gf, *it, e1, e2, e3, _columns, _dirs);
473 else if(_connections.size() == 2) {
474 MEdge e1(*it, _connections[0]);
475 MEdge e2(*it, _connections[1]);
476 treat2Connections(gf, *it, e1, e2, _columns, _dirs, fan, fanSize);
478 else if(_connections.size() == 1) {
479 MEdge e1(*it, _connections[0]);
480 std::vector<SVector3> N1;
481 for(
auto itm = _columns->
_normals.lower_bound(e1);
482 itm != _columns->
_normals.upper_bound(e1); ++itm)
483 N1.push_back(itm->second);
492 std::vector<MVertex *> Ts;
493 for(
auto itm = tangents.lower_bound(*it);
494 itm != tangents.upper_bound(*it); ++itm)
495 Ts.push_back(itm->second);
502 GEdge *ge =
dynamic_cast<GEdge *
>(Ts[0]->onWhat());
504 if(ge && gv) { addColumnAtTheEndOfTheBL(ge, gv, _columns, blf); }
508 "Impossible BL Configuration -- One Edge -- Tscp.size() = %d",
512 else if(N1.size() == 2) {
515 double alpha1 = atan2(N1[0].y(), N1[0].x());
516 double alpha2 = atan2(N1[1].y(), N1[1].x());
517 double alpha3 = atan2(p1.
y() - p0.
y(), p1.
x() - p0.
x());
518 double AMAX = std::max(alpha1, alpha2);
519 double AMIN = std::min(alpha1, alpha2);
522 AMAX = AMIN + 2 * M_PI;
527 AMIN = AMAX - 2 * M_PI;
530 double frac = fabs(AMAX - AMIN) / M_PI;
531 int n = (int)(frac * fanSize + 0.5);
532 int fanSize2 = fan ? n : 0;
533 if(fan) _columns->
addFan(*it, e1, e1,
true);
534 for(
int i = -1; i <= fanSize2; i++) {
535 double t = (double)(i + 1) / (fanSize2 + 1);
536 double alpha = t * AMAX + (1. - t) * AMIN;
537 SVector3 x(cos(alpha), sin(alpha), 0);
547 for(std::size_t DIR = 0; DIR < _dirs.size(); DIR++) {
560 if(endOfTheBL &&
dot(n, dirEndOfBL) > .99) {
567 getLocalInfoAtNode(first, blf, hWall);
568 std::vector<MVertex *> _column;
573 double zlog = log((1 + blf->
beta) / (blf->
beta - 1));
577 const double power = exp(zlog * (1. - eta));
578 const double ratio = (1. - power) / (1. + power);
579 t[i] = 1.0 + blf->
beta * ratio;
580 printf(
"%12.5E ", t[i]);
584 double L = hWall * t[i] / t[0];
585 SPoint2 pnew(par.
x() + L * n.
x(), par.
y() + L * n.
y());
590 _column.push_back(_current);
597 getLocalInfoAtNode(first, blf, hWall);
598 std::vector<MVertex *> _column;
605 SPoint2 pnew(par.
x() + L * n.
x(), par.
y() + L * n.
y());
610 _column.push_back(_current);
611 int ith = _column.size();
613 L += hWall * pow(blf->
ratio, ith);
619 addedAdditionalPoints =
true;
624 sprintf(name,
"points_face_%d.pos", gf->
tag());
625 FILE *
f =
Fopen(name,
"w");
627 fprintf(
f,
"View \"\" {\n");
628 for(
auto it = _vertices.begin(); it != _vertices.end() ; ++it){
632 for(std::size_t j = 0; j < data.
_column.size(); j++){
634 fprintf(
f,
"SP(%g,%g,%g){%d};\n", blv->
x(), blv->
y(), blv->
z(),
644 return addedAdditionalPoints;