11 #include "GmshConfig.h"
18 #if defined(HAVE_DINTEGRATION)
19 #include "Integration3D.h"
27 if(
_parts.size() == 0)
return;
29 for(std::size_t i = 0; i <
_parts.size(); i++) {
32 for(
int j = 0; j < 4; j++) {
34 for(k =
_faces.size() - 1; k >= 0; k--)
42 for(
int j = 0; j < 6; j++) {
44 for(k =
_edges.size() - 1; k >= 0; k--)
48 for(
int j = 0; j < 4; j++) {
50 for(k =
_vertices.size() - 1; k >= 0; k--)
58 for(std::size_t i = 0; i <
_faces.size(); i++) {
59 for(
int j = 0; j < 3; j++) {
61 for(k =
_edges.size() - 1; k >= 0; k--)
65 for(
int j = 0; j < 3; j++) {
67 for(k =
_vertices.size() - 1; k >= 0; k--)
75 for(std::size_t i = 0; i <
_parts.size(); i++) {
76 for(
int j = 0; j < 4; j++) {
86 if(!
_orig)
return false;
87 double uvw[3] = {u, v, w};
88 for(std::size_t i = 0; i <
_parts.size(); i++) {
90 for(
int j = 0; j < 4; j++) {
92 double v_xyz[3] = {vij->
x(), vij->
y(), vij->
z()};
95 MVertex v0(verts[0][0], verts[0][1], verts[0][2]);
96 MVertex v1(verts[1][0], verts[1][1], verts[1][2]);
97 MVertex v2(verts[2][0], verts[2][1], verts[2][2]);
98 MVertex v3(verts[3][0], verts[3][1], verts[3][2]);
102 if(t.
isInside(ksi[0], ksi[1], ksi[2]))
return true;
114 for(std::size_t i = 0; i <
_parts.size(); i++) {
117 _parts[i]->getIntegrationPoints(pOrder, &nptsi, &ptsi);
119 for(
int j = 0; j < 4; j++) {
120 double xyz[3] = {
_parts[i]->getVertex(j)->x(),
121 _parts[i]->getVertex(j)->y(),
122 _parts[i]->getVertex(j)->z()};
125 MVertex v0(uvw[0][0], uvw[0][1], uvw[0][2]);
126 MVertex v1(uvw[1][0], uvw[1][1], uvw[1][2]);
127 MVertex v2(uvw[2][0], uvw[2][1], uvw[2][2]);
128 MVertex v3(uvw[3][0], uvw[3][1], uvw[3][2]);
131 for(
int ip = 0; ip < nptsi; ip++) {
132 const double u = ptsi[ip].
pt[0];
133 const double v = ptsi[ip].
pt[1];
134 const double w = ptsi[ip].
pt[2];
140 double partJac =
_parts[i]->getJacobian(p.
x(), p.
y(), p.
z(), jac);
154 if(
_parts.size() == 0)
return;
161 n =
_parts[0]->getFace(0).normal();
162 for(std::size_t i = 0; i <
_parts.size(); i++) {
164 if(
dot(n, ni) < 0.)
_parts[i]->reverse();
167 std::vector<MEdge> edg;
168 std::vector<MEdge> multiEdges;
170 for(
int j = 0; j <
_parts[0]->getNumEdges(); j++)
171 edg.push_back(
_parts[0]->getEdge(j));
172 for(std::size_t i = 1; i <
_parts.size(); i++) {
173 for(
int j = 0; j <
_parts[i]->getNumEdges(); j++) {
177 for(k = edg.size() - 1; k >= 0; k--) {
179 edg.erase(edg.begin() + k);
185 for(k = 0; k < (int)multiEdges.size(); k++)
187 multiEdges[k].isInside(ed.
getVertex(1))) {
193 for(k = edg.size() - 1; k >= 0; k--) {
196 multiEdges.push_back(edg[k]);
197 edg.erase(edg.begin() + k);
204 for(k = edg.size() - 1; k >= 0; k--) {
205 if(ed.
isInside(edg[k].getVertex(0)) &&
207 edg.erase(edg.begin() + k);
208 int nbME = multiEdges.size();
209 if(nbME == 0 || multiEdges[nbME - 1] != ed)
210 multiEdges.push_back(ed);
215 if(!found) edg.push_back(ed);
221 edg.erase(edg.begin());
224 for(std::size_t i = 0; i < edg.size(); i++) {
227 edg.erase(edg.begin() + i);
232 edg.erase(edg.begin() + i);
235 if(i == edg.size() - 1) {
237 edg.erase(edg.begin());
243 for(std::size_t i = 0; i <
_edges.size(); i++) {
248 for(std::size_t i = 0; i <
_parts.size(); i++) {
249 for(
int j = 0; j < 3; j++) {
260 double uvw[3] = {u, v, w};
261 for(std::size_t i = 0; i <
_parts.size(); i++) {
263 for(
int j = 0; j < 3; j++) {
265 double v_xyz[3] = {vij->
x(), vij->
y(), vij->
z()};
268 MVertex v0(v_uvw[0][0], v_uvw[0][1], v_uvw[0][2]);
269 MVertex v1(v_uvw[1][0], v_uvw[1][1], v_uvw[1][2]);
270 MVertex v2(v_uvw[2][0], v_uvw[2][1], v_uvw[2][2]);
274 if(t.
isInside(ksi[0], ksi[1], ksi[2]))
return true;
286 for(std::size_t i = 0; i <
_parts.size(); i++) {
289 _parts[i]->getIntegrationPoints(pOrder, &nptsi, &ptsi);
291 for(
int j = 0; j < 3; j++) {
292 double xyz[3] = {
_parts[i]->getVertex(j)->x(),
293 _parts[i]->getVertex(j)->y(),
294 _parts[i]->getVertex(j)->z()};
297 MVertex v0(uvw[0][0], uvw[0][1], uvw[0][2]);
298 MVertex v1(uvw[1][0], uvw[1][1], uvw[1][2]);
299 MVertex v2(uvw[2][0], uvw[2][1], uvw[2][2]);
301 for(
int ip = 0; ip < nptsi; ip++) {
302 const double u = ptsi[ip].
pt[0];
303 const double v = ptsi[ip].
pt[1];
304 const double w = ptsi[ip].
pt[2];
310 double partJac =
_parts[i]->getJacobian(p.
x(), p.
y(), p.
z(), jac);
323 if(!
_orig)
return false;
324 double uvw[3] = {u, v, w};
326 for(
int i = 0; i < 2; i++) {
328 double v_xyz[3] = {vi->
x(), vi->
y(), vi->
z()};
331 MVertex v0(v_uvw[0][0], v_uvw[0][1], v_uvw[0][2]);
332 MVertex v1(v_uvw[1][0], v_uvw[1][1], v_uvw[1][2]);
336 if(l.
isInside(ksi[0], ksi[1], ksi[2]))
return true;
349 for(
int i = 0; i < 2; i++) {
351 double v_xyz[3] = {vi->
x(), vi->
y(), vi->
z()};
354 MVertex v0(v_uvw[0][0], v_uvw[0][1], v_uvw[0][2]);
355 MVertex v1(v_uvw[1][0], v_uvw[1][1], v_uvw[1][2]);
358 for(
int ip = 0; ip < nptsi; ip++) {
359 const double u = ptsi[ip].
pt[0];
360 const double v = ptsi[ip].
pt[1];
361 const double w = ptsi[ip].
pt[2];
379 double uvw[3] = {u, v, w};
381 for(
int i = 0; i < 3; i++) {
383 double v_xyz[3] = {vi->
x(), vi->
y(), vi->
z()};
386 MVertex v0(v_uvw[0][0], v_uvw[0][1], v_uvw[0][2]);
387 MVertex v1(v_uvw[1][0], v_uvw[1][1], v_uvw[1][2]);
388 MVertex v2(v_uvw[2][0], v_uvw[2][1], v_uvw[2][2]);
392 if(t.
isInside(ksi[0], ksi[1], ksi[2]))
return true;
406 for(
int j = 0; j < 3; j++) {
407 double xyz[3] = {
_v[j]->
x(),
_v[j]->
y(),
_v[j]->
z()};
410 MVertex v0(uvw[0][0], uvw[0][1], uvw[0][2]);
411 MVertex v1(uvw[1][0], uvw[1][1], uvw[1][2]);
412 MVertex v2(uvw[2][0], uvw[2][1], uvw[2][2]);
416 for(
int ip = 0; ip < nptsi; ip++) {
417 const double u = ptsi[ip].
pt[0];
418 const double v = ptsi[ip].
pt[1];
419 const double w = ptsi[ip].
pt[2];
438 double uvw[3] = {u, v, w};
440 for(
int i = 0; i < 2; i++) {
442 double v_xyz[3] = {vi->
x(), vi->
y(), vi->
z()};
445 MVertex v0(v_uvw[0][0], v_uvw[0][1], v_uvw[0][2]);
446 MVertex v1(v_uvw[1][0], v_uvw[1][1], v_uvw[1][2]);
450 if(l.
isInside(ksi[0], ksi[1], ksi[2]))
return true;
464 for(
int j = 0; j < 2; j++) {
465 double xyz[3] = {
_v[j]->
x(),
_v[j]->
y(),
_v[j]->
z()};
468 MVertex v0(uvw[0][0], uvw[0][1], uvw[0][2]);
469 MVertex v1(uvw[1][0], uvw[1][1], uvw[1][2]);
472 for(
int ip = 0; ip < nptsi; ip++) {
473 const double u = ptsi[ip].
pt[0];
474 const double v = ptsi[ip].
pt[1];
475 const double w = ptsi[ip].
pt[2];
490 #if defined(HAVE_DINTEGRATION)
493 assignPhysicals(
GModel *GM, std::vector<int> &gePhysicals,
int reg,
int dim,
494 std::map<
int, std::map<int, std::string> > physicals[4],
495 std::map<int, int> &newPhysTags,
int lsTag)
497 for(std::size_t i = 0; i < gePhysicals.size(); i++) {
498 int phys = gePhysicals[i];
500 if(lsTag > 0 && newPhysTags.count(phys)) {
501 int phys2 = newPhysTags[phys];
503 (!physicals[dim].count(reg) || !physicals[dim][reg].count(phys2))) {
505 if(name !=
"" && newPhysTags.count(-phys)) {
506 auto it = physicals[dim].begin();
507 for(; it != physicals[dim].end(); it++) {
508 auto it2 = it->second.begin();
509 for(; it2 != it->second.end(); it2++)
510 if(it2->second == name)
511 physicals[dim][it->first][it2->first] = name +
"_out";
515 physicals[dim][reg][phys2] = name;
518 else if(lsTag < 0 && newPhysTags.count(-phys)) {
519 int phys2 = newPhysTags[-phys];
521 (!physicals[dim].count(reg) || !physicals[dim][reg].count(phys2))) {
523 if(name !=
"" && newPhysTags.count(phys)) {
524 auto it = physicals[dim].begin();
525 for(; it != physicals[dim].end(); it++) {
526 auto it2 = it->second.begin();
527 for(; it2 != it->second.end(); it2++)
528 if(it2->second == name)
529 physicals[dim][it->first][it2->first] = name +
"_in";
533 physicals[dim][reg][phys2] = name;
540 assignLsPhysical(
GModel *GM,
int reg,
int dim,
541 std::map<
int, std::map<int, std::string> > physicals[4],
542 int physTag,
int lsTag)
544 if(!physicals[dim][reg].count(physTag)) {
545 std::stringstream strs;
547 std::string sdim = (dim == 2) ?
"S" :
"L";
548 physicals[dim][reg][physTag] =
"levelset_" + sdim + strs.str();
550 Msg::Info(
"Levelset %d -> physical %d", lsTag, physTag);
554 static int getElementaryTag(
int lsTag,
int elementary,
555 std::map<int, int> &newElemTags)
558 if(newElemTags.count(elementary))
559 return newElemTags[elementary];
561 int reg = ++newElemTags[0];
562 newElemTags[elementary] = reg;
568 static void getPhysicalTag(
int lsTag,
const std::vector<int> &physicals,
569 std::map<int, int> &newPhysTags)
571 for(std::size_t i = 0; i < physicals.size(); i++) {
572 int phys = physicals[i];
574 if(!newPhysTags.count(-phys)) newPhysTags[-phys] = ++newPhysTags[0];
575 phys = newPhysTags[-phys];
577 else if(!newPhysTags.count(phys))
578 newPhysTags[phys] = phys;
582 static int getBorderTag(
int lsTag,
int count,
int &maxTag,
583 std::map<int, int> &borderTags)
585 if(borderTags.count(lsTag))
return borderTags[lsTag];
586 if(count || lsTag < 0) {
588 borderTags[lsTag] = tag;
591 maxTag = std::max(maxTag, lsTag);
592 borderTags[lsTag] = lsTag;
596 static void elementSplitMesh(
599 std::map<int, MVertex *> &vertexMap,
600 std::map<MElement *, MElement *> &newParents,
601 std::map<MElement *, MElement *> &newDomains,
602 std::map<
int, std::vector<MElement *> > elements[10],
603 std::map<
int, std::map<int, std::string> > physicals[4],
604 std::map<int, int> newElemTags[4], std::map<int, int> newPhysTags[4],
605 std::map<int, int> borderElemTags[2], std::map<int, int> borderPhysTags[2])
607 int elementary = ge->
tag();
609 std::vector<int> gePhysicals = ge->
physicals;
610 int iLs = (verticesLs.
size1() == 1) ? 0 : verticesLs.
size1() - 1;
611 int gLsTag = RPN[RPN.size() - 1]->getTag();
615 bool splitElem =
false;
630 if(lsTag * lsTag2 < 0) {
634 for(; ils < verticesLs.
size1() - 1; ils++) {
639 if(lsT1 * lsT2 < 0)
break;
641 for(
int i = 0; i <= ils; i++)
642 if(!RPN[i]->isPrimitive()) ils++;
643 gLsTag = RPN[ils]->getTag();
662 int reg = getElementaryTag(lsTag, elementary, newElemTags[3]);
663 getPhysicalTag(lsTag, gePhysicals, newPhysTags[3]);
665 elements[4][reg].push_back(
copy);
667 elements[5][reg].push_back(
copy);
669 elements[6][reg].push_back(
copy);
671 elements[7][reg].push_back(
copy);
673 elements[9][reg].push_back(
copy);
674 assignPhysicals(GM, gePhysicals, reg, 3, physicals, newPhysTags[3], lsTag);
679 int reg = getElementaryTag(lsTag, elementary, newElemTags[2]);
680 getPhysicalTag(lsTag, gePhysicals, newPhysTags[2]);
682 elements[2][reg].push_back(
copy);
684 elements[3][reg].push_back(
copy);
686 elements[8][reg].push_back(
copy);
687 assignPhysicals(GM, gePhysicals, reg, 2, physicals, newPhysTags[2], lsTag);
690 int reg = getElementaryTag(lsTag, elementary, newElemTags[1]);
691 getPhysicalTag(lsTag, gePhysicals, newPhysTags[1]);
692 elements[1][reg].push_back(
copy);
693 assignPhysicals(GM, gePhysicals, reg, 1, physicals, newPhysTags[1], lsTag);
696 int reg = getElementaryTag(lsTag, elementary, newElemTags[0]);
697 getPhysicalTag(lsTag, gePhysicals, newPhysTags[0]);
698 elements[0][reg].push_back(
copy);
699 assignPhysicals(GM, gePhysicals, reg, 0, physicals, newPhysTags[0], lsTag);
701 default:
Msg::Error(
"This type of element cannot be split.");
return;
705 if(splitElem && e->
getDim() == 2) {
712 double val0 = (verticesLs(iLs, v0->
getIndex()) > eps) ? 1 : -1;
713 double val1 = (verticesLs(iLs, v1->
getIndex()) > eps) ? 1 : -1;
714 if(val0 * val1 > 0.0 && val0 < 0.0) {
715 getPhysicalTag(-1, gePhysicals, newPhysTags[1]);
716 int c = elements[1].count(gLsTag);
717 int reg = getBorderTag(gLsTag,
c, newElemTags[1][0], borderElemTags[0]);
719 (!gePhysicals.size()) ?
721 getBorderTag(gLsTag,
c, newPhysTags[1][0], borderPhysTags[0]);
723 for(i = elements[1][reg].size() - 1; i >= 0; i--) {
731 elements[1][reg].push_back(lin);
732 if(physTag) assignLsPhysical(GM, reg, 1, physicals, physTag, gLsTag);
736 elements[1][reg].erase(elements[1][reg].begin() + i);
742 else if(splitElem && e->
getDim() == 3) {
745 bool sameSign =
true;
751 if(val0 * valj < 0.0) {
756 if(sameSign && val0 < 0.0) {
757 getPhysicalTag(-1, gePhysicals, newPhysTags[2]);
758 int c = elements[2].count(gLsTag) + elements[3].count(gLsTag) +
759 elements[8].count(gLsTag);
760 int reg = getBorderTag(gLsTag,
c, newElemTags[2][0], borderElemTags[1]);
762 (!gePhysicals.size()) ?
764 getBorderTag(gLsTag,
c, newPhysTags[2][0], borderPhysTags[1]);
769 int i = elements[2][reg].size() - 1;
779 elements[2][reg].push_back(tri);
783 elements[2][reg].erase(elements[2][reg].begin() + i);
793 for(i = elements[3][reg].size() - 1; i >= 0; i--) {
803 elements[3][reg].push_back(quad);
807 elements[3][reg].erase(elements[3][reg].begin() + i);
811 if(physTag) assignLsPhysical(GM, reg, 2, physicals, physTag, gLsTag);
817 static bool equalV(
MVertex *v,
const DI_Point *p)
819 return (fabs(v->
x() - p->x()) < 1.e-15 && fabs(v->
y() - p->y()) < 1.e-15 &&
820 fabs(v->
z() - p->z()) < 1.e-15);
823 static int getElementVertexNum(DI_Point *p,
MElement *e)
830 typedef std::set<MVertex *, MVertexPtrLessThanLexicographic>
831 newVerticesContainer;
833 static void elementCutMesh(
836 std::map<int, MVertex *> &vertexMap, newVerticesContainer &newVertices,
837 std::map<MElement *, MElement *> &newParents,
838 std::map<MElement *, MElement *> &newDomains,
839 std::multimap<MElement *, MElement *> borders[2],
840 std::map<
int, std::vector<MElement *> > elements[10],
841 std::map<
int, std::map<int, std::string> > physicals[4],
842 std::map<int, int> newElemTags[4], std::map<int, int> newPhysTags[4],
843 std::map<int, int> borderElemTags[2], std::map<int, int> borderPhysTags[2],
844 DI_Point::Container &cp, std::vector<DI_Line *> &lines,
845 std::vector<DI_Triangle *> &triangles, std::vector<DI_Quad *> &quads,
846 std::vector<DI_Tetra *> &tetras, std::vector<DI_Hexa *> &hexas)
848 int elementary = ge->
tag();
853 std::vector<int> gePhysicals = ge->
physicals;
856 std::vector<DI_IntegrationPoint *> ipV;
857 std::vector<DI_IntegrationPoint *> ipS;
859 std::size_t nbL = lines.size();
860 std::size_t nbTr = triangles.size();
861 std::size_t nbQ = quads.size();
862 std::size_t nbTe = tetras.size();
863 std::size_t nbH = hexas.size();
882 T.setPolynomialOrder(recur + 1);
885 isCut = T.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder,
886 tetras, quads, triangles, recur, nodeLs);
898 H.setPolynomialOrder(recur + 1);
902 H.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder, integOrder,
903 hexas, tetras, quads, triangles, lines, recur, nodeLs);
912 for(
int i = 0; i < 3; i++)
915 bool iC1 = T1.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder,
916 tetras, quads, triangles, recur, nodeLs);
927 bool iC2 = T2.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder,
928 tetras, quads, triangles, recur, nodeLs);
935 for(
int i = 1; i < 4; i++)
937 bool iC3 = T3.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder,
938 tetras, quads, triangles, recur, nodeLs);
939 isCut = iC1 || iC2 || iC3;
948 for(
int i = 0; i < 3; i++)
951 bool iC1 = T1.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder,
952 tetras, quads, triangles, recur, nodeLs);
960 for(
int i = 1; i < 4; i++)
962 bool iC2 = T2.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder,
963 tetras, quads, triangles, recur, nodeLs);
974 Tet.setPolynomialOrder(recur + 1);
977 bool iC =
Tet.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder,
978 tetras, quads, triangles, recur, nodeLs);
979 isCut = (isCut || iC);
984 std::vector<MTetrahedron *> poly[2];
986 for(std::size_t i = nbTe; i < tetras.size(); i++) {
987 MVertex *mv[4] = {
nullptr,
nullptr,
nullptr,
nullptr};
988 for(
int j = 0; j < 4; j++) {
989 int numV = getElementVertexNum(tetras[i]->pt(j), e);
992 new MVertex(tetras[i]->x(j), tetras[i]->y(j), tetras[i]->
z(j));
993 auto it = newVertices.insert(newv);
998 auto it = vertexMap.find(numV);
999 if(it == vertexMap.end()) {
1000 mv[j] =
new MVertex(tetras[i]->x(j), tetras[i]->y(j),
1001 tetras[i]->
z(j),
nullptr, numV);
1002 vertexMap[numV] = mv[j];
1009 if(tetras[i]->lsTag() < 0)
1010 poly[0].push_back(mt);
1012 poly[1].push_back(mt);
1014 bool own = (eParent && !e->
ownsParent()) ?
false :
true;
1015 if(poly[0].size()) {
1017 p1 =
new MPolyhedron(poly[0], n, ePart, own, parent);
1019 int reg = getElementaryTag(-1, elementary, newElemTags[3]);
1020 getPhysicalTag(-1, gePhysicals, newPhysTags[3]);
1021 elements[9][reg].push_back(p1);
1022 assignPhysicals(GM, gePhysicals, reg, 3, physicals, newPhysTags[3], -1);
1024 if(poly[1].size()) {
1027 p2 =
new MPolyhedron(poly[1], n, ePart, own, parent);
1028 getPhysicalTag(1, gePhysicals, newPhysTags[3]);
1029 elements[9][elementary].push_back(p2);
1030 assignPhysicals(GM, gePhysicals, elementary, 3, physicals,
1034 auto itr = borders[1].equal_range(
copy);
1035 std::vector<std::pair<MElement *, MElement *> > bords;
1036 for(
auto it = itr.first; it != itr.second; it++) {
1044 if(match == 3)
break;
1046 MElement *dom = (match == 3) ? p1 : p2;
1048 bords.push_back(std::make_pair(dom, tb));
1050 borders[1].erase(itr.first, itr.second);
1051 for(std::size_t i = 0; i < bords.size(); i++) borders[1].insert(bords[i]);
1053 copy->setParent(
nullptr,
false);
1060 lsTag = hexas[nbH]->lsTag();
1062 lsTag = tetras[nbTe]->lsTag();
1063 int reg = getElementaryTag(lsTag, elementary, newElemTags[3]);
1064 getPhysicalTag(lsTag, gePhysicals, newPhysTags[3]);
1066 elements[4][reg].push_back(
copy);
1068 elements[5][reg].push_back(
copy);
1070 elements[6][reg].push_back(
copy);
1072 elements[7][reg].push_back(
copy);
1074 elements[9][reg].push_back(
copy);
1075 assignPhysicals(GM, gePhysicals, reg, 3, physicals, newPhysTags[3],
1079 for(std::size_t i = nbTr; i < triangles.size(); i++) {
1080 MVertex *mv[3] = {
nullptr,
nullptr,
nullptr};
1081 for(
int j = 0; j < 3; j++) {
1082 int numV = getElementVertexNum(triangles[i]->pt(j), e);
1084 MVertex *newv =
new MVertex(triangles[i]->x(j), triangles[i]->y(j),
1085 triangles[i]->
z(j));
1086 auto it = newVertices.insert(newv);
1087 mv[j] = *(it.first);
1091 auto it = vertexMap.find(numV);
1092 if(it == vertexMap.end()) {
1093 mv[j] =
new MVertex(triangles[i]->x(j), triangles[i]->y(j),
1094 triangles[i]->
z(j),
nullptr, numV);
1095 vertexMap[numV] = mv[j];
1111 tri =
new MTriangle(mv[0], mv[1], mv[2], ++numEle, ePart);
1112 int lsTag = triangles[i]->lsTag();
1113 int cR = elements[2].count(lsTag) + elements[3].count(lsTag) +
1114 elements[8].count(lsTag);
1116 for(
auto it = physicals[2].begin(); it != physicals[2].end(); it++)
1117 for(
auto it2 = it->second.begin(); it2 != it->second.end(); it2++)
1118 if(it2->first == lsTag) {
1123 int reg = getBorderTag(lsTag, cR, newElemTags[2][0], borderElemTags[1]);
1125 (!gePhysicals.size()) ?
1127 getBorderTag(lsTag, cP, newPhysTags[2][0], borderPhysTags[1]);
1128 elements[2][reg].push_back(tri);
1129 if(physTag) assignLsPhysical(GM, reg, 2, physicals, physTag, lsTag);
1130 for(
int i = 0; i < 2; i++)
1132 borders[1].insert(std::make_pair(tri->
getDomain(i), tri));
1143 T.setPolynomialOrder(recur + 1);
1146 isCut = T.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder,
1147 quads, triangles, lines, recur, nodeLs);
1155 Q.setPolynomialOrder(recur + 1);
1158 isCut = Q.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder,
1159 quads, triangles, lines, recur, nodeLs);
1168 Tri.setPolynomialOrder(recur + 1);
1171 bool iC = Tri.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder,
1172 quads, triangles, lines, recur, nodeLs);
1173 isCut = (isCut || iC);
1177 MPolygon *p1 =
nullptr, *p2 =
nullptr;
1179 std::vector<MTriangle *> poly[2];
1181 for(std::size_t i = nbTr; i < triangles.size(); i++) {
1182 MVertex *mv[3] = {
nullptr,
nullptr,
nullptr};
1183 for(
int j = 0; j < 3; j++) {
1184 int numV = getElementVertexNum(triangles[i]->pt(j), e);
1186 MVertex *newv =
new MVertex(triangles[i]->x(j), triangles[i]->y(j),
1187 triangles[i]->
z(j));
1188 auto it = newVertices.insert(newv);
1189 mv[j] = *(it.first);
1193 auto it = vertexMap.find(numV);
1194 if(it == vertexMap.end()) {
1195 mv[j] =
new MVertex(triangles[i]->x(j), triangles[i]->y(j),
1196 triangles[i]->
z(j),
nullptr, numV);
1197 vertexMap[numV] = mv[j];
1204 if(triangles[i]->lsTag() < 0)
1205 poly[0].push_back(mt);
1207 poly[1].push_back(mt);
1210 for(std::size_t i = nbQ; i < quads.size(); i++) {
1211 MVertex *mv[4] = {
nullptr,
nullptr,
nullptr,
nullptr};
1212 for(
int j = 0; j < 4; j++) {
1213 int numV = getElementVertexNum(quads[i]->pt(j), e);
1216 new MVertex(quads[i]->x(j), quads[i]->y(j), quads[i]->
z(j));
1217 auto it = newVertices.insert(newv);
1218 mv[j] = *(it.first);
1222 auto it = vertexMap.find(numV);
1223 if(it == vertexMap.end()) {
1224 mv[j] =
new MVertex(quads[i]->x(j), quads[i]->y(j),
1225 quads[i]->
z(j),
nullptr, numV);
1226 vertexMap[numV] = mv[j];
1234 if(quads[i]->lsTag() < 0) {
1235 poly[0].push_back(mt0);
1236 poly[0].push_back(mt1);
1239 poly[1].push_back(mt0);
1240 poly[1].push_back(mt1);
1244 bool own = (eParent && !e->
ownsParent()) ?
false :
true;
1245 if(poly[0].size()) {
1249 copy->getDomain(0),
copy->getDomain(1));
1251 p1 =
new MPolygon(poly[0], n, ePart, own, parent);
1253 int reg = getElementaryTag(-1, elementary, newElemTags[2]);
1254 getPhysicalTag(-1, gePhysicals, newPhysTags[2]);
1255 elements[8][reg].push_back(p1);
1256 assignPhysicals(GM, gePhysicals, reg, 2, physicals, newPhysTags[2], -1);
1257 for(
int i = 0; i < 2; i++)
1259 borders[1].insert(std::make_pair(p1->
getDomain(i), p1));
1261 if(poly[1].size()) {
1266 copy->getDomain(0),
copy->getDomain(1));
1268 p2 =
new MPolygon(poly[1], n, ePart, own, parent);
1269 getPhysicalTag(1, gePhysicals, newPhysTags[2]);
1270 elements[8][elementary].push_back(p2);
1271 assignPhysicals(GM, gePhysicals, elementary, 2, physicals,
1273 for(
int i = 0; i < 2; i++)
1274 if(p2->getDomain(i))
1275 borders[1].insert(std::make_pair(p2->getDomain(i), p2));
1278 auto itr = borders[0].equal_range(
copy);
1279 std::vector<std::pair<MElement *, MElement *> > bords;
1280 for(
auto it = itr.first; it != itr.second; ++it) {
1287 if(match == 2)
break;
1289 MElement *dom = (match == 2) ? p1 : p2;
1291 bords.push_back(std::make_pair(dom, lb));
1293 borders[0].erase(itr.first, itr.second);
1294 for(std::size_t i = 0; i < bords.size(); i++) borders[0].insert(bords[i]);
1296 copy->setParent(
nullptr,
false);
1303 lsTag = quads[nbQ]->lsTag();
1305 lsTag = triangles[nbTr]->lsTag();
1306 int reg = getElementaryTag(lsTag, elementary, newElemTags[2]);
1307 getPhysicalTag(lsTag, gePhysicals, newPhysTags[2]);
1309 elements[2][reg].push_back(
copy);
1311 elements[3][reg].push_back(
copy);
1313 elements[8][reg].push_back(
copy);
1314 assignPhysicals(GM, gePhysicals, reg, 2, physicals, newPhysTags[2],
1316 for(
int i = 0; i < 2; i++)
1317 if(
copy->getDomain(i))
1318 borders[1].insert(std::make_pair(
copy->getDomain(i),
copy));
1321 for(std::size_t i = nbL; i < lines.size(); i++) {
1322 MVertex *mv[2] = {
nullptr,
nullptr};
1323 for(
int j = 0; j < 2; j++) {
1324 int numV = getElementVertexNum(lines[i]->pt(j), e);
1327 new MVertex(lines[i]->x(j), lines[i]->y(j), lines[i]->
z(j));
1328 auto it = newVertices.insert(newv);
1329 mv[j] = *(it.first);
1333 auto it = vertexMap.find(numV);
1334 if(it == vertexMap.end()) {
1335 mv[j] =
new MVertex(lines[i]->x(j), lines[i]->y(j), lines[i]->
z(j),
1337 vertexMap[numV] = mv[j];
1346 lin =
new MLineBorder(mv[0], mv[1], ++numEle, ePart, p2, p1);
1348 lin =
new MLineBorder(mv[0], mv[1], ++numEle, ePart, p1, p2);
1351 lin =
new MLine(mv[0], mv[1], ++numEle, ePart);
1352 int lsTag = lines[i]->lsTag();
1353 int cR = elements[1].count(lsTag);
1355 for(
auto it = physicals[1].begin(); it != physicals[1].end(); it++)
1356 for(
auto it2 = it->second.begin(); it2 != it->second.end(); it2++)
1357 if(it2->first == lsTag) {
1362 int reg = getBorderTag(lsTag, cR, newElemTags[1][0], borderElemTags[0]);
1364 (!gePhysicals.size()) ?
1366 getBorderTag(lsTag, cP, newPhysTags[1][0], borderPhysTags[0]);
1367 elements[1][reg].push_back(lin);
1368 if(physTag) assignLsPhysical(GM, reg, 1, physicals, physTag, lsTag);
1369 for(
int i = 0; i < 2; i++)
1371 borders[0].insert(std::make_pair(lin->
getDomain(i), lin));
1377 L.setPolynomialOrder(recur + 1);
1380 isCut = L.cut(RPN, ipV, cp, integOrder, lines, recur, nodeLs);
1383 bool own = (eParent && !e->
ownsParent()) ?
false :
true;
1384 for(std::size_t i = nbL; i < lines.size(); i++) {
1385 MVertex *mv[2] = {
nullptr,
nullptr};
1386 for(
int j = 0; j < 2; j++) {
1387 int numV = getElementVertexNum(lines[i]->pt(j), e);
1390 new MVertex(lines[i]->x(j), lines[i]->y(j), lines[i]->
z(j));
1391 auto it = newVertices.insert(newv);
1392 mv[j] = *(it.first);
1396 auto it = vertexMap.find(numV);
1397 if(it == vertexMap.end()) {
1398 mv[j] =
new MVertex(lines[i]->x(j), lines[i]->y(j),
1399 lines[i]->
z(j),
nullptr, numV);
1400 vertexMap[numV] = mv[j];
1409 ml =
new MLineChild(mv[0], mv[1], n, ePart, own, parent);
1412 copy->getDomain(1));
1415 getElementaryTag(lines[i]->lsTag(), elementary, newElemTags[1]);
1416 int lsTag = lines[i]->lsTag();
1417 getPhysicalTag(lsTag, gePhysicals, newPhysTags[1]);
1418 elements[1][reg].push_back(ml);
1419 assignPhysicals(GM, gePhysicals, reg, 1, physicals, newPhysTags[1],
1421 for(
int i = 0; i < 2; i++)
1423 borders[0].insert(std::make_pair(ml->
getDomain(i), ml));
1426 copy->setParent(
nullptr,
false);
1431 int lsTag = lines[nbL]->lsTag();
1432 int reg = getElementaryTag(lsTag, elementary, newElemTags[1]);
1433 getPhysicalTag(lsTag, gePhysicals, newPhysTags[1]);
1434 elements[1][reg].push_back(
copy);
1435 assignPhysicals(GM, gePhysicals, reg, 1, physicals, newPhysTags[1],
1437 for(
int i = 0; i < 2; i++)
1438 if(
copy->getDomain(i))
1439 borders[0].insert(std::make_pair(
copy->getDomain(i),
copy));
1445 P.computeLs(RPN.back());
1446 int lsTag = P.lsTag();
1447 int reg = getElementaryTag(lsTag, elementary, newElemTags[0]);
1448 getPhysicalTag(lsTag, gePhysicals, newPhysTags[0]);
1449 elements[0][reg].push_back(
copy);
1450 assignPhysicals(GM, gePhysicals, reg, 0, physicals, newPhysTags[0], lsTag);
1452 default:
Msg::Error(
"This type of element cannot be cut %d.", eType);
break;
1455 for(std::size_t i = 0; i < ipS.size(); i++)
delete ipS[i];
1456 for(std::size_t i = 0; i < ipV.size(); i++)
delete ipV[i];
1460 #endif // HAVE_DINTEGRATION
1463 std::map<
int, std::vector<MElement *> > elements[10],
1464 std::map<int, MVertex *> &vertexMap,
1465 std::map<
int, std::map<int, std::string> > physicals[4],
1468 #if defined(HAVE_DINTEGRATION)
1473 std::vector<GEntity *> gmEntities;
1476 std::vector<gLevelset *> primitives;
1478 int primS = primitives.size();
1479 std::vector<gLevelset *> RPN;
1482 int nbLs = (primS > 1) ? primS + 1 : 1;
1486 bool lsPoints =
false;
1487 for(
int i = 0; i < primS; i++)
1488 if(primitives[i]->type() ==
LSPOINTS) {
1493 std::vector<MVertex *> vert;
1494 for(std::size_t i = 0; i < gmEntities.size(); i++) {
1495 for(std::size_t j = 0; j < gmEntities[i]->getNumMeshVertices(); j++) {
1496 vert.push_back(gmEntities[i]->getMeshVertex(j));
1499 for(
int k = 0; k < primS; k++) {
1500 if(primitives[k]->type() ==
LSPOINTS) {
1507 for(std::size_t i = 0; i < gmEntities.size(); i++) {
1508 for(std::size_t j = 0; j < gmEntities[i]->getNumMeshVertices(); j++) {
1509 MVertex *vi = gmEntities[i]->getMeshVertex(j);
1512 for(; k < primS; k++)
1514 (*primitives[k])(vi->
x(), vi->
y(), vi->
z());
1516 verticesLs(k, vi->
getIndex()) = (*ls)(vi->
x(), vi->
y(), vi->
z());
1520 vertexMap[vi->
getNum()] = vn;
1525 std::size_t numEle =
1527 for(std::size_t i = 0; i < gmEntities.size(); i++) {
1528 for(std::size_t j = 0; j < gmEntities[i]->getNumMeshElements(); j++) {
1529 MElement *e = gmEntities[i]->getMeshElement(j);
1536 std::map<int, int> newElemTags[4];
1537 std::map<int, int> newPhysTags[4];
1538 for(
int d = 0; d < 4; d++) {
1543 std::map<MElement *, MElement *> newParents;
1544 std::map<MElement *, MElement *> newDomains;
1547 std::map<int, int> borderPhysTags[2];
1551 for(std::size_t i = 0; i < gmEntities.size(); i++) {
1552 for(std::size_t j = 0; j < gmEntities[i]->getNumMeshElements(); j++) {
1553 MElement *e = gmEntities[i]->getMeshElement(j);
1555 elementSplitMesh(e, RPN, verticesLs, gmEntities[i], gm, numEle,
1556 vertexMap, newParents, newDomains, elements, physicals,
1557 newElemTags, newPhysTags, borderElemTags,
1568 newVerticesContainer newVertices;
1570 std::multimap<MElement *, MElement *> borders[2];
1571 DI_Point::Container cp;
1572 std::vector<DI_Line *> lines;
1573 std::vector<DI_Triangle *> triangles;
1574 std::vector<DI_Quad *> quads;
1575 std::vector<DI_Tetra *> tetras;
1576 std::vector<DI_Hexa *> hexas;
1577 std::vector<int> lsLineRegs;
1578 for(std::size_t i = 0; i < gmEntities.size(); i++) {
1579 std::vector<int> oldLineRegs;
1580 for(
auto it = elements[1].begin(); it != elements[1].end(); it++)
1581 oldLineRegs.push_back(it->first);
1582 int nbBorders = borders[0].size();
1583 for(std::size_t j = 0; j < gmEntities[i]->getNumMeshElements(); j++) {
1584 MElement *e = gmEntities[i]->getMeshElement(j);
1586 elementCutMesh(e, RPN, verticesLs, gmEntities[i], gm, numEle, vertexMap,
1587 newVertices, newParents, newDomains, borders, elements,
1588 physicals, newElemTags, newPhysTags, borderElemTags,
1589 borderPhysTags, cp, lines, triangles, quads, tetras,
1597 if((
int)borders[0].size() > nbBorders && gmEntities[i]->dim() == 2 &&
1600 for(
auto it = elements[1].begin(); it != elements[1].end(); it++) {
1601 if(oldLineRegs.size() && it->first == oldLineRegs[k])
1604 lsLineRegs.push_back(it->first);
1606 for(std::size_t j = 0; j < lsLineRegs.size(); j++) {
1607 int nLR = lsLineRegs[j];
1608 bool havePhys = physicals[1][nLR].size();
1610 std::vector<MElement *> conLines;
1611 conLines.push_back(elements[1][nLR][0]);
1612 elements[1][nLR].erase(elements[1][nLR].begin());
1613 MVertex *v1 = conLines[0]->getVertex(0);
1614 MVertex *v2 = conLines[0]->getVertex(1);
1615 for(std::size_t k = 0; k < elements[1][nLR].size();) {
1616 MVertex *va = elements[1][nLR][k]->getVertex(0);
1617 MVertex *vb = elements[1][nLR][k]->getVertex(1);
1618 if(va == v1 || vb == v1 || va == v2 || vb == v2) {
1619 conLines.push_back(elements[1][nLR][k]);
1620 elements[1][nLR].erase(elements[1][nLR].begin() + k);
1634 if(!elements[1][nLR].empty()) {
1635 int newReg = ++newElemTags[1][0];
1636 int newPhys = (!havePhys) ? 0 : ++newPhysTags[1][0];
1638 assignLsPhysical(gm, newReg, 1, physicals, newPhys,
1639 lines[lines.size() - 1]->lsTag());
1640 for(std::size_t k = 0; k < conLines.size(); k++)
1641 elements[1][newReg].push_back(conLines[k]);
1644 for(std::size_t k = 0; k < conLines.size(); k++)
1645 elements[1][nLR].push_back(conLines[k]);
1652 for(
auto it = cp.begin(); it != cp.end(); it++)
delete *it;
1653 for(std::size_t k = 0; k < lines.size(); k++)
delete lines[k];
1654 for(std::size_t k = 0; k < triangles.size(); k++)
delete triangles[k];
1655 for(std::size_t k = 0; k < quads.size(); k++)
delete quads[k];
1656 for(std::size_t k = 0; k < tetras.size(); k++)
delete tetras[k];
1657 for(std::size_t k = 0; k < hexas.size(); k++)
delete hexas[k];
1667 int numElements = 0;
1668 for(
int i = 0; i < 10; i++) {
1669 printf(
" - element type : %d\n", i);
1670 for(
auto it = elements[i].begin(); it != elements[i].end(); it++){
1671 printf(
" elementary : %d\n",it->first);
1672 for(std::size_t j = 0; j < it->second.size(); j++){
1674 printf(
"element %d",e->
getNum());
1678 printf(
"\n"); numElements++;
1683 for(
int i = 0; i < 4; i++)
1684 for(
auto it = physicals[i].begin(); it != physicals[i].end(); it++)
1685 for(
auto it2 = it->second.begin(); it2 != it->second.end(); it2++)
1686 printf(
" dim=%d reg=%d phys=%d \"%s\"\n", i, it->first, it2->first,
1687 it2->second.c_str());
1688 printf(
"new Model : %d elements %d nodes\n\n", numElements, vertexMap.size());
1691 for(
auto it = newVertices.begin(); it != newVertices.end(); ++it) {
1692 vertexMap[(*it)->getNum()] = *it;
1697 Msg::Error(
"Gmsh need to be compiled with levelset support to cut mesh");