12 #include "GmshConfig.h"
37 typedef std::map<std::pair<MVertex *, MVertex *>, std::vector<MVertex *> >
51 return ge->
length(u[i], u[i + 1], 10);
55 double *weight =
nullptr)
58 for(
int i = 0; i < N - 1; i++) L[i] =
mylength(ge, i, u);
60 for(
int i = 0; i < N - 2; i++)
61 r(i) = L[i + 1] / weight[i + 1] - L[i] / weight[i];
63 for(
int i = 0; i < N - 2; i++) r(i) = L[i + 1] - L[i];
67 double *u,
double underRelax)
69 const double PRECISION = 1.e-6;
70 const int MAX_ITER = 50;
71 const double eps = (uN - u0) * 1.e-5;
79 double du = (uN - u0) / (N - 1);
80 for(
int i = 1; i < N; i++) { u[i] = u[i - 1] + du; }
93 while(iter < MAX_ITER) {
97 for(
int i = 0; i < M; i++) {
100 for(
int j = 0; j < M; j++) { J(i, j) = (Rp(j) - R(j)) / eps; }
105 DU(0) = R(0) / J(0, 0);
109 for(
int i = 0; i < M; i++) { u[i + 1] -= underRelax * DU(i); }
112 if(u[N - 2] > uN)
break;
114 double newt_norm = DU.
norm();
115 if(newt_norm < PRECISION) {
return true; }
121 double *u,
double underRelax)
123 static const double GLLQL[7] = {
124 -1.000000000000000, -0.830223896278567, -0.468848793470714, 0,
125 0.468848793470714, 0.830223896278567, 1.000000000000000};
127 for(
int i = 0; i < 6; ++i) { weight[i] = GLLQL[i + 1] - GLLQL[i]; }
129 const double PRECISION = 1.e-6;
130 const int MAX_ITER = 50;
131 const double eps = (uN - u0) * 1.e-5;
140 double uMiddle = .5 * (u0 + uN);
141 double du = .5 * (uN - u0);
142 for(
int i = 1; i < N - 1; i++) { u[i] = uMiddle + GLLQL[i] * du; }
153 while(iter < MAX_ITER) {
157 for(
int i = 0; i < M; i++) {
160 for(
int j = 0; j < M; j++) { J(i, j) = (Rp(j) - R(j)) / eps; }
165 DU(0) = R(0) / J(0, 0);
169 for(
int i = 0; i < M; i++) { u[i + 1] -= underRelax * DU(i); }
172 if(u[N - 2] > uN)
break;
174 double newt_norm = DU.
norm();
175 if(newt_norm < PRECISION) {
return true; }
181 double v0,
double vN,
SPoint3 &p0,
182 SPoint3 &pN,
int N,
bool geodesic,
183 double *u,
double *v)
185 const int NI = N - 1;
190 const double fact = 1. / (double)NI;
191 for(
int i = 1; i < NI; i++) {
192 const double t = i * fact;
193 u[i] = u0 + (uN - u0) * t;
194 v[i] = v0 + (vN - v0) * t;
198 SPoint3 pc(t * pN + (1. - t) * p0);
199 double guess[2] = {u[i], v[i]};
214 const double lobPt[7] = {
215 -1.000000000000000, -0.830223896278567, -0.468848793470714, 0,
216 0.468848793470714, 0.830223896278567, 1.000000000000000};
217 const double lagPt[7] = {
218 -1.000000000000000, -0.666666666666666, -0.333333333333333, 0,
219 0.333333333333333, 0.666666666666666, 1.000000000000000};
222 const double monomial[7] = {0, 1, 2, 3, 4, 5, 6};
225 for(
int i = 0; i < ndofs; i++) {
226 for(
int j = 0; j < ndofs; j++) {
227 Vandermonde(i, j) =
pow_int(lobPt[i], monomial[j]);
232 Vandermonde.
invert(coefficient);
236 for(
int i = 0; i < ndofs; i++) {
237 for(
int j = 0; j < ndofs; j++) {
238 Vandermonde(i, j) =
pow_int(lagPt[i], monomial[j]);
248 std::vector<MVertex *> &ve,
int nPts = 1)
250 static bool GLLquad =
false;
251 static const double relaxFail = 1e-2;
252 double u0 = 0., u1 = 0., US[100];
262 double uMin = std::min(u0, u1), uMax = std::max(u0, u1);
265 while(failed && (relax > relaxFail)) {
275 "Failed to compute equidistant parameters (relax = %g, value = %g) "
276 "for edge %d-%d parametrized with %g %g on curve %d",
279 const double du = (uMax - uMin) / (nPts + 1);
280 for(
int i = 1; i <= nPts; i++) US[i] = US[i - 1] + du;
284 Msg::Error(
"Cannot reparametrize a mesh node in high order meshing");
286 if(!reparamOK)
return false;
290 M(0, 0) = u0 < u1 ? v0->
x() : v1->
x();
291 M(0, 1) = u0 < u1 ? v0->
y() : v1->
y();
292 M(0, 2) = u0 < u1 ? v0->
z() : v1->
z();
293 M(6, 0) = u0 < u1 ? v1->
x() : v0->
x();
294 M(6, 1) = u0 < u1 ? v1->
y() : v0->
y();
295 M(6, 2) = u0 < u1 ? v1->
z() : v0->
z();
296 for(
int j = 0; j < nPts; j++) {
297 int count = u0 < u1 ? j + 1 : nPts + 1 - (j + 1);
299 M(j + 1, 0) = pc.x();
300 M(j + 1, 1) = pc.y();
301 M(j + 1, 2) = pc.z();
307 for(
int j = 0; j < nPts; j++) {
309 int count = u0 < u1 ? j + 1 : nPts + 1 - (j + 1);
311 v =
new MEdgeVertex(Mlag(count, 0), Mlag(count, 1), Mlag(count, 2), ge,
318 for(
int j = 0; j < nPts; j++) {
320 int count = u0 < u1 ? j + 1 : nPts + 1 - (j + 1);
322 v =
new MEdgeVertex(pc.x(), pc.y(), pc.z(), ge, US[count]);
333 std::vector<MVertex *> &ve,
int nPts = 1)
336 double US[100], VS[100];
342 nPts + 2,
false, US, VS);
351 nPts + 2,
true, US, VS);
355 Msg::Error(
"Cannot reparametrize mesh edge %lu-%lu on surface %d",
360 for(
int j = 0; j < nPts; j++) {
363 new MFaceVertex(pc.
x(), pc.
y(), pc.
z(), gf, US[j + 1], VS[j + 1]);
371 std::vector<MVertex *> &veEdge,
376 for(
int k = 2; k < nPts + 2; k++) {
378 edgeEl->
pnt(points(k, 0), 0., 0., pos);
401 std::vector<MVertex *> &ve,
407 std::vector<MVertex *> veOld;
410 const bool increasing =
getMinMaxVert(veOld[0], veOld[1], vMin, vMax);
411 std::pair<MVertex *, MVertex *> p(vMin, vMax);
413 std::vector<MVertex *> veEdge;
419 if(edgeVertices.count(p) == 0) {
421 edgeVertices[p].insert(edgeVertices[p].end(), veEdge.begin(),
424 edgeVertices[p].insert(edgeVertices[p].end(), veEdge.rbegin(),
427 else if(p.first != p.second) {
430 "Mesh edges from different curves share nodes: create a finer mesh "
431 "(curve involved: %d)",
434 ve.insert(ve.end(), veEdge.begin(), veEdge.end());
439 std::vector<MVertex *> &ve,
446 std::vector<MVertex *> veOld;
449 const bool increasing =
getMinMaxVert(veOld[0], veOld[1], vMin, vMax);
450 std::pair<MVertex *, MVertex *> p(vMin, vMax);
451 std::vector<MVertex *> veEdge;
453 auto eIter = edgeVertices.find(p);
455 if(eIter != edgeVertices.end()) {
456 std::vector<MVertex *> &eVtcs = eIter->second;
458 veEdge.assign(eVtcs.begin(), eVtcs.end());
460 veEdge.assign(eVtcs.rbegin(), eVtcs.rend());
473 std::vector<MVertex *> &eVtcs = edgeVertices[p];
476 eVtcs.insert(eVtcs.end(), veEdge.begin(), veEdge.end());
478 eVtcs.insert(eVtcs.end(), veEdge.rbegin(), veEdge.rend());
480 ve.insert(ve.end(), veEdge.begin(), veEdge.end());
486 std::vector<MVertex *> &ve,
490 std::vector<MVertex *> veOld;
493 const bool increasing =
getMinMaxVert(veOld[0], veOld[1], vMin, vMax);
494 std::pair<MVertex *, MVertex *> p(vMin, vMax);
495 std::vector<MVertex *> veEdge;
496 if(edgeVertices.count(p)) {
498 veEdge.assign(edgeVertices[p].begin(), edgeVertices[p].end());
500 veEdge.assign(edgeVertices[p].rbegin(), edgeVertices[p].rend());
506 edgeVertices[p].insert(edgeVertices[p].end(), veEdge.begin(),
509 edgeVertices[p].insert(edgeVertices[p].end(), veEdge.rbegin(),
512 ve.insert(ve.end(), veEdge.begin(), veEdge.end());
519 int orientation,
bool swap)
521 int nbPts = vtcs.size();
522 if(nbPts <= 1)
return;
523 std::vector<MVertex *> tmp(nbPts);
524 int interiorOrder = (int)((sqrt(1. + 8. * nbPts) - 3) / 2);
526 for(
int o = interiorOrder; o > 0; o -= 3) {
528 tmp[pos] = vtcs[pos];
529 tmp[pos + 1] = vtcs[pos + 2];
530 tmp[pos + 2] = vtcs[pos + 1];
531 for(
int i = 0; i < 3 * (o - 1); i++)
532 tmp[pos + 3 + i] = vtcs[pos + 3 * o - i - 1];
535 for(
int i = 0; i < 3 * o; i++) tmp[pos + i] = vtcs[pos + i];
537 for(
int i = 0; i < 3; i++) {
538 int ri = (i + orientation) % 3;
539 vtcs[pos + ri] = tmp[pos + i];
540 for(
int j = 0; j < o - 1; j++)
541 vtcs[pos + 3 + (o - 1) * ri + j] = tmp[pos + 3 + (o - 1) * i + j];
548 bool swap,
int order)
550 int nbPts = vtcs.size();
551 if(nbPts <= 1)
return;
552 std::vector<MVertex *> tmp(nbPts);
558 if(order == 0) { start++; }
560 int i1(0), i2(0), i3(0), i4(0);
562 if(orientation == 0) {
568 else if(orientation == 1) {
574 else if(orientation == 2) {
580 else if(orientation == 3) {
588 if(orientation == 0) {
594 else if(orientation == 3) {
600 else if(orientation == 2) {
606 else if(orientation == 1) {
614 int indices[4] = {i1, i2, i3, i4};
615 for(
int i = 0; i < 4; i++) tmp[i] = vtcs[start + indices[i]];
616 for(
int i = 0; i < 4; i++) vtcs[start + i] = tmp[i];
620 for(
int iEdge = 0; iEdge < 4; iEdge++) {
621 int p1 = indices[iEdge];
622 int p2 = indices[(iEdge + 1) % 4];
624 if(p1 == 0 && p2 == 1) {
625 for(
int i = start + 0 * nbP; i < start + 1 * nbP; i++)
626 tmp[index++] = vtcs[i];
628 else if(p1 == 1 && p2 == 2) {
629 for(
int i = start + 1 * nbP; i < start + 2 * nbP; i++)
630 tmp[index++] = vtcs[i];
632 else if(p1 == 2 && p2 == 3) {
633 for(
int i = start + 2 * nbP; i < start + 3 * nbP; i++)
634 tmp[index++] = vtcs[i];
636 else if(p1 == 3 && p2 == 0) {
637 for(
int i = start + 3 * nbP; i < start + 4 * nbP; i++)
638 tmp[index++] = vtcs[i];
640 else if(p1 == 1 && p2 == 0) {
641 for(
int i = start + 1 * nbP - 1; i >= start + 0 * nbP; i--)
642 tmp[index++] = vtcs[i];
644 else if(p1 == 2 && p2 == 1) {
645 for(
int i = start + 2 * nbP - 1; i >= start + 1 * nbP; i--)
646 tmp[index++] = vtcs[i];
648 else if(p1 == 3 && p2 == 2) {
649 for(
int i = start + 3 * nbP - 1; i >= start + 2 * nbP; i--)
650 tmp[index++] = vtcs[i];
652 else if(p1 == 0 && p2 == 3) {
653 for(
int i = start + 4 * nbP - 1; i >= start + 3 * nbP; i--)
654 tmp[index++] = vtcs[i];
657 Msg::Error(
"Something wrong in reorientQuadPoints");
659 for(
int i = 0; i < index; i++) vtcs[start + i] = tmp[i];
664 if(start >= (
int)vtcs.size())
break;
670 const std::vector<MVertex *> &
vertices,
671 std::vector<MVertex *> &vFace)
673 for(
int k = 0; k < coefficients.
size1(); k++) {
674 double x(0), y(0),
z(0);
675 for(
int j = 0; j < coefficients.
size2(); j++) {
677 x += coefficients(k, j) * v->
x();
678 y += coefficients(k, j) * v->
y();
679 z += coefficients(k, j) * v->
z();
681 vFace.push_back(
new MVertex(x, y,
z, ge));
687 const std::vector<MVertex *> &
vertices,
688 std::vector<MVertex *> &vf)
691 if(coefficients.
size1() != 1 ||
vertices.size() != 8)
return false;
706 const std::vector<MVertex *> &
vertices,
707 std::vector<MVertex *> &vf)
710 bool reparamOK =
true;
711 for(std::size_t k = 0; k <
vertices.size(); ++k)
713 for(
int k = 0; k < coefficients.
size1(); k++) {
714 double X(0), Y(0), Z(0), GUESS[2] = {0, 0};
715 for(
int j = 0; j < coefficients.
size2(); j++) {
717 X += coefficients(k, j) * vt->
x();
718 Y += coefficients(k, j) * vt->
y();
719 Z += coefficients(k, j) * vt->
z();
721 GUESS[0] += coefficients(k, j) * pts[j][0];
722 GUESS[1] += coefficients(k, j) * pts[j][1];
756 std::vector<MVertex *> &newVertices,
762 std::vector<MVertex *> boundaryVertices;
765 boundaryVertices.reserve(nCorner + newVertices.size());
767 boundaryVertices.resize(nCorner);
768 boundaryVertices.insert(boundaryVertices.end(), newVertices.begin(),
773 std::vector<MVertex *> vFace;
788 faceVertices[face].insert(faceVertices[face].end(), vFace.begin(),
790 newVertices.insert(newVertices.end(), vFace.begin(), vFace.end());
794 const std::vector<MVertex *> &vCorner,
795 const std::vector<MVertex *> &vEdges,
796 std::vector<MVertex *> &v)
805 for(
int i = 0; i < 3; ++i) {
807 int n = std::abs(edge) - 1;
808 v.insert(v.end(), vEdges.begin() + n * nPts,
809 vEdges.begin() + (n + 1) * nPts);
810 if(edge < 0) std::reverse(v.end() - nPts, v.end());
818 for(
int i = 0; i < 4; ++i) {
820 int n = std::abs(edge) - 1;
821 v.insert(v.end(), vEdges.begin() + n * nPts,
822 vEdges.begin() + (n + 1) * nPts);
823 if(edge < 0) std::reverse(v.end() - nPts, v.end());
827 nCorner = k < 2 ? 3 : 4;
832 for(
int i = 0; i < nCorner; ++i) {
834 int n = std::abs(edge) - 1;
835 v.insert(v.end(), vEdges.begin() + n * nPts,
836 vEdges.begin() + (n + 1) * nPts);
837 if(edge < 0) std::reverse(v.end() - nPts, v.end());
841 nCorner = k < 4 ? 3 : 4;
846 for(
int i = 0; i < nCorner; ++i) {
848 int n = std::abs(edge) - 1;
849 v.insert(v.end(), vEdges.begin() + n * nPts,
850 vEdges.begin() + (n + 1) * nPts);
851 if(edge < 0) std::reverse(v.end() - nPts, v.end());
860 std::vector<MVertex *> &newVertices,
863 std::vector<MVertex *> vCorner;
869 std::vector<MVertex *> vFace;
870 auto fIter = faceVertices.find(face);
871 if(fIter != faceVertices.end()) {
872 std::vector<MVertex *> vtcs = fIter->second;
875 if(fIter->first.computeCorrespondence(face, orientation,
swap)) {
884 "Error in face lookup for retrieval of high order face nodes");
885 vFace.assign(vtcs.begin(), vtcs.end());
888 std::vector<MVertex *> faceBoundaryVertices;
890 i, ele->
getType(), nPts, vCorner, newVertices, faceBoundaryVertices);
895 faceVertices[face].insert(faceVertices[face].end(), vFace.begin(),
898 newVertices.insert(newVertices.end(), vFace.begin(), vFace.end());
904 std::vector<MVertex *> &newVertices,
int nPts = 1)
906 std::vector<MVertex *> boundaryVertices;
909 boundaryVertices.reserve(nCorner + newVertices.size());
911 boundaryVertices.resize(nCorner);
912 boundaryVertices.insert(boundaryVertices.end(), newVertices.begin(),
918 for(
int k = 0; k < coefficients.
size1(); k++) {
919 double x(0), y(0),
z(0);
920 for(
int j = 0; j < coefficients.
size2(); j++) {
921 MVertex *v = boundaryVertices[j];
922 x += coefficients(k, j) * v->
x();
923 y += coefficients(k, j) * v->
y();
924 z += coefficients(k, j) * v->
z();
927 newVertices.push_back(v);
936 std::vector<MLine *> lines2;
937 for(std::size_t i = 0; i < ge->
lines.size(); i++) {
939 std::vector<MVertex *> ve;
956 bool incomplete,
int nPts)
958 std::vector<MVertex *> v;
974 bool incomplete,
int nPts)
976 std::vector<MVertex *> v;
981 q->
getVertex(3), v[0], v[1], v[2], v[3], 0,
994 q->
getVertex(3), v[0], v[1], v[2], v[3], v[4], 0,
1007 bool incomplete,
int nPts = 1)
1009 std::vector<MTriangle *> triangles2;
1010 for(std::size_t i = 0; i < gf->
triangles.size(); i++) {
1013 setHighOrder(t, gf, edgeVertices, faceVertices, linear, incomplete, nPts);
1014 triangles2.push_back(tNew);
1019 std::vector<MQuadrangle *> quadrangles2;
1020 for(std::size_t i = 0; i < gf->
quadrangles.size(); i++) {
1023 setHighOrder(q, gf, edgeVertices, faceVertices, linear, incomplete, nPts);
1024 quadrangles2.push_back(qNew);
1036 std::vector<MVertex *> v;
1040 t->
getVertex(3), v[0], v[1], v[2], v[3], v[4],
1059 std::vector<MVertex *> v;
1066 v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10],
1083 v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10],
1084 v[11], v[12], v[13], v[14], v[15], v[16], v[17], v[18], 0,
1100 std::vector<MVertex *> v;
1106 v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8],
1120 v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8],
1137 std::vector<MVertex *> v;
1152 std::vector<MTetrahedron *> tetrahedra2;
1153 for(std::size_t i = 0; i < gr->
tetrahedra.size(); i++) {
1156 setHighOrder(t, gr, edgeVertices, faceVertices, incomplete, nPts);
1157 tetrahedra2.push_back(tNew);
1162 std::vector<MHexahedron *> hexahedra2;
1163 for(std::size_t i = 0; i < gr->
hexahedra.size(); i++) {
1166 setHighOrder(h, gr, edgeVertices, faceVertices, incomplete, nPts);
1167 hexahedra2.push_back(hNew);
1172 std::vector<MPrism *> prisms2;
1173 for(std::size_t i = 0; i < gr->
prisms.size(); i++) {
1176 setHighOrder(p, gr, edgeVertices, faceVertices, incomplete, nPts);
1177 prisms2.push_back(pNew);
1182 std::vector<MPyramid *> pyramids2;
1183 for(std::size_t i = 0; i < gr->
pyramids.size(); i++) {
1186 setHighOrder(p, gr, edgeVertices, faceVertices, incomplete, nPts);
1187 pyramids2.push_back(pNew);
1199 bool onlyVisible,
bool skipDiscrete)
1203 std::vector<T *> elements1;
1204 for(std::size_t i = 0; i < elements.size(); i++) {
1205 T *ele = elements[i];
1206 std::size_t n = ele->getNumPrimaryVertices();
1207 std::vector<MVertex *> v1;
1209 for(std::size_t j = 0; j < n; j++) v1.push_back(ele->getVertex(j));
1210 elements1.push_back(
new T(v1, 0, ele->getPartition()));
1213 elements = elements1;
1222 std::vector<MVertex *> v1;
1239 setFirstOrder(*it, (*it)->lines, onlyVisible, skipDiscrete);
1242 setFirstOrder(*it, (*it)->triangles, onlyVisible, skipDiscrete);
1243 setFirstOrder(*it, (*it)->quadrangles, onlyVisible, skipDiscrete);
1246 setFirstOrder(*it, (*it)->tetrahedra, onlyVisible, skipDiscrete);
1247 setFirstOrder(*it, (*it)->hexahedra, onlyVisible, skipDiscrete);
1248 setFirstOrder(*it, (*it)->prisms, onlyVisible, skipDiscrete);
1249 setFirstOrder(*it, (*it)->pyramids, onlyVisible, skipDiscrete);
1262 std::vector<MElement *> &bad,
double &minJGlob)
1266 double minGGlob = 1.0;
1268 int count = 0, nbfair = 0;
1270 for(std::size_t i = 0; i < (*it)->triangles.size(); i++) {
1274 double disto = disto_;
1275 minJGlob = std::min(minJGlob, disto);
1276 minGGlob = std::min(minGGlob, gamma_);
1281 else if(disto < 0.2)
1301 "%s: worst distortion = %g (%d elements in ]0, 0.2]); worst gamma = %g",
1302 cc, minJGlob, nbfair, minGGlob);
1305 "%s: worst distortion = %g (avg = %g, %d elements with jac. < 0); "
1307 cc, minJGlob, avg / (count ? count : 1), bad.size(), minGGlob);
1311 std::vector<MElement *> &bad,
double &minJGlob)
1316 int count = 0, nbfair = 0;
1318 for(std::size_t i = 0; i < (*it)->tetrahedra.size(); i++) {
1321 minJGlob = std::min(minJGlob, disto_);
1326 else if(disto_ < 0.2)
1333 Msg::Info(
"%s: worst distortion = %g (%d elements in ]0, 0.2])", cc,
1337 "%s: worst distortion = %g (avg = %g, %d elements with jac. < 0)", cc,
1338 minJGlob, avg / (count ? count : 1), bad.size());
1352 std::vector<MVertex *> v;
1356 std::pair<MVertex *, MVertex *> p(vMin, vMax);
1357 if(edgeVertices.count(p) == 0) {
1360 edgeVertices[p].push_back(v[j]);
1375 std::pair<MVertex *, MVertex *> p(vMin, vMax);
1376 if(edgeVertices.count(p) == 0) {
1377 std::vector<MVertex *> edgv;
1379 for(std::size_t k = 2; k < edgv.size(); k++) {
1380 edgeVertices[p].push_back(edgv[k]);
1385 std::vector<MVertex *> facev;
1386 if(faceVertices.count(
f) == 0) {
1389 j < facev.size(); j++) {
1390 faceVertices[
f].push_back(facev[j]);
1418 int nPts = order - 1;
1421 sprintf(msg,
"Meshing order %d (curvilinear %s)...", order,
1422 linear ?
"off" :
"on");
1442 Msg::Info(
"Meshing curve %d order %d", (*it)->tag(), order);
1444 if(onlyVisible && !(*it)->getVisibility())
continue;
1452 Msg::Info(
"Meshing surface %d order %d", (*it)->tag(), order);
1454 if(onlyVisible && !(*it)->getVisibility())
continue;
1456 setHighOrder(*it, edgeVertices, faceVertices, linear, incomplete, nPts);
1459 if((*it)->getColumns() !=
nullptr) (*it)->getColumns()->clearElementData();
1463 Msg::Info(
"Meshing volume %d order %d", (*it)->tag(), order);
1465 if(onlyVisible && !(*it)->getVisibility())
continue;
1467 setHighOrder(*it, edgeVertices, faceVertices, incomplete, nPts);
1468 if((*it)->getColumns() !=
nullptr) (*it)->getColumns()->clearElementData();
1478 std::vector<MElement *> bad;
1484 Msg::StatusBar(
true,
"Done meshing order %d (Wall %gs, CPU %gs)", order,