9 #include "GmshConfig.h"
34 #if defined(HAVE_MESH)
38 #define SQU(a) ((a) * (a))
85 for(rot = 0; rot < N; ++rot) {
87 for(i = 0; i < N; ++i) {
90 if(i == N)
return true;
94 for(rot = 0; rot < N; ++rot) {
96 for(i = 0; i < N; ++i) {
99 if(i == N)
return true;
116 if(faceIndex >= 0) { n[0] = n[1] =
getFace(faceIndex).
normal(); }
123 #if defined(HAVE_VISUDEV)
125 MVertex *v3,
double *x,
double *y,
double *
z,
130 x[2] = (x[0] + x[1] + v2->
x() + v3->
x()) / 4;
133 y[2] = (y[0] + y[1] + v2->
y() + v3->
y()) / 4;
136 z[2] = (
z[0] +
z[1] + v2->
z() + v3->
z()) / 4;
138 SVector3 t1(x[1] - x[0], y[1] - y[0],
z[1] -
z[0]);
139 SVector3 t2(x[2] - x[0], y[2] - y[0],
z[2] -
z[0]);
142 for(
int i = 0; i < 3; i++) n[i] = normal;
158 SVector3 t1(x[1] - x[0], y[1] - y[0],
z[1] -
z[0]);
159 SVector3 t2(x[2] - x[0], y[2] - y[0],
z[2] -
z[0]);
162 for(
int i = 0; i < 3; i++) n[i] = normal;
174 std::vector<MVertex *> vertices(
static_cast<std::size_t
>(order) + 1);
181 for(
int i = start; i < end; ++i) { vertices[++k] =
getVertex(i); }
184 for(
int i = end - 1; i >= start; --i) { vertices[++k] =
getVertex(i); }
191 for(ithEdge = 0; ithEdge <
getNumEdges(); ithEdge++) {
210 Msg::Error(
"Wrong dimension for getHighOrderFace");
222 const std::vector<int> &closure = fs->
getClosure(
id);
224 std::vector<MVertex *> vertices(closure.size());
225 for(std::size_t i = 0; i < closure.size(); ++i) {
229 static int type2numTriFaces[9] = {0, 0, 0, 1, 0, 4, 4, 2, 0};
260 const int &nV = uvw.
size1();
261 const int &dim = uvw.
size2();
264 std::vector<SPoint3> xyz1(nV1);
265 for(
int iV = 0; iV < nV1; ++iV) xyz1[iV] =
getVertex(iV)->
point();
267 for(
int iV = nV1; iV < nV; ++iV) {
269 lagBasis1->
f(uvw(iV, 0), (dim > 1) ? uvw(iV, 1) : 0.,
270 (dim > 2) ? uvw(iV, 2) : 0.,
f);
272 for(
int iSF = 0; iSF < nV1; ++iSF) xyzS += xyz1[iSF] *
f[iSF];
274 double dx = vec.
norm();
275 if(dx > maxdx) maxdx = dx;
282 #if defined(HAVE_MESH)
291 #if defined(HAVE_MESH)
301 #if defined(HAVE_MESH)
313 if(vert->
onWhat() == ge) {
320 if(geoNorm.
normSq() == 0.) {
323 geoNorm = ((
GFace *)ge)->normal(param);
327 const double scal = geoNorm(0) * elNorm(0, 0) + geoNorm(1) * elNorm(0, 1) +
328 geoNorm(2) * elNorm(0, 2);
329 if(scal < 0.) SJi.
scale(-1.);
340 #if defined(HAVE_MESH)
347 double sumEdLength = 0.;
348 for(
int iEd = 0; iEd < nEd; iEd++) sumEdLength +=
getEdge(iEd).
length();
349 const double invMeanEdLength = double(nEd) / sumEdLength;
350 if(sumEdLength == 0.) {
356 (dim == 1.) ? invMeanEdLength :
357 (dim == 2.) ? invMeanEdLength * invMeanEdLength :
358 invMeanEdLength * invMeanEdLength * invMeanEdLength;
365 if(vert->
onWhat() == ge) {
372 if(geoNorm.
normSq() == 0.) {
375 geoNorm = ((
GFace *)ge)->normal(param);
379 const double dp = geoNorm(0) * elNorm(0, 0) + geoNorm(1) * elNorm(0, 1) +
380 geoNorm(2) * elNorm(0, 2);
392 iCNMin = iCNMax = 1.0;
393 #if defined(HAVE_MESH)
401 normals(0, 0) = nVec[0];
402 normals(0, 1) = nVec[1];
403 normals(0, 2) = nVec[2];
411 if(vert->
onWhat() == ge) {
418 if(geoNorm.
normSq() == 0.) {
421 geoNorm = ((
GFace *)ge)->normal(param);
423 const double dp = geoNorm(0) * normals(0, 0) + geoNorm(1) * normals(0, 1) +
424 geoNorm(2) * normals(0, 2);
426 normals(0, 0) = -normals(0, 0);
427 normals(0, 1) = -normals(0, 1);
428 normals(0, 2) = -normals(0, 2);
433 iCNMin = *std::min_element(invCondNum.
getDataPtr(),
435 iCNMax = *std::max_element(invCondNum.
getDataPtr(),
442 #if defined(HAVE_MESH)
454 v =
getDim() > 1 ? refpnts(num, 1) : 0;
455 w =
getDim() > 2 ? refpnts(num, 2) : 0;
465 Msg::Error(
"Function space not implemented for this type of element");
469 double s[][3],
int o)
const
475 Msg::Error(
"Function space not implemented for this type of element");
479 double s[][3][3],
int o)
const
485 Msg::Error(
"Function space not implemented for this type of element");
494 fs->
dddf(u, v, w, s);
496 Msg::Error(
"Function space not implemented for this type of element");
508 for(
int i = 0; i < n; i++) {
510 xmin = std::min(xmin, v->
x());
511 xmax = std::max(xmax, v->
x());
512 ymin = std::min(ymin, v->
y());
513 ymax = std::max(ymax, v->
y());
514 zmin = std::min(zmin, v->
z());
515 zmax = std::max(zmax, v->
z());
517 return SPoint3(0.5 * (xmin + xmax), 0.5 * (ymin + ymax), 0.5 * (zmin + zmax));
524 for(std::size_t i = 0; i < n; i++) {
540 for(std::size_t i = 0; i < n; i++) {
554 for(
int i = 0; i < n; i++) {
573 for(
int i = 0; i < npts; i++) {
593 if(
getDim() < 3)
return true;
602 #if defined(HAVE_MESH)
605 if(jmin > .0)
return 1;
606 if(jmax >= .0)
return 0;
618 std::ostringstream sstream;
619 sstream.precision(12);
621 sstream <<
"Element " <<
getNum() <<
":";
622 if(multline) sstream <<
"\n";
626 sstream <<
" " << name <<
" (MSH type " <<
getTypeForMSH() <<
", dimension "
629 if(multline) sstream <<
"\n";
631 sstream <<
" Nodes:";
634 if(multline) sstream <<
"\n";
636 sstream <<
" Volume: " <<
getVolume() <<
"\n";
639 sstream <<
" Barycenter: (" << pt[0] <<
", " << pt[1] <<
", " << pt[2] <<
")";
640 if(multline) sstream <<
"\n";
642 sstream <<
" Edge length: "
643 <<
"min = " <<
minEdge() <<
" "
645 if(multline) sstream <<
"\n";
647 sstream <<
" Quality: "
649 if(multline) sstream <<
"\n";
651 double sICNMin, sICNMax;
653 sstream <<
" SICN range: " << sICNMin <<
" " << sICNMax;
654 if(multline) sstream <<
"\n";
656 double sIGEMin, sIGEMax;
658 sstream <<
" SIGE range: " << sIGEMin <<
" " << sIGEMax;
659 if(multline) sstream <<
"\n";
663 return sstream.str();
701 jac[0][0] = jac[1][1] = jac[2][2] = 1.0;
702 jac[0][1] = jac[1][0] = jac[2][0] = 0.0;
703 jac[0][2] = jac[1][2] = jac[2][1] = 0.0;
707 dJ = sqrt(
SQU(jac[0][0]) +
SQU(jac[0][1]) +
SQU(jac[0][2]));
710 double a[3], b[3],
c[3];
714 if((fabs(a[0]) >= fabs(a[1]) && fabs(a[0]) >= fabs(a[2])) ||
715 (fabs(a[1]) >= fabs(a[0]) && fabs(a[1]) >= fabs(a[2]))) {
737 dJ = sqrt(
SQU(jac[0][0] * jac[1][1] - jac[0][1] * jac[1][0]) +
738 SQU(jac[0][2] * jac[1][0] - jac[0][0] * jac[1][2]) +
739 SQU(jac[0][1] * jac[1][2] - jac[0][2] * jac[1][1]));
742 double a[3], b[3],
c[3];
758 (jac[0][0] * jac[1][1] * jac[2][2] + jac[0][2] * jac[1][0] * jac[2][1] +
759 jac[0][1] * jac[1][2] * jac[2][0] - jac[0][2] * jac[1][1] * jac[2][0] -
760 jac[0][0] * jac[1][2] * jac[2][1] - jac[0][1] * jac[1][0] * jac[2][2]);
780 jac[0] = jac[4] = jac[8] = 1.0;
781 jac[1] = jac[2] = jac[3] = 0.0;
782 jac[5] = jac[6] = jac[7] = 0.0;
786 dJ = sqrt(
SQU(jac[0]) +
SQU(jac[1]) +
SQU(jac[2]));
789 double a[3], b[3],
c[3];
793 if((fabs(a[0]) >= fabs(a[1]) && fabs(a[0]) >= fabs(a[2])) ||
794 (fabs(a[1]) >= fabs(a[0]) && fabs(a[1]) >= fabs(a[2]))) {
816 dJ = sqrt(
SQU(jac[0] * jac[4] - jac[1] * jac[3]) +
817 SQU(jac[2] * jac[3] - jac[0] * jac[5]) +
818 SQU(jac[1] * jac[5] - jac[2] * jac[4]));
821 double a[3], b[3],
c[3];
836 dJ = (jac[0] * jac[4] * jac[8] + jac[2] * jac[3] * jac[7] +
837 jac[1] * jac[5] * jac[6] - jac[2] * jac[4] * jac[6] -
838 jac[0] * jac[5] * jac[7] - jac[1] * jac[3] * jac[8]);
846 double jac[3][3])
const
848 jac[0][0] = jac[0][1] = jac[0][2] = 0.;
849 jac[1][0] = jac[1][1] = jac[1][2] = 0.;
850 jac[2][0] = jac[2][1] = jac[2][2] = 0.;
851 if(
getDim() > 3)
return 0;
858 for(
int j = 0; j <
getDim(); j++) {
859 jac[j][0] += ver->
x() * gg[j];
860 jac[j][1] += ver->
y() * gg[j];
861 jac[j][2] += ver->
z() * gg[j];
869 double jac[3][3])
const
871 jac[0][0] = jac[0][1] = jac[0][2] = 0.;
872 jac[1][0] = jac[1][1] = jac[1][2] = 0.;
873 jac[2][0] = jac[2][1] = jac[2][2] = 0.;
874 if(gsf.
size2() > 3)
return 0;
877 for(std::size_t i = 0; i < numShapeFunctions; i++) {
879 for(
int j = 0; j < gsf.
size2(); j++) {
880 jac[j][0] += v->
x() * gsf(i, j);
881 jac[j][1] += v->
y() * gsf(i, j);
882 jac[j][2] += v->
z() * gsf(i, j);
889 double jac[3][3])
const
891 jac[0][0] = jac[0][1] = jac[0][2] = 0.;
892 jac[1][0] = jac[1][1] = jac[1][2] = 0.;
893 jac[2][0] = jac[2][1] = jac[2][2] = 0.;
896 for(
int i = 0; i < numShapeFunctions; i++) {
898 for(
int j = 0; j < 3; j++) {
899 const double mult = gsf[i][j];
900 jac[j][0] += v->
x() *
mult;
901 jac[j][1] += v->
y() *
mult;
902 jac[j][2] += v->
z() *
mult;
911 for(std::size_t i = 0; i < 9; i++) { jac[i] = 0.; }
914 for(
int i = 0; i < numShapeFunctions; i++) {
916 for(
int j = 0; j < 3; j++) {
917 const double mult = gsf[i][j];
918 jac[3 * j + 0] += v->
x() *
mult;
919 jac[3 * j + 1] += v->
y() *
mult;
920 jac[3 * j + 2] += v->
z() *
mult;
931 for(
int i = 0; i < 3; i++) {
940 double jac[3][3])
const
942 jac[0][0] = jac[0][1] = jac[0][2] = 0.;
943 jac[1][0] = jac[1][1] = jac[1][2] = 0.;
944 jac[2][0] = jac[2][1] = jac[2][2] = 0.;
951 for(std::size_t j = 0; j < 3; j++) {
952 jac[j][0] += v->
x() * gg[j];
953 jac[j][1] += v->
y() * gg[j];
954 jac[j][2] += v->
z() * gg[j];
972 for(
int i = 0; i < numNodes; i++) {
974 nodesXYZ(i, 0) = v->
x();
975 nodesXYZ(i, 1) = v->
y();
976 nodesXYZ(i, 2) = v->
z();
991 pnt(nodesUVW(i, 0), nodesUVW(i, 1), nodesUVW(i, 2), xyz);
992 nodesXYZ(i, 0) = xyz[0];
993 nodesXYZ(i, 1) = xyz[1];
994 nodesXYZ(i, 2) = xyz[2];
1008 for(
int i = 0; i < pntUVW.
size1(); ++i) {
1009 uvw[0] = uvw[1] = uvw[2] = 0.;
1010 for(
int j = 0; j < pntUVW.
size2(); ++j) {
1011 uvw[j] = pntUVW(i, j);
1013 pnt(uvw[0], uvw[1], uvw[2], xyz);
1014 pntXYZ(i, 0) = xyz[0];
1015 pntXYZ(i, 1) = xyz[1];
1016 pntXYZ(i, 2) = xyz[2];
1023 double values[3])
const
1034 for(
int d = 0; d < 3; ++d) values[0] += jac[d][0] * jac[d][0];
1039 for(
int i = 0; i < 2; ++i) {
1040 for(
int j = 0; j < 2; ++j) {
1041 for(
int d = 0; d < 3; ++d) metric(i, j) += jac[d][i] * jac[d][j];
1046 metric.
eig(valReal, valImag, vecLeft, vecRight,
true);
1048 return std::sqrt(valReal(0) / valReal(1));
1053 for(
int i = 0; i < 3; ++i) {
1054 for(
int j = 0; j < 3; ++j) {
1055 for(
int d = 0; d < 3; ++d) metric(i, j) += jac[d][i] * jac[d][j];
1061 metric.
eig(valReal, valImag, vecLeft, vecRight,
true);
1063 return std::sqrt(valReal(0) / valReal(2));
1067 Msg::Error(
"wrong dimension for getEigenvaluesMetric function");
1074 double x = 0., y = 0.,
z = 0.;
1079 x += sf[j] * v->
x();
1080 y += sf[j] * v->
y();
1081 z += sf[j] * v->
z();
1088 double x = 0., y = 0.,
z = 0.;
1093 x += sf[j] * v->
x();
1094 y += sf[j] * v->
y();
1095 z += sf[j] * v->
z();
1104 double x = 0., y = 0.,
z = 0.;
1107 x += sf[j] * v->
x();
1108 y += sf[j] * v->
y();
1109 z += sf[j] * v->
z();
1116 double x = 0., y = 0.,
z = 0.;
1121 x += sf[j] * v->
x();
1122 y += sf[j] * v->
y();
1123 z += sf[j] * v->
z();
1133 uvw[0] = uvw[1] = uvw[2] = 0.;
1139 double distNearer = (v->
x() - xyz[0]) * (v->
x() - xyz[0]) +
1140 (v->
y() - xyz[1]) * (v->
y() - xyz[1]) +
1141 (v->
z() - xyz[2]) * (v->
z() - xyz[2]);
1144 double dist = (v->
x() - xyz[0]) * (v->
x() - xyz[0]) +
1145 (v->
y() - xyz[1]) * (v->
y() - xyz[1]) +
1146 (v->
z() - xyz[2]) * (v->
z() - xyz[2]);
1147 if(dist < distNearer) {
1154 for(
int i = 0; i <
getDim(); i++) { uvw[i] = refpnts(numNearer, i); }
1157 int iter = 1, maxiter = 20;
1158 double error = 1., tol = 1.e-6;
1160 while(error > tol && iter < maxiter) {
1162 if(!
getJacobian(uvw[0], uvw[1], uvw[2], jac))
break;
1163 double xn = 0., yn = 0., zn = 0.;
1168 xn += v->
x() * sf[i];
1169 yn += v->
y() * sf[i];
1170 zn += v->
z() * sf[i];
1174 double un = uvw[0] + inv[0][0] * (xyz[0] - xn) + inv[1][0] * (xyz[1] - yn) +
1175 inv[2][0] * (xyz[2] - zn);
1176 double vn = uvw[1] + inv[0][1] * (xyz[0] - xn) + inv[1][1] * (xyz[1] - yn) +
1177 inv[2][1] * (xyz[2] - zn);
1178 double wn = uvw[2] + inv[0][2] * (xyz[0] - xn) + inv[1][2] * (xyz[1] - yn) +
1179 inv[2][2] * (xyz[2] - zn);
1180 error = sqrt(
SQU(un - uvw[0]) +
SQU(vn - uvw[1]) +
SQU(wn - uvw[2]));
1194 double xyz[3] = {p.
x(), p.
y(), p.
z()};
1208 double xyz[3] = {p.
x(), p.
y(), p.
z()};
1217 int stride,
int order)
1224 sum += val[j] * sf[i];
1231 double f[],
int stride,
double invjac[3][3],
1234 double dfdu[3] = {0., 0., 0.};
1236 double gsf[1256][3];
1239 dfdu[0] += val[j] * gsf[i][0];
1240 dfdu[1] += val[j] * gsf[i][1];
1241 dfdu[2] += val[j] * gsf[i][2];
1244 if(invjac) {
matvec(invjac, dfdu,
f); }
1246 double jac[3][3], inv[3][3];
1254 double f[],
int stride,
int order)
1256 double fx[3], fy[3], fz[3], jac[3][3], inv[3][3];
1262 f[0] = fz[1] - fy[2];
1263 f[1] = -(fz[0] - fx[2]);
1264 f[2] = fy[0] - fx[1];
1268 int stride,
int order)
1270 double fx[3], fy[3], fz[3], jac[3][3], inv[3][3];
1276 return fx[0] + fy[1] + fz[2];
1285 for(
int i = 0; i < npts; i++) {
1286 double u = gp[i].
pt[0];
1287 double v = gp[i].
pt[1];
1288 double w = gp[i].
pt[2];
1289 double weight = gp[i].
weight;
1291 sum +=
interpolate(val, u, v, w, stride, order) * weight * detuvw;
1299 Msg::Error(
"No edge %d for this element", edge);
1303 std::vector<MVertex *> v;
1310 for(
int i = 0; i < 3; i++) {
1311 intv[i] = ee->
integrate(&val[i], pOrder, 3, order);
1315 double t[3] = {v[1]->x() - v[0]->x(), v[1]->y() - v[0]->y(),
1316 v[1]->z() - v[0]->z()};
1325 Msg::Error(
"No face %d for this element", face);
1328 std::vector<MVertex *> v;
1351 default: type = 0;
break;
1356 for(
int i = 0; i < 3; i++) {
1357 intv[i] = fe->
integrate(&val[i], pOrder, 3, order);
1362 normal3points(v[0]->x(), v[0]->y(), v[0]->
z(), v[1]->x(), v[1]->y(),
1363 v[1]->
z(), v[2]->x(), v[2]->y(), v[2]->
z(), n);
1369 int elementary,
int physical,
int parentNum,
1370 int dom1Num,
int dom2Num, std::vector<short> *ghosts)
1377 int par = (parentNum) ? 1 : 0;
1378 int dom = (dom1Num) ? 2 : 0;
1386 t->
writeMSH2(fp, version, binary, num++, elementary, physical, 0, 0, 0,
1393 t->
writeMSH2(fp, version, binary, num++, elementary, physical, 0, 0, 0,
1400 l->
writeMSH2(fp, version, binary, num++, elementary, physical, 0, 0, 0,
1410 fprintf(fp,
"%d %d", num ? num : (
int)
_num, type);
1412 fprintf(fp,
" %d %d %d", abs(physical), elementary, n);
1413 else if(version < 2.2)
1414 fprintf(fp,
" %d %d %d", abs(physical), elementary,
_partition);
1416 fprintf(fp,
" %d %d %d", 2 + par + dom, abs(physical), elementary);
1418 fprintf(fp,
" %d %d %d 1 %d", 4 + par + dom, abs(physical), elementary,
1421 int numGhosts = ghosts->size();
1422 fprintf(fp,
" %d %d %d %d %d", 4 + numGhosts + par + dom, abs(physical),
1424 for(std::size_t i = 0; i < ghosts->size(); i++)
1425 fprintf(fp,
" %d", -(*ghosts)[i]);
1427 if(version >= 2.0 && par) fprintf(fp,
" %d", parentNum);
1428 if(version >= 2.0 && dom) fprintf(fp,
" %d %d", dom1Num, dom2Num);
1429 if(version >= 2.0 && poly) fprintf(fp,
" %d", n);
1432 int numTags, numGhosts = 0;
1438 numGhosts = ghosts->size();
1439 numTags = 4 + numGhosts;
1448 type, 1, numTags, num ? num : (int)
_num,
1449 abs(physical), elementary, 1 + numGhosts,
_partition};
1451 for(
int i = 0; i < numGhosts; i++) blob[8 + i] = -(*ghosts)[i];
1452 if(par) blob[8 + numGhosts] = parentNum;
1453 if(poly)
Msg::Error(
"Unable to write polygons/polyhedra in binary files.");
1454 fwrite(blob,
sizeof(
int), 4 + numTags, fp);
1459 std::vector<int> verts;
1463 for(
int i = 0; i < n; i++) fprintf(fp,
" %d", verts[i]);
1467 fwrite(&verts[0],
sizeof(
int), n, fp);
1474 std::vector<short> *ghosts)
1480 std::vector<int> verts;
1485 std::vector<int> data;
1486 data.insert(data.end(), verts.begin(), verts.end());
1490 data.push_back(1 + ghosts->size());
1492 data.insert(data.end(), ghosts->begin(), ghosts->end());
1499 int numData = data.size();
1502 fprintf(fp,
"%d %d %d %d", num, type, entity, numData);
1503 for(
int i = 0; i < numData; i++) fprintf(fp,
" %d", data[i]);
1507 fwrite(&num,
sizeof(
int), 1, fp);
1508 fwrite(&type,
sizeof(
int), 1, fp);
1509 fwrite(&entity,
sizeof(
int), 1, fp);
1510 fwrite(&numData,
sizeof(
int), 1, fp);
1511 fwrite(&data[0],
sizeof(
int), numData, fp);
1516 bool printSICN,
bool printSIGE,
bool printGamma,
1517 bool printDisto,
double scalingFactor,
int elementary)
1523 fprintf(fp,
"%s(", str);
1524 for(
int i = 0; i < n; i++) {
1525 if(i) fprintf(fp,
",");
1526 fprintf(fp,
"%g,%g,%g",
getVertex(i)->x() * scalingFactor,
1532 if(printElementary) {
1533 for(
int i = 0; i < n; i++) {
1538 fprintf(fp,
"%d", elementary);
1541 if(printElementNumber) {
1542 for(
int i = 0; i < n; i++) {
1547 fprintf(fp,
"%lu",
getNum());
1552 for(
int i = 0; i < n; i++) {
1557 fprintf(fp,
"%g", sICNMin);
1562 for(
int i = 0; i < n; i++) {
1567 fprintf(fp,
"%g", sIGEMin);
1572 for(
int i = 0; i < n; i++) {
1577 fprintf(fp,
"%g", gamma);
1582 for(
int i = 0; i < n; i++) {
1587 fprintf(fp,
"%g", disto);
1590 fprintf(fp,
"};\n");
1596 int qid[3] = {0, 2, 3};
1599 fprintf(fp,
"facet normal %g %g %g\n", n[0], n[1], n[2]);
1600 fprintf(fp,
" outer loop\n");
1601 for(
int j = 0; j < 3; j++)
1603 fp,
" vertex %.16g %.16g %.16g\n",
getVertex(j)->x() * scalingFactor,
1605 fprintf(fp,
" endloop\n");
1606 fprintf(fp,
"endfacet\n");
1608 fprintf(fp,
"facet normal %g %g %g\n", n[0], n[1], n[2]);
1609 fprintf(fp,
" outer loop\n");
1610 for(
int j = 0; j < 3; j++)
1611 fprintf(fp,
" vertex %.16g %.16g %.16g\n",
1615 fprintf(fp,
" endloop\n");
1616 fprintf(fp,
"endfacet\n");
1621 float *coords = (
float *)data;
1622 coords[0] = (float)n[0];
1623 coords[1] = (float)n[1];
1624 coords[2] = (float)n[2];
1625 for(
int j = 0; j < 3; j++) {
1626 coords[3 + 3 * j] = (float)(
getVertex(j)->
x() * scalingFactor);
1627 coords[3 + 3 * j + 1] = (float)(
getVertex(j)->
y() * scalingFactor);
1628 coords[3 + 3 * j + 2] = (float)(
getVertex(j)->
z() * scalingFactor);
1630 data[48] = data[49] = 0;
1631 fwrite(data,
sizeof(
char), 50, fp);
1633 for(
int j = 0; j < 3; j++) {
1634 coords[3 + 3 * j] = (float)(
getVertex(qid[j])->
x() * scalingFactor);
1635 coords[3 + 3 * j + 1] = (float)(
getVertex(qid[j])->
y() * scalingFactor);
1636 coords[3 + 3 * j + 2] = (float)(
getVertex(qid[j])->
z() * scalingFactor);
1638 fwrite(data,
sizeof(
char), 50, fp);
1646 int qid[3] = {0, 2, 3};
1648 for(
int j = 0; j < 3; j++)
1649 fprintf(fp,
"%g %g %g\n",
getVertex(j)->x() * scalingFactor,
1653 for(
int j = 0; j < 3; j++) {
1654 fprintf(fp,
"%g %g %g\n",
getVertex(qid[j])->x() * scalingFactor,
1673 fprintf(fp,
"-1,\n");
1682 fprintf(fp,
"element %d %s ", num, str);
1683 for(
int i = 0; i < n; i++) {
1697 for(
int i = 0; i < n; i++)
1700 if(!bigEndian)
SwapBytes((
char *)verts,
sizeof(
int), n + 1);
1701 fwrite(verts,
sizeof(
int), n + 1, fp);
1704 fprintf(fp,
"%d", n);
1705 for(
int i = 0; i < n; i++)
1718 "Binary format not available for Matlab, saving into ASCII format");
1725 for(
int i = 0; i < n; i++)
1735 fprintf(fp,
" %d\n", physical ? abs(physical) : elementary);
1747 int physical_property = elementary;
1748 int material_property = abs(physical);
1750 fprintf(fp,
"%10d%10d%10d%10d%10d%10d\n", num ? num : (
int)
_num, type,
1751 physical_property, material_property, color, n);
1752 if(type == 21 || type == 24)
1753 fprintf(fp,
"%10d%10d%10d\n", 0, 0, 0);
1757 for(
int k = 0; k < n; k++) {
1759 if(k % 8 == 7) fprintf(fp,
"\n");
1761 if(n - 1 % 8 != 7) fprintf(fp,
"\n");
1777 fprintf(fp,
" %ld",
getVertex(i)->getIndex());
1778 fprintf(fp,
" %d\n",
1780 (elementTagType == 2) ? abs(physical) :
1792 if(i == 7) fprintf(fp,
"\n ");
1806 fprintf(fp,
"%d %d %d", num,
1808 (elementTagType == 2) ? abs(physical) :
1811 for(
int i = 0; i < numVert; i++)
1812 fprintf(fp,
" %ld",
getVertex(i)->getIndex());
1819 int elementary,
int physical)
1825 const char *cont[4] = {
"E",
"F",
"G",
"H"};
1830 int tag = (elementTagType == 3) ?
_partition :
1831 (elementTagType == 2) ? abs(physical) :
1835 fprintf(fp,
"%s,%lu,%d", str,
_num, tag);
1836 for(
int i = 0; i < n; i++) {
1838 if(i != n - 1 && !((i + 3) % 8)) {
1839 fprintf(fp,
",+%s%lu\n+%s%lu", cont[ncont],
_num, cont[ncont],
_num);
1844 fprintf(fp,
",0.,0.,0.");
1847 else if(format == 1) {
1848 fprintf(fp,
"%-8s%-8lu%-8d", str,
_num, tag);
1849 for(
int i = 0; i < n; i++) {
1851 if(i != n - 1 && !((i + 3) % 8)) {
1852 fprintf(fp,
"+%s%-6lu\n+%s%-6lu", cont[ncont],
_num, cont[ncont],
_num);
1857 fprintf(fp,
"%-8s%-8s%-8s",
"0.",
"0.",
"0.");
1861 fprintf(fp,
"%-8s%-8lu%-8d", str,
_num, tag);
1862 for(
int i = 0; i < n; i++) {
1864 if(i != n - 1 && !((i + 3) % 8)) {
1870 fprintf(fp,
"%-8s%-8s%-8s",
"0.",
"0.",
"0.");
1889 fprintf(fp,
"%d %s %d ", num, str, abs(physical));
1890 for(
int i = 0; i < n; i++)
1900 fprintf(fp,
"%d, ", num);
1902 for(
int i = 0; i < n; i++) {
1906 if(i && !((i + 2) % 16)) fprintf(fp,
"\n");
1914 fprintf(fp,
"%d, %d, ", num, pid);
1921 nid[7] = nid[6] = nid[5] = nid[4] = nid[3];
1924 nid[7] = nid[6] = nid[5];
1935 nid[7] = nid[6] = nid[5];
1945 for(i = 2; i < 8; i++) nid[i] = 0;
1949 for(i = 0; i < n; i++) {
1950 fprintf(fp,
"%d", nid[i]);
1953 if(!((i + 2) % 10)) fprintf(fp,
"\n");
1961 fprintf(fp,
"%10d", num);
1990 for(i = 0; i < 8; i++) {
1991 fprintf(fp,
"%10d", nid[i]);
1994 for(i = 8; i < 16; i++) {
1995 fprintf(fp,
"%10d", nid[i]);
1998 for(i = 16; i < 20; i++) {
1999 fprintf(fp,
"%10d", nid[i]);
2005 for(i = 0; i < 8; i++) {
2006 fprintf(fp,
"%10d", nid[i]);
2009 for(i = 8; i < 16; i++) {
2010 fprintf(fp,
"%10d", nid[i]);
2013 for(i = 16; i < 20; i++) {
2014 fprintf(fp,
"%10d", nid[i]);
2026 nid[7] = nid[6] = nid[5];
2040 for(i = 0; i < n; i++) {
2041 fprintf(fp,
"%10d", nid[i]);
2052 fprintf(fp,
"%d\n", num);
2061 if(name) *name =
"Point";
2064 if(name) *name =
"Line 1";
2067 if(name) *name =
"Line 2";
2070 if(name) *name =
"Line 3";
2073 if(name) *name =
"Line 4";
2076 if(name) *name =
"Line 5";
2079 if(name) *name =
"Line 6";
2082 if(name) *name =
"Line 7";
2085 if(name) *name =
"Line 8";
2088 if(name) *name =
"Line 9";
2091 if(name) *name =
"Line 10";
2094 if(name) *name =
"Line 11";
2097 if(name) *name =
"Line Border";
2100 if(name) *name =
"Line Child";
2103 if(name) *name =
"Triangle 1";
2106 if(name) *name =
"Triangle 3";
2109 if(name) *name =
"Triangle 6";
2112 if(name) *name =
"Triangle 9";
2115 if(name) *name =
"Triangle 10";
2118 if(name) *name =
"Triangle 12";
2121 if(name) *name =
"Triangle 15";
2124 if(name) *name =
"Triangle 15I";
2127 if(name) *name =
"Triangle 21";
2130 if(name) *name =
"Triangle 28";
2133 if(name) *name =
"Triangle 36";
2136 if(name) *name =
"Triangle 45";
2139 if(name) *name =
"Triangle 55";
2142 if(name) *name =
"Triangle 66";
2145 if(name) *name =
"Triangle 18";
2148 if(name) *name =
"Triangle 21I";
2151 if(name) *name =
"Triangle 24";
2154 if(name) *name =
"Triangle 27";
2157 if(name) *name =
"Triangle 30";
2160 if(name) *name =
"Triangle Border";
2163 if(name) *name =
"Quadrilateral 1";
2166 if(name) *name =
"Quadrilateral 4";
2169 if(name) *name =
"Quadrilateral 8";
2172 if(name) *name =
"Quadrilateral 9";
2175 if(name) *name =
"Quadrilateral 16";
2178 if(name) *name =
"Quadrilateral 25";
2181 if(name) *name =
"Quadrilateral 36";
2184 if(name) *name =
"Quadrilateral 49";
2187 if(name) *name =
"Quadrilateral 64";
2190 if(name) *name =
"Quadrilateral 81";
2193 if(name) *name =
"Quadrilateral 100";
2196 if(name) *name =
"Quadrilateral 121";
2199 if(name) *name =
"Quadrilateral 12";
2202 if(name) *name =
"Quadrilateral 16I";
2205 if(name) *name =
"Quadrilateral 20";
2208 if(name) *name =
"Quadrilateral 24";
2211 if(name) *name =
"Quadrilateral 28";
2214 if(name) *name =
"Quadrilateral 32";
2217 if(name) *name =
"Quadrilateral 36I";
2220 if(name) *name =
"Quadrilateral 40";
2223 if(name) *name =
"Polygon";
2226 if(name) *name =
"Polygon Border";
2229 if(name) *name =
"Tetrahedron 1";
2232 if(name) *name =
"Tetrahedron 4";
2235 if(name) *name =
"Tetrahedron 10";
2238 if(name) *name =
"Tetrahedron 20";
2241 if(name) *name =
"Tetrahedron 35";
2242 return 4 + 18 + 12 + 1;
2244 if(name) *name =
"Tetrahedron 56";
2245 return 4 + 24 + 24 + 4;
2247 if(name) *name =
"Tetrahedron 84";
2248 return (7 * 8 * 9) / 6;
2250 if(name) *name =
"Tetrahedron 120";
2251 return (8 * 9 * 10) / 6;
2253 if(name) *name =
"Tetrahedron 165";
2254 return (9 * 10 * 11) / 6;
2256 if(name) *name =
"Tetrahedron 220";
2257 return (10 * 11 * 12) / 6;
2259 if(name) *name =
"Tetrahedron 286";
2260 return (11 * 12 * 13) / 6;
2262 if(name) *name =
"Tetrahedron 16";
2265 if(name) *name =
"Tetrahedron 22";
2268 if(name) *name =
"Tetrahedron 28";
2271 if(name) *name =
"Tetrahedron 34";
2274 if(name) *name =
"Tetrahedron 40";
2277 if(name) *name =
"Tetrahedron 46";
2280 if(name) *name =
"Tetrahedron 52";
2283 if(name) *name =
"Tetrahedron 58";
2286 if(name) *name =
"Hexahedron 1";
2289 if(name) *name =
"Hexahedron 8";
2292 if(name) *name =
"Hexahedron 20";
2295 if(name) *name =
"Hexahedron 27";
2296 return 8 + 12 + 6 + 1;
2298 if(name) *name =
"Hexahedron 64";
2301 if(name) *name =
"Hexahedron 125";
2304 if(name) *name =
"Hexahedron 216";
2307 if(name) *name =
"Hexahedron 343";
2310 if(name) *name =
"Hexahedron 512";
2313 if(name) *name =
"Hexahedron 729";
2316 if(name) *name =
"Hexahedron 1000";
2319 if(name) *name =
"Hexahedron 32";
2322 if(name) *name =
"Hexahedron 44";
2325 if(name) *name =
"Hexahedron 56";
2328 if(name) *name =
"Hexahedron 68";
2331 if(name) *name =
"Hexahedron 80";
2334 if(name) *name =
"Hexahedron 92";
2337 if(name) *name =
"Hexahedron 104";
2340 if(name) *name =
"Prism 1";
2343 if(name) *name =
"Prism 6";
2346 if(name) *name =
"Prism 15";
2349 if(name) *name =
"Prism 18";
2352 if(name) *name =
"Prism 40";
2353 return 6 + 18 + 12 + 2 + 2 * 1;
2355 if(name) *name =
"Prism 75";
2356 return 6 + 27 + 27 + 6 + 3 * 3;
2358 if(name) *name =
"Prism 126";
2359 return 6 + 36 + 48 + 12 + 4 * 6;
2361 if(name) *name =
"Prism 196";
2362 return 6 + 45 + 75 + 20 + 5 * 10;
2364 if(name) *name =
"Prism 288";
2365 return 6 + 54 + 108 + 30 + 6 * 15;
2367 if(name) *name =
"Prism 405";
2368 return 6 + 63 + 147 + 42 + 7 * 21;
2370 if(name) *name =
"Prism 550";
2371 return 6 + 72 + 192 + 56 + 8 * 28;
2373 if(name) *name =
"Prism 24";
2376 if(name) *name =
"Prism 33";
2379 if(name) *name =
"Prism 42";
2382 if(name) *name =
"Prism 51";
2385 if(name) *name =
"Prism 60";
2388 if(name) *name =
"Prism 69";
2391 if(name) *name =
"Prism 78";
2394 if(name) *name =
"Pyramid 1";
2397 if(name) *name =
"Pyramid 5";
2400 if(name) *name =
"Pyramid 13";
2403 if(name) *name =
"Pyramid 14";
2406 if(name) *name =
"Pyramid 30";
2407 return 5 + 8 * 2 + 4 * 1 + 1 * 4 + 1;
2409 if(name) *name =
"Pyramid 55";
2410 return 5 + 8 * 3 + 4 * 3 + 1 * 9 + 5;
2412 if(name) *name =
"Pyramid 91";
2413 return 5 + 8 * 4 + 4 * 6 + 1 * 16 + 14;
2415 if(name) *name =
"Pyramid 140";
2416 return 5 + 8 * 5 + 4 * 10 + 1 * 25 + 30;
2418 if(name) *name =
"Pyramid 204";
2419 return 5 + 8 * 6 + 4 * 15 + 1 * 36 + 55;
2421 if(name) *name =
"Pyramid 285";
2422 return 5 + 8 * 7 + 4 * 21 + 1 * 49 + 91;
2424 if(name) *name =
"Pyramid 385";
2425 return 5 + 8 * 8 + 4 * 28 + 1 * 64 + 140;
2427 if(name) *name =
"Pyramid 21";
2430 if(name) *name =
"Pyramid 29";
2433 if(name) *name =
"Pyramid 37";
2436 if(name) *name =
"Pyramid 45";
2439 if(name) *name =
"Pyramid 53";
2442 if(name) *name =
"Pyramid 61";
2445 if(name) *name =
"Pyramid 69";
2448 if(name) *name =
"Trihedron 4";
2451 if(name) *name =
"Polyhedron";
2454 if(name) *name =
"Point Xfem";
2457 if(name) *name =
"Line Xfem";
2460 if(name) *name =
"Triangle Xfem";
2463 if(name) *name =
"Tetrahedron Xfem";
2466 Msg::Error(
"Unknown type of element %d", typeMSH);
2467 if(name) *name =
"Unknown";
2487 std::map<MElement *, MElement *> &newParents,
2488 std::map<MElement *, MElement *> &newDomains)
2490 if(newDomains.count(
this))
return newDomains.find(
this)->second;
2491 std::vector<MVertex *> vmv;
2497 std::size_t numV = v->
getNum();
2498 if(vertexMap.count(numV))
2499 vmv.push_back(vertexMap[numV]);
2503 vertexMap[numV] = mv;
2511 std::size_t numV = v->
getNum();
2512 if(vertexMap.count(numV))
2513 vmv.push_back(vertexMap[numV]);
2517 vertexMap[numV] = mv;
2525 auto it = newParents.find(eParent);
2527 if(it == newParents.end()) {
2528 newParent = eParent->
copy(vertexMap, newParents, newDomains);
2529 newParents[eParent] = newParent;
2532 newParent = it->second;
2540 for(
int i = 0; i < 2; i++) {
2543 auto it = newDomains.find(dom);
2545 if(it == newDomains.end()) {
2546 newDom = dom->
copy(vertexMap, newParents, newDomains);
2547 newDomains[dom] = newDom;
2550 newDom = newDomains.find(dom)->second;
2557 std::size_t num,
int part,
bool owner,
2664 return (parent_ptr) ?
new MSubPoint(v, num, part, owner, parent_ptr) :
2665 new MSubPoint(v, num, part, owner, parent);
2667 return (parent_ptr) ?
new MSubLine(v, num, part, owner, parent_ptr) :
2668 new MSubLine(v, num, part, owner, parent);
2670 return (parent_ptr) ?
new MSubTriangle(v, num, part, owner, parent_ptr) :
2673 return (parent_ptr) ?
new MSubTetrahedron(v, num, part, owner, parent_ptr) :
2686 default:
return nullptr;
2691 const std::vector<int> &data,
GModel *model)
2698 if(data.size() && !numVertices) {
2700 numVertices = data[0];
2703 std::vector<MVertex *> vertices(numVertices);
2704 if((
int)data.size() > startVertices + numVertices - 1) {
2705 for(
int i = 0; i < numVertices; i++) {
2706 int numVertex = data[startVertices + i];
2708 if(v) { vertices[i] = v; }
2710 Msg::Error(
"Unknown node %d in element %d", numVertex, num);
2716 Msg::Error(
"Missing data in element %d", num);
2720 unsigned int part = 0;
2721 int startPartitions = startVertices + numVertices;
2726 parent = data[startPartitions];
2727 startPartitions += 1;
2730 std::vector<short> ghosts;
2731 if((
int)data.size() > startPartitions) {
2732 int numPartitions = data[startPartitions];
2733 if(numPartitions > 0 &&
2734 (
int)data.size() > startPartitions + numPartitions - 1) {
2735 part = data[startPartitions + 1];
2736 for(
int i = 1; i < numPartitions; i++)
2737 ghosts.push_back(data[startPartitions + 1 + i]);
2756 if(
f.getNumVertices() == 3) {
2760 else if(
f.getNumVertices() == 4) {