18 double &h1,
double &h2)
23 double l1 = 0.5 * (a + b + sqrt((a - b) * (a - b) + 4 *
c *
c));
24 double l2 = 0.5 * (a + b - sqrt((a - b) * (a - b) + 4 *
c *
c));
28 double theta = 0.5 * atan2(2 *
c, a - b);
33 double bestParabola(
double x0,
double y0,
double x1,
double y1,
double &xmid,
34 double &ymid,
int VIEW_TAG);
36 double x1,
double y1,
int VIEW_TAG);
38 static double maxDir(
double &
c,
double &s,
double &h,
const double &C,
39 const double &
S,
const double &H1,
const double &H2)
41 double PV1 =
c * C + s *
S;
42 double PV2 = s * C -
c *
S;
43 double PV3 = -
c * C - s *
S;
44 double PV4 = -s * C +
c *
S;
45 if(PV1 > PV2 && PV1 > PV3 && PV1 > PV4) {
51 else if(PV2 > PV3 && PV2 > PV4) {
77 double v2,
double v3,
double v4,
double v5)
79 double L0 = (1 - xi - eta) * (1 - 2 * xi - 2 * eta);
80 double L1 = xi * (2 * xi - 1);
81 double L2 = eta * (2 * eta - 1);
82 double L3 = 4 * xi * (1 - xi - eta);
83 double L4 = 4 * xi * eta;
84 double L5 = 4 * eta * (1 - xi - eta);
86 return L0 * v0 + L1 * v1 + L2 * v2 + L3 * v3 + L4 * v4 + L5 * v5;
89 static void derivativeP2(
double u,
double v,
double dfdu[6],
double dfdv[6])
98 dfdu[0] = -3 + 4 * v + 4 * u;
101 dfdu[3] = 4 - 4 * v - 8 * u;
105 dfdv[0] = -3 + 4 * u + 4 * v;
107 dfdv[2] = -1 + 4 * v;
110 dfdv[5] = 4 - 4 * u - 8 * v;
114 double *xbc,
double *xca,
double J[6])
116 double *x[6] = {xa, xb, xc, xab, xbc, xca};
117 double nodes[6][2] = {{0, 0}, {1, 0}, {0, 1}, {0.5, 0}, {0.5, 0.5}, {0, 0.5}};
118 for(
int i = 0; i < 6; i++) {
119 double u = nodes[i][0];
120 double v = nodes[i][1];
121 double dfdu[6], dfdv[6];
123 double dxdu = 0, dxdv = 0, dydu = 0, dydv = 0;
124 for(
int j = 0; j < 6; j++) {
125 dxdu += x[j][0] * dfdu[j];
126 dxdv += x[j][0] * dfdv[j];
127 dydu += x[j][1] * dfdu[j];
128 dydv += x[j][1] * dfdv[j];
130 J[i] = -(dxdu * dydv - dydu * dxdv);
135 double *xbc,
double *xca,
double *xis,
double *etas,
136 double detJ[6],
double J[6][4])
138 double *x[6] = {xa, xb, xc, xab, xbc, xca};
139 for(
int i = 0; i < 6; i++) {
142 double dfdu[6], dfdv[6];
144 double dxdu = 0, dxdv = 0, dydu = 0, dydv = 0;
145 for(
int j = 0; j < 6; j++) {
146 dxdu += x[j][0] * dfdu[j];
147 dxdv += x[j][0] * dfdv[j];
148 dydu += x[j][1] * dfdu[j];
149 dydv += x[j][1] * dfdv[j];
155 detJ[i] = -(dxdu * dydv - dydu * dxdv);
160 double *xab,
double *xbc,
double *xca)
164 double bez[6] = {J[0],
167 2 * J[3] - 0.5 * (J[0] + J[1]),
168 2 * J[4] - 0.5 * (J[1] + J[2]),
169 2 * J[5] - 0.5 * (J[0] + J[2])};
171 for(
int i = 0; i < 6; i++) _MIN = bez[i] < _MIN ? bez[i] : _MIN;
179 const double D = M_PI / 2;
180 double U0 = fabs(u - 2 *
D - t);
181 double U1 = fabs(u -
D - t);
182 double U2 = fabs(u - t);
183 double U3 = fabs(u +
D - t);
184 double U4 = fabs(u + 2 *
D - t);
185 if(U0 < U1 && U0 < U2 && U0 < U3 && U0 < U4)
return u - 2 *
D;
186 if(U1 < U2 && U1 < U3 && U1 < U4)
return u -
D;
187 if(U2 < U3 && U2 < U4)
return u;
188 if(U3 < U4)
return u +
D;
193 double *xc,
double *xab,
194 double *xbc,
double *xca,
197 double xis[6] = {0, .2, .4, .6, .8, 1};
198 double etas[6] = {0, 0, 0, 0., 0., 0.};
209 for(uint32_t j = 0; j < 6; j++) {
211 double eta = etas[j];
218 std::vector<double> val(9);
220 gmsh::view::probe(VIEW_TAG, x[j][0], x[j][1], 0.0, val, dist);
221 double dxdu = Js[j][0];
222 double dydu = Js[j][2];
228 THETAM[j] = atan2(
S, C);
230 THETAM[j] =
closest(THETAM[j - 1], atan2(
S, C));
233 THETA[j] = atan2(dydu, dxdu);
235 THETA[j] =
closest(THETA[j - 1], atan2(dydu, dxdu));
237 for(uint32_t j = 1; j < 5; j++) {
238 double dtheta = THETA[j + 1] - THETA[j - 1];
239 double dthetam = THETAM[j + 1] - THETAM[j - 1];
240 double D2 = (dtheta - dthetam) * (dtheta - dthetam);
254 std::vector<double> val(9);
256 gmsh::view::probe(VIEW_TAG, (xa[0] + xb[0] + xc[0]) / 3,
257 (xa[1] + xb[1] + xc[1]) / 3, 0.0, val, dist);
258 double M[3] = {val[0], val[4], val[1]};
265 double det = sqrt(M[0] * M[1] - M[2] * M[2]);
267 double d1[2] = {xb[0] - xa[0], xb[1] - xa[1]};
268 double d2[2] = {xc[0] - xb[0], xc[1] - xb[1]};
269 double d3[2] = {xa[0] - xc[0], xa[1] - xc[1]};
271 double tmp1 = d1[0] * d1[0] + d2[0] * d2[0] + d3[0] * d3[0];
272 double tmp2 = d1[1] * d1[1] + d2[1] * d2[1] + d3[1] * d3[1];
273 double tmp3 = 2 * (d1[0] * d1[1] + d2[0] * d2[1] + d3[0] * d3[1]);
275 double l2 = (tmp1 * M[0] + tmp2 * M[1] + tmp3 * M[2]);
279 return det * area / 3.0 / l2;
283 double *lengthInMetricField,
int VIEW_TAG)
285 *lengthInMetricField = 0.0;
289 static double GL_pt8[8] = {-9.602898564975363e-01, -7.966664774136268e-01,
290 -5.255324099163290e-01, -1.834346424956498e-01,
291 1.834346424956498e-01, 5.255324099163290e-01,
292 7.966664774136268e-01, 9.602898564975363e-01};
294 static double GL_wt8[8] = {1.012285362903768e-01, 2.223810344533745e-01,
295 3.137066458778874e-01, 3.626837833783620e-01,
296 3.626837833783620e-01, 3.137066458778874e-01,
297 2.223810344533745e-01, 1.012285362903768e-01};
301 for(
size_t i = 0; i < n; ++i) {
305 double x[2] = {-0.5 * t * (1 - t) * lagrangianPoints[0][0] +
306 (1 + t) * (1 - t) * lagrangianPoints[1][0] +
307 0.5 * t * (1 + t) * lagrangianPoints[2][0],
308 -0.5 * t * (1 - t) * lagrangianPoints[0][1] +
309 (1 + t) * (1 - t) * lagrangianPoints[1][1] +
310 0.5 * t * (1 + t) * lagrangianPoints[2][1]};
312 double dx = -0.5 * (1 - 2 * t) * lagrangianPoints[0][0] -
313 2 * t * lagrangianPoints[1][0] +
314 0.5 * (1 + 2 * t) * lagrangianPoints[2][0];
315 double dy = -0.5 * (1 - 2 * t) * lagrangianPoints[0][1] -
316 2 * t * lagrangianPoints[1][1] +
317 0.5 * (1 + 2 * t) * lagrangianPoints[2][1];
319 std::vector<double> val(9);
321 gmsh::view::probe(VIEW_TAG, x[0], x[1], 0.0, val, dist);
322 if(val.empty()) { *lengthInMetricField = 1.e22; }
324 double M[3] = {val[0], val[4], val[1]};
325 *lengthInMetricField =
326 *lengthInMetricField +
327 w * sqrt(M[0] * dx * dx + 2 * M[2] * dx * dy + M[1] * dy * dy);
334 double x1,
double y1,
int VIEW_TAG)
336 double lagrangianPoints[3][2] = {{x0, y0}, {xt, yt}, {x1, y1}};
337 double lengthInMetricField;
341 return lengthInMetricField;
350 double y2,
int VIEW_TAG)
355 double goldenSection(
double x0,
double y0,
double &xt,
double &yt,
double x1,
356 double y1,
double astart,
double bstart,
double &gamma1,
361 double fstart,
f, f1, f2;
366 if(Lstart > 2)
return Lstart;
368 double lambda = 1.0 / (0.5 * (sqrt(5) + 1.0));
374 double xi1 = b - lambda * (b - a);
375 double xi2 = a + lambda * (b - a);
378 yt - xi1 *
direction[1], x1, y1, VIEW_TAG);
380 yt - xi2 *
direction[1], x1, y1, VIEW_TAG);
382 while(fabs(xi2 - xi1) > tol) {
387 xi1 = b - lambda * (b - a);
389 yt - xi1 *
direction[1], x1, y1, VIEW_TAG);
395 xi2 = a + lambda * (b - a);
397 yt - xi2 *
direction[1], x1, y1, VIEW_TAG);
422 double *lengthGeodesicsTwoPoints)
424 double x0 = xstart[0];
426 double y0 = xstart[1];
443 xmid[0] = (x0 + x1) / 2;
444 xmid[1] = (y0 + y1) / 2;
446 double direction[2] = {y1 - y0, x0 - x1};
456 xmid[0] = xmid[0] - gamma1 *
direction[0];
457 xmid[1] = xmid[1] - gamma1 *
direction[1];
459 *lengthGeodesicsTwoPoints =
471 double lengthGeodesicsTwoPoints;
474 return lengthGeodesicsTwoPoints;
478 static double closestPoint(
int VIEW_TAG, std::vector<SPoint2> &_points,
482 for(
size_t i = 0; i < _points.size(); i++) {
495 double adimensionalLength,
SPoint2 &n)
497 std::vector<double> val;
499 gmsh::view::probe(VIEW_TAG, p.
x(), p.
y(), 0.0, val, dist);
500 if(val.empty())
return false;
503 double A[4] = {C, -C,
S, -
S};
504 double B[4] = {
S, -
S, -C, C};
505 double H[4] = {h1, h1, h2, h2};
511 std::vector<SPoint2> path;
513 for(
size_t iter = 0; iter < N; iter++) {
514 SPoint2 pp(PP.
x() + dx * h * adimensionalLength / N,
515 PP.
y() + dy * h * adimensionalLength / N);
516 double Cpp, Spp, h1pp, h2pp;
518 gmsh::view::probe(VIEW_TAG, pp.
x(), pp.
y(), 0.0, val, dist);
519 if(val.empty()) { iter = N + 1; }
522 maxDir(dx, dy, h, Cpp, Spp, h1pp, h2pp);
527 if(path.size() == N) {
537 if(!he->
f)
return -1;
540 if(he->
f->
data < 0)
return -1;
557 if(std::min(q312, q320) > std::min(q012, q103))
return 1;
563 std::map<PolyMesh::HalfEdge *, SPoint2> *midPoints =
nullptr)
574 ab = (*midPoints)[hea];
575 bc = (*midPoints)[heb];
576 ca = (*midPoints)[hec];
584 std::map<PolyMesh::HalfEdge *, SPoint2> *midPoints =
nullptr)
596 ab = (*midPoints)[hea];
597 bc = (*midPoints)[heb];
598 ca = (*midPoints)[hec];
602 std::vector<double> val0(9), val1(9), val2(9), val3(9), val4(9), val5(9);
610 gmsh::view::probe(VIEW_TAG, ab.
x(), ab.
y(), 0.0, val3, dist);
611 gmsh::view::probe(VIEW_TAG, bc.
x(), bc.
y(), 0.0, val4, dist);
612 gmsh::view::probe(VIEW_TAG, ca.
x(), ca.
y(), 0.0, val5, dist);
615 "ST2(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,0,%g,%g,0,%g,%g,0){%g,%g,%g,%"
620 ab.
x(), ab.
y(), bc.
x(), bc.
y(), ca.
x(), ca.
y(), val0[8], val1[8],
621 val2[8], val3[8], val4[8], val5[8]);
625 if(validity < 0)
return validity;
639 std::map<PolyMesh::HalfEdge *, SPoint2> &midPoints,
int VIEW_TAG,
640 bool straight =
false)
647 straight ?
SPoint2(0.5 * (x0 + x1), 0.5 * (y0 + y1)) : midPoints[he];
652 std::map<PolyMesh::HalfEdge *, SPoint2> &midPoints,
655 double XI_MIN = -ximax;
656 double XI_MAX = ximax;
663 double xmid = (x0 + x1) / 2;
664 double ymid = (y0 + y1) / 2;
666 double direction[2] = {y1 - y0, x0 - x1};
673 double QMIN = std::min(Q1, Q2);
676 for(
int i = 0; i < N; i++) {
677 double t = (double)i / (N - 1);
678 double xi = XI_MIN + (XI_MAX - XI_MIN) * t;
680 midPoints[he] = midPoints[he->
opposite] = X;
683 if(std::min(Q1, Q2) > QMIN) {
684 QMIN = std::min(Q1, Q2);
688 midPoints[he] = midPoints[he->
opposite] = CUR;
696 std::map<PolyMesh::HalfEdge *, SPoint2> &midPoints,
697 double er(
double *,
double *,
double *,
double *,
701 double XI_MIN = -ximax;
702 double XI_MAX = ximax;
709 double xmid = (x0 + x1) / 2;
710 double ymid = (y0 + y1) / 2;
712 double direction[2] = {y1 - y0, x0 - x1};
719 midPoints[he], midPoints[he->next], midPoints[he->next->next]);
721 er(he->opposite->v->position, he->opposite->next->v->position,
722 he->opposite->next->next->v->position, midPoints[he->opposite],
723 midPoints[he->opposite->next], midPoints[he->opposite->next->next]);
726 if(V1 <= 0) Q1 = 1.e22;
727 if(V2 <= 0) Q2 = 1.e22;
729 double QSUM = Q1 + Q2;
732 for(
int i = 0; i < N; i++) {
733 double t = (double)i / (N - 1);
734 double xi = XI_MIN + (XI_MAX - XI_MIN) * t;
736 midPoints[he] = midPoints[he->opposite] = X;
739 er(he->v->position, he->next->v->position, he->next->next->v->position,
740 midPoints[he], midPoints[he->next], midPoints[he->next->next]);
742 er(he->opposite->v->position, he->opposite->next->v->position,
743 he->opposite->next->next->v->position, midPoints[he->opposite],
744 midPoints[he->opposite->next], midPoints[he->opposite->next->next]);
749 if(V1 <= 0) Q1 = 1.e22;
750 if(V2 <= 0) Q2 = 1.e22;
757 midPoints[he] = midPoints[he->opposite] = CUR;
764 double bestParabola(
double x0,
double y0,
double x1,
double y1,
double &xmid,
765 double &ymid,
int VIEW_TAG)
767 double XI_MIN = -0.2;
773 xmid = (x0 + x1) / 2;
774 ymid = (y0 + y1) / 2;
777 double direction[2] = {y1 - y0, x0 - x1};
781 double QMAX = -1.e22;
784 for(
int i = 0; i < N; i++) {
785 double t = (double)i / (N - 1);
786 double xi = XI_MIN + (XI_MAX - XI_MIN) * t;
804 const char *modelForMetric,
const char *modelForMesh,
int VIEW_TAG,
805 int faceTag, std::vector<double> &pts,
806 double er(
double *,
double *,
double *,
double *,
double *,
double *))
810 FILE *
f = fopen(
"PTS.pos",
"w");
811 fprintf(
f,
"View \" \"{\n");
813 gmsh::model::setCurrent(modelForMesh);
815 if(result)
return result;
818 std::stack<SPoint2> _q;
819 std::vector<SPoint2> _points;
822 SPoint2 pp(v->position.x(), v->position.y());
824 _points.push_back(pp);
828 gmsh::model::setCurrent(modelForMetric);
830 std::vector<double> additional;
838 for(
int DIR = 0; DIR < 4; DIR++) {
843 double dist =
closestPoint(VIEW_TAG, _points, pp, close);
845 additional.push_back(pp.
x());
846 additional.push_back(pp.
y());
848 fprintf(
f,
"SL(%22.15E,%22.15E,0,%22.15E,%22.15E,0){%g,%g};\n",
849 pp.
x(), pp.
y(), p.
x(), p.
y(), dist, dist);
850 _points.push_back(pp);
851 fprintf(
f,
"SP(%22.15E,%22.15E,0){%lu};\n", pp.
x(), pp.
y(),
860 if(_points.size() % 100 == 0)
861 printf(
"q size %lu p size %lu\n", _q.size(), _points.size());
867 gmsh::model::setCurrent(modelForMesh);
870 gmsh::model::setCurrent(modelForMetric);
874 for(
auto he : newMesh->
hedges) {
881 if(count == 0)
break;
885 std::map<PolyMesh::HalfEdge *, SPoint2> midPoints;
886 std::map<PolyMesh::HalfEdge *, double> LS;
887 for(
auto he : newMesh->
hedges) {
890 SPoint2 p_m = (p_0 + p_1) * .5;
895 double ximax = 0.3 / 5;
897 for(
auto he : newMesh->
hedges) {
900 SPoint2 p_m = (p_0 + p_1) * .5;
906 double L =
LENGTH(he, midPoints, VIEW_TAG);
917 for(
auto he : newMesh->
hedges) {
921 double LA =
LENGTH(he, midPoints, VIEW_TAG);
930 double LB =
LENGTH(he, midPoints, VIEW_TAG);
931 bool invalid =
false;
933 if(er && B > 1.e10) invalid =
true;
934 if(er && B > A) better =
true;
935 if(!er && B < 0) invalid =
true;
936 if(!er && B < A) better =
true;
939 midPoints[he] = midPoints[he->
opposite] = old;
950 printf(
"%12.5E %12.5E %12.5E %12.5E %12.5E \n", A, LA, B, LB,
951 LENGTH(he, midPoints, VIEW_TAG));
955 printf(
"count %3d\n", count);
956 if(count == 0)
break;
960 FILE *FFF = fopen(
"meshMetric.pos",
"w");
961 fprintf(FFF,
"View \" metric \"{\n");
963 for(
auto he : newMesh->
hedges) {
970 fprintf(FFF,
"};\n");
976 sprintf(name,
"polyMeshCurved%d.pos", 200);
977 FILE *
f = fopen(name,
"w");
978 sprintf(name,
"polyMeshCurved%d.pos", 300);
979 FILE *f2 = fopen(name,
"w");
980 fprintf(
f,
"View \" %s \"{\n", name);
981 fprintf(f2,
"View \" %s \"{\n", name);
982 for(
auto he : newMesh->
hedges) {
985 if(he->
f->
data >= 0) {
987 double Lhe =
LENGTH(he, midPoints, VIEW_TAG);
988 double Lhe2 =
LENGTH(he, midPoints, VIEW_TAG,
true);
989 fprintf(
f,
"SL2(%g,%g,0,%g,%g,0,%g,%g,0){%g,%g,%g};\n",
992 p.
y(), Lhe, Lhe, Lhe);
993 fprintf(f2,
"SL(%g,%g,0,%g,%g,0){%g,%g};\n", he->
v->
position.
x(),
1000 fprintf(f2,
"};\n");
1004 gmsh::model::setCurrent(modelForMesh);