12 #include "GmshConfig.h"
41 for (std::size_t i = 1; i < Points.size(); i++)
43 double dh = (Points[i].xp / Points[i].lc - Points[i - 1].xp / Points[i - 1].lc);
44 double dt = Points[i].t - Points[i - 1].t;
45 double dhdt = dh / dt;
46 if (dhdt / Points[i].xp > (alpha - 1.) * 1.01)
48 double hnew = Points[i - 1].xp / Points[i - 1].lc + dt * (alpha - 1) * Points[i].xp;
49 Points[i].lc = Points[i].xp / hnew;
54 for (
int i = Points.size() - 1; i > 0; i--)
56 double dh = (Points[i - 1].xp / Points[i - 1].lc - Points[i].xp / Points[i].lc);
57 double dt = std::abs(Points[i - 1].t - Points[i].t);
58 double dhdt = dh / dt;
59 if (dhdt / Points[i - 1].xp > (alpha - 1.) * 1.01)
61 double hnew = Points[i].xp / Points[i].lc + dt * (alpha - 1) * Points[i].xp;
62 Points[i - 1].lc = Points[i - 1].xp / hnew;
70 if (!(count1 + count2))
75 for (std::size_t i = 1; i < Points.size(); i++)
79 pt2.
p = pt1.
p + (pt2.
t - pt1.
t) * 0.5 * (pt2.
lc + pt1.
lc);
81 return Points[Points.size() - 1].p;
99 double t_begin = bounds.
low();
100 double t_end = bounds.
high();
101 double lc_here = 1.e22;
107 lc_here = std::min(lc_here,
BGM_MeshSize(ge, t, 0, p.
x(), p.
y(), p.
z()));
109 return norm(der) / lc_here;
121 double t_begin = bounds.
low();
122 double t_end = bounds.
high();
135 if (bl_field ==
nullptr)
146 return std::sqrt(
dot(der, lc_here, der));
157 static double dfbeta(
double t,
double beta)
159 double ratio = (1 + beta) / (beta - 1);
160 double zlog = log(ratio);
161 return 2 * beta / ((1 + beta - t) * (-1 + beta + t) * zlog);
171 Msg::Error(
"Zero-length curve %d in transfinite mesh", ge->
tag());
176 double d =
norm(der);
179 int atype = std::abs(type);
186 double t_begin = bounds.
low();
187 double t_end = bounds.
high();
188 double t = (t_ - t_begin) / (t_end - t_begin);
192 if (coef <= 0.0 || coef == 1.0 || (atype == 3 && coef < 1.))
195 val = d * coef / ge->
length();
204 double r = (
gmsh_sign(type) >= 0) ? coef : 1. / coef;
205 double a =
length * (r - 1.) / (std::pow(r, nbpt - 1.) - 1.);
206 int i = (int)(std::log(t *
length / a * (r - 1.) + 1.) / std::log(r));
207 val = d / (a * std::pow(r, (
double)i));
217 a = -4. * std::sqrt(coef - 1.) * std::atan2(1.0, std::sqrt(coef - 1.)) / ((double)nbpt *
length);
221 a = 2. * std::sqrt(1. - coef) *
222 std::log(std::abs((1. + 1. / std::sqrt(1. - coef)) / (1. - 1. / std::sqrt(1. - coef)))) /
226 val = d / (-a * std::pow(t *
length - (
length)*0.5, 2) + b);
233 val =
dfbeta(1. - t, coef);
265 return 0.5 * (P1->
lc + P2->
lc) * (P2->
t - P1->
t);
268 template <
typename function>
270 double Prec,
int *depth)
276 P.
t = 0.5 * (from->
t + to->
t);
282 double const err = std::abs(val1 - val2 - val3);
284 if (((err < Prec) && (*depth > 7)) || (*depth > 25))
292 Points.push_back(*to);
303 template <
typename function>
304 static double Integration(
GEdge *ge,
double t1,
double t2,
function f, std::vector<IntPoint> &Points,
double Prec)
311 from.
lc =
f(ge, from.
t);
313 Points.push_back(from);
320 return Points.back().p;
325 double ps[4] = {vsource->
x(), vsource->
y(), vsource->
z(), 1.};
326 double res[4] = {0., 0., 0., 0.};
328 for (
int i = 0; i < 4; i++)
329 for (
int j = 0; j < 4; j++)
330 res[i] += tfo[idx++] * ps[j];
332 return SPoint3(res[0], res[1], res[2]);
339 Msg::Error(
"Cannot copy mesh on curves without begin/end points");
344 double u_min = u_bounds.
low();
345 double u_max = u_bounds.
high();
348 double to_u_min = to_u_bounds.
low();
370 newu = (
direction > 0) ? (u - u_min + to_u_min) : (u_max - u + to_u_min);
371 gp = to->
point(newu);
379 gp = to->
point(newu);
386 for (std::size_t i = 0; i < to->
mesh_vertices.size() + 1; i++)
398 Msg::Error(
"Cannot fill corresponding nodes on curves without begin/end points");
413 Msg::Error(
"Incompatible meshes to fill node correspondance");
454 if (((N + 1) / 2 - 1) % 2 != 0)
468 bool forceOdd =
false;
482 std::vector<std::pair<double, MVertex *>> lengths;
488 Msg::Error(
"Node not classified on curve in 1D mesh filtering");
507 double lc =
F_LcB()(ge, t);
511 lengths.push_back(std::make_pair(lc / d, v));
516 std::sort(lengths.begin(), lengths.end());
517 int last = lengths.size();
520 while (last % 2 != 0)
534 bool filteringObservesMinimumN = (((int)ge->
mesh_vertices.size() - last) >= nMinimumPoints);
535 if (filteringObservesMinimumN)
537 for (
int i = 0; i < last; i++)
545 delete lengths[i].second;
556 const double hWall = blf->
hWall(gv->
tag());
563 double zlog = log((1 + blf->
beta) / (blf->
beta - 1));
567 const double power = exp(zlog * (1. - eta));
568 const double ratio = (1. - power) / (1. + power);
569 t[i] = 1.0 + blf->
beta * ratio;
573 double L = hWall * t[i] / t[0];
574 SPoint3 p(gv->
x() + dir.
x() * L, gv->
y() + dir.
y() * L, 0.0);
582 if (L > blf->
thickness || L > LEdge * .4)
587 SPoint3 p(gv->
x() + dir.
x() * L, gv->
y() + dir.
y() * L, 0.0);
590 L += hWall * std::pow(blf->
ratio, ith);
596 std::vector<MVertex *> &_addEnd)
613 for (
int i = 0; i < n; ++i)
616 if (bl_field ==
nullptr)
631 for (
int i = 0; i < n; ++i)
634 if (bl_field ==
nullptr)
643 Msg::Error(
"Boundary layer end point %d should lie on a straight line", gvb->
tag());
646 if (_addBegin.size())
648 Msg::Error(
"Different boundary layers cannot touch each other");
652 if (!_addBegin.empty())
653 _addBegin[_addBegin.size() - 1]->getParameter(0, t_begin);
659 Msg::Error(
"Boundary layer end point %d should lie on a straight line", gve->
tag());
664 Msg::Error(
"Different boundary layers cannot touch each other");
668 if (!_addEnd.empty())
669 _addEnd[_addEnd.size() - 1]->getParameter(0, t_end);
744 for (std::size_t i = 0; i < Points.size(); i++)
753 N = std::max(filterMinimumN, (
int)(a + 1.99));
760 std::vector<GFace *>
const &
faces = ge->
faces();
770 for (
auto it =
faces.begin(); it !=
faces.end(); it++)
772 if ((*it)->meshAttributes.recombine)
792 std::vector<GFace *>
f = ge->
faces();
794 for (
size_t i = 0; i <
f.size(); i++)
854 double t_begin = bounds.
low();
855 double t_end = bounds.
high();
858 std::vector<MVertex *> _addBegin, _addEnd;
863 std::vector<IntPoint> Points;
882 Msg::Warning(
"Skipping curve with no begin or end point");
887 end_p = beg_p = ge->
point(t_begin);
888 Msg::Debug(
"Meshing periodic closed curve (tag %i, %i points)", ge->
tag(), N);
894 beg_p =
GPoint(v0->
x(), v0->
y(), v0->
z());
895 end_p =
GPoint(v1->
x(), v1->
y(), v1->
z());
902 const double b = a /
static_cast<double>(N - 1);
903 int count = 1, NUMP = 1;
905 mesh_vertices.resize(N - 2);
909 P1 = Points[count - 1];
911 const double d = (double)NUMP * b;
912 if ((std::abs(P2.
p) >= std::abs(d)) && (std::abs(P1.
p) < std::abs(d)))
914 double const dt = P2.
t - P1.
t;
915 double const dlc = P2.
lc - P1.
lc;
916 double const dp = P2.
p - P1.
p;
917 double const t = P1.
t + dt / dp * (d - P1.
p);
919 const double d =
norm(der);
920 double lc = d / (P1.
lc + dlc / dp * (d - P1.
p));
922 mesh_vertices[NUMP - 1] =
new MEdgeVertex(V.
x(), V.
y(), V.
z(), ge, t, 0, lc);
930 mesh_vertices.resize(NUMP - 1);
935 std::vector<MVertex *> vv;
936 vv.insert(vv.end(), _addBegin.begin(), _addBegin.end());
937 vv.insert(vv.end(), mesh_vertices.begin(), mesh_vertices.end());
938 for (std::size_t i = 0; i < _addEnd.size(); i++)
939 vv.push_back(_addEnd[_addEnd.size() - 1 - i]);
945 if (_addBegin.empty() && _addEnd.empty())
948 std::vector<MLine *> &lines = ge->
lines;
950 for (std::size_t i = 0; i <= mesh_vertices.size(); i++)
955 lines.push_back(
new MLine(v0, v1));
983 double t_begin = bounds.
low();
984 double t_end = bounds.
high();
987 std::vector<IntPoint> Points;
989 int filterMinimumN = 1;