10 #include "GmshConfig.h"
46 #if defined(HAVE_MESH)
60 #if defined(HAVE_POST)
65 #if defined(HAVE_KBIPACK)
73 : _name(name), _visible(1), _elementOctree(nullptr),
74 _geo_internals(nullptr), _occ_internals(nullptr), _acis_internals(nullptr),
75 _parasolid_internals(nullptr), _fields(nullptr),
76 _currentMeshEntity(nullptr), _numPartitions(0), normals(nullptr),
94 #if defined(HAVE_MESH)
101 auto it = std::find(
list.begin(),
list.end(),
this);
102 if(it !=
list.end())
list.erase(it);
106 bool othervisible =
false;
107 for(std::size_t i = 0; i <
list.size(); i++) {
110 if(!othervisible &&
list.size())
list.back()->setVisibility(1);
118 #if defined(HAVE_MESH)
139 Msg::Debug(
"No current model available: creating one");
143 if(_current < 0 || _current >= (
int)
list.size())
return list.back();
149 for(std::size_t i = 0; i <
list.size(); i++) {
161 for(
int i =
list.size() - 1; i >= 0; i--)
163 (fileName.empty() || !
list[i]->hasFileName(fileName)))
187 std::set<GRegion *, GEntityPtrLessThan>().swap(
regions);
191 std::set<GFace *, GEntityPtrLessThan>().swap(
faces);
195 std::set<GEdge *, GEntityPtrLessThan>().swap(
edges);
199 std::set<GVertex *, GEntityPtrLessThan>().swap(
vertices);
208 #if defined(HAVE_MESH)
250 if(entities.empty()) {
254 for(std::size_t i = 0; i < entities.size(); i++) {
259 std::vector<GEdge *> e = ge->
edges();
260 for(
auto it = e.begin(); it != e.end(); ++it) {
261 if((*it)->getNumMeshElements()) {
268 std::vector<GFace *>
f = ge->
faces();
269 for(
auto it =
f.begin(); it !=
f.end(); ++it) {
270 if((*it)->getNumMeshElements()) {
277 std::list<GRegion *> r = ge->
regions();
278 for(
auto it = r.begin(); it != r.end(); ++it) {
279 if((*it)->getNumMeshElements()) {
288 Msg::Warning(
"Cannot delete mesh of entity (%d, %d), connected to mesh "
289 "of higher dimensional entity",
302 (*it)->deleteVertexArrays();
304 (*it)->deleteVertexArrays();
306 (*it)->deleteVertexArrays();
308 (*it)->deleteVertexArrays();
330 if(it !=
faces.end())
340 if(it !=
edges.end())
421 const std::string &name)
423 std::vector<int>
tags;
424 std::map<int, std::vector<GEntity *> > physicalGroups;
426 std::vector<GEntity *> entities =
428 for(
auto it = entities.begin(); it != entities.end(); it++) {
440 std::vector<GFace *>
f = r->
faces();
441 for(
auto it =
f.begin(); it !=
f.end(); it++) (*it)->delRegion(r);
452 if(it !=
faces.end()) {
454 std::vector<GEdge *>
const &e =
f->edges();
455 for(
auto it = e.begin(); it != e.end(); it++) (*it)->delFace(
f);
466 if(it !=
edges.end()) {
495 if(
remove(gr)) removed.push_back(gr);
497 std::vector<GFace *>
f = gr->
faces();
498 for(
auto it =
f.begin(); it !=
f.end(); it++)
499 remove(2, (*it)->tag(), removed, recursive);
508 std::vector<GFace *>
f = (*it)->faces();
509 if(std::find(
f.begin(),
f.end(), gf) !=
f.end()) {
513 auto ef = (*it)->embeddedFaces();
514 if(std::find(ef.begin(), ef.end(), gf) != ef.end()) {
520 if(
remove(gf)) removed.push_back(gf);
522 std::vector<GEdge *>
const &e = gf->
edges();
523 for(
auto it = e.begin(); it != e.end(); it++)
524 remove(1, (*it)->tag(), removed, recursive);
534 auto ee = (*it)->embeddedEdges();
535 if(std::find(ee.begin(), ee.end(), ge) != ee.end()) {
542 std::vector<GEdge *>
const &e = (*it)->edges();
543 if(std::find(e.begin(), e.end(), ge) != e.end()) {
547 auto ee = (*it)->embeddedEdges();
548 if(std::find(ee.begin(), ee.end(), ge) != ee.end()) {
555 if(
remove(ge)) removed.push_back(ge);
578 auto ev = (*it)->embeddedVertices();
579 if(std::find(ev.begin(), ev.end(), gv) != ev.end()) {
587 auto ev = (*it)->embeddedVertices();
588 if(std::find(ev.begin(), ev.end(), gv) != ev.end()) {
595 if(
remove(gv)) removed.push_back(gv);
602 std::vector<GEntity*> &removed,
bool recursive)
604 for(std::size_t i = 0; i < dimTags.size(); i++)
605 remove(dimTags[i].first, dimTags[i].second, removed, recursive);
625 std::vector<GEdge *>
const &
edges = (*vit)->edges();
626 for(
auto it =
edges.begin(); it !=
edges.end(); ++it) {
629 if((*it)->getBeginVertex() == *vit) { t = parb.
low(); }
630 else if((*it)->getEndVertex() == *vit) {
634 Msg::Error(
"Weird point: impossible to snap");
637 GPoint gp = (*it)->point(t);
638 double d = sqrt((gp.
x() - (*vit)->x()) * (gp.
x() - (*vit)->x()) +
639 (gp.
y() - (*vit)->y()) * (gp.
y() - (*vit)->y()) +
640 (gp.
z() - (*vit)->z()) * (gp.
z() - (*vit)->z()));
642 (*vit)->setPosition(gp);
643 Msg::Info(
"Snapping geometry point %d to curve (distance = %g)",
658 case 1: entities.insert(entities.end(),
edges.begin(),
edges.end());
break;
659 case 2: entities.insert(entities.end(),
faces.begin(),
faces.end());
break;
665 entities.insert(entities.end(),
edges.begin(),
edges.end());
666 entities.insert(entities.end(),
faces.begin(),
faces.end());
676 std::vector<GEntity *> all;
679 for(std::size_t i = 0; i < all.size(); i++) {
681 if(bbox.
min().
x() >=
box.min().x() && bbox.
max().
x() <=
box.max().x() &&
682 bbox.
min().
y() >=
box.min().y() && bbox.
max().
y() <=
box.max().y() &&
683 bbox.
min().
z() >=
box.min().z() && bbox.
max().
z() <=
box.max().z())
684 entities.push_back(all[i]);
692 if(std::abs(i1) < std::abs(i2))
return true;
698 std::vector<std::pair<int, int> > &outDimTags,
699 bool combined,
bool oriented,
bool recursive)
702 for(std::size_t i = 0; i < inDimTags.size(); i++) {
703 int dim = inDimTags[i].first;
704 int tag = std::abs(inDimTags[i].second);
705 bool reverse = (inDimTags[i].second < 0);
710 std::vector<GVertex *>
const &vert = gr->
vertices();
711 for(
auto it = vert.begin(); it != vert.end(); it++)
712 outDimTags.push_back(std::make_pair(0, (*it)->tag()));
717 auto ito = orientations.begin();
718 for(
auto it =
faces.begin(); it !=
faces.end(); it++) {
719 int t = (*it)->tag();
720 if(oriented && ito != orientations.end()) {
724 outDimTags.push_back(std::make_pair(2, t));
729 Msg::Error(
"Unknown model region with tag %d", tag);
737 std::vector<GVertex *>
const &vert = gf->
vertices();
738 for(
auto it = vert.begin(); it != vert.end(); it++)
739 outDimTags.push_back(std::make_pair(0, (*it)->tag()));
742 std::vector<GEdge *>
const &
edges = gf->
edges();
744 auto ito = orientations.begin();
745 for(
auto it =
edges.begin(); it !=
edges.end(); it++) {
746 int t = (*it)->tag();
747 if(oriented && ito != orientations.end()) {
751 outDimTags.push_back(std::make_pair(1, t));
756 Msg::Error(
"Unknown model face with tag %d", tag);
765 outDimTags.push_back(
768 outDimTags.push_back(
773 outDimTags.push_back(
776 outDimTags.push_back(
781 Msg::Error(
"Unknown model curve with tag %d", tag);
787 if(gv && recursive) {
788 outDimTags.push_back(std::make_pair(0, gv->
tag()));
795 std::set<int, AbsIntLessThan>
c[3];
796 for(std::size_t i = 0; i < outDimTags.size(); i++) {
797 int dim = outDimTags[i].first;
798 int tag = outDimTags[i].second;
799 if(dim >= 0 && dim < 3) {
800 auto it =
c[dim].find(tag);
801 if(it ==
c[dim].end())
809 for(
int dim = 0; dim < 3; dim++) {
810 for(
auto it =
c[dim].begin(); it !=
c[dim].end(); it++)
811 outDimTags.push_back(std::make_pair(dim, *it));
819 std::vector<GEntity *> entities;
822 for(std::size_t i = 0; i < entities.size(); i++)
823 if(dim < 0 || entities[i]->dim() == dim)
824 num = std::max(num, std::abs(entities[i]->tag()));
830 std::vector<GEntity *> entities;
832 for(std::size_t i = 0; i < entities.size(); i++)
833 if(entities[i]->physicals.size())
return false;
838 std::map<
int, std::vector<GEntity *> > groups[4])
const
840 std::vector<GEntity *> entities;
842 for(std::size_t i = 0; i < entities.size(); i++) {
843 std::map<int, std::vector<GEntity *> > &group(groups[entities[i]->dim()]);
844 for(std::size_t j = 0; j < entities[i]->physicals.size(); j++) {
847 int p = std::abs(entities[i]->physicals[j]);
848 group[p].push_back(entities[i]);
851 for(
int dim = 0; dim < 4; ++dim) {
852 std::map<int, std::vector<GEntity *> > &group(groups[dim]);
853 for(
auto it = group.begin(); it != group.end(); ++it) {
854 std::vector<GEntity *> &v = it->second;
862 int dim, std::map<
int, std::vector<GEntity *> > &groups)
const
864 std::vector<GEntity *> entities;
866 for(std::size_t i = 0; i < entities.size(); i++) {
867 for(std::size_t j = 0; j < entities[i]->physicals.size(); j++) {
870 int p = std::abs(entities[i]->physicals[j]);
871 groups[p].push_back(entities[i]);
874 for(
auto it = groups.begin(); it != groups.end(); ++it) {
875 std::vector<GEntity *> &v = it->second;
886 ge->
physicals.push_back((t > 0) ? tag : -tag);
888 Msg::Warning(
"Unknown entity of dimension %d and tag %d in physical "
889 "group %d", dim, t, tag);
895 std::vector<GEntity *> entities;
897 for(std::size_t i = 0; i < entities.size(); i++)
898 entities[i]->physicals.clear();
905 std::vector<GEntity *> entities;
907 for(std::size_t i = 0; i < entities.size(); i++) {
909 for(std::size_t j = 0; j < entities[i]->physicals.size(); j++)
910 if(std::abs(entities[i]->physicals[j]) != tag)
911 p.push_back(entities[i]->physicals[j]);
912 entities[i]->physicals = p;
919 std::vector<GEntity *> entities;
922 for(std::size_t i = 0; i < entities.size(); i++)
923 if(dim < 0 || entities[i]->dim() == dim)
924 for(std::size_t j = 0; j < entities[i]->physicals.size(); j++)
925 num = std::max(num, std::abs(entities[i]->physicals[j]));
934 iterators[physIt->first.first] = physIt;
941 if(findPhy != -1)
return findPhy;
945 _physicalNames.insert(std::make_pair(std::make_pair(dim, number), name));
957 return _physicalNames.insert(pos, std::make_pair(std::make_pair(dim, number),
972 if(it->second == name)
983 if(dim == physIt->first.first && name == physIt->second)
984 return physIt->first.second;
1018 if(it->second == name)
1028 std::vector<GEntity *> entities;
1031 for(std::size_t i = 0; i < entities.size(); i++) {
1032 entities[i]->setSelection(val);
1036 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++)
1038 entities[i]->getMeshElement(j)->setVisibility(1);
1045 std::vector<GEntity *> entities;
1048 for(std::size_t i = 0; i < entities.size(); i++) {
1051 bb += entities[i]->bounds();
1055 if(entities[i]->dim() == 0)
1056 bb +=
static_cast<GVertex *
>(entities[i])->xyz();
1058 for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
1059 bb += entities[i]->mesh_vertices[j]->point();
1068 #if defined(HAVE_MESH)
1075 std::vector<std::pair<int, int> > newPhysicals;
1089 for(std::size_t i = 0; i < (*it)->getNumMeshElements(); ++i)
1090 if(!(*it)->getMeshElement(i)->setVolumePositive()) ok =
false;
1095 addToMap(std::multimap<MFace, MElement *, MFaceLessThan> &faceToElement,
1096 std::map<
MElement *, std::vector<std::pair<MElement *, bool> > >
1100 auto fit = faceToElement.find(face);
1101 if(fit == faceToElement.end()) {
1102 faceToElement.insert(std::make_pair(face, el));
1105 faceToElement.insert(std::make_pair(face, el));
1106 if(faceToElement.count(face) > 2) {
1108 "Topological fault: Face sharing two other faces. Element %i. "
1109 "Number of nodes %i. Count of faces: %i Three first nodes %i %i %i",
1115 MFace outFace = fit->first;
1116 std::vector<std::pair<MElement *, bool> > &neigh = elToNeighbors[el];
1117 for(
size_t iN = 0; iN < neigh.size(); iN++)
1118 if(neigh[iN].first == fit->second)
1123 bool sameOrientation =
1125 neigh.push_back(std::make_pair(fit->second, !sameOrientation));
1126 elToNeighbors[fit->second].push_back(std::make_pair(el, !sameOrientation));
1132 std::map<
MElement *, std::vector<std::pair<MElement *, bool> > >
1136 int connectivity = faceToElement.count(face);
1139 if(connectivity != 2)
1140 Msg::Error(
"Non conforming trihedron %i (nb connections for a face %i)",
1141 el->
getNum(), faceToElement.count(face));
1145 if(connectivity != 2) {
1151 Msg::Error(
"Non conforming element %i (%i connection(s) for a face "
1152 "located on dim %i (vertex %i))",
1153 el->
getNum(), connectivity,
1163 Msg::Info(
"Orienting volumes according to topology");
1164 std::map<MElement *, std::vector<std::pair<MElement *, bool> > >
1166 std::multimap<MFace, MElement *, MFaceLessThan> faceToElement;
1170 for(std::size_t iEl = 0; iEl < (*it)->getNumMeshElements(); ++iEl) {
1171 el = (*it)->getMeshElement(iEl);
1172 for(
int iFace = 0; iFace < el->
getNumFaces(); iFace++) {
1178 for(std::size_t iEl = 0; iEl < (*it)->getNumMeshElements(); ++iEl) {
1179 el = (*it)->getMeshElement(iEl);
1180 for(
int iFace = 0; iFace < el->
getNumFaces(); iFace++) {
1185 std::vector<std::pair<MElement *, bool> > queue;
1186 std::set<MElement *> queued;
1187 if((*
regions.begin())->tetrahedra.size() == 0) {
1189 "setAllVolumePositiveTopology needs at least one tetrahedron to start");
1192 el = (*
regions.begin())->tetrahedra[0];
1193 queue.push_back(std::make_pair(el,
true));
1194 for(
size_t i = 0; i < queue.size(); i++) {
1195 el = queue[i].first;
1196 if(!queue[i].second) {
1201 const std::vector<std::pair<MElement *, bool> > &neigh = elToNeighbors[el];
1202 for(
size_t iN = 0; iN < neigh.size(); iN++)
1203 if(queued.count(neigh[iN].first) == 0) {
1205 std::make_pair(neigh[iN].first, neigh[iN].second == queue[i].second));
1210 queued.insert(neigh[iN].first);
1217 #if defined(HAVE_MESH)
1233 std::vector<std::vector<double> > parameters,
int niter,
1276 #if defined(HAVE_MESH)
1290 Msg::Info(
" - Adapt mesh (all dimensions) iter. = %d", ITER);
1293 for(std::size_t imetric = 0; imetric < technique.size(); imetric++) {
1294 metric->
addMetric(technique[imetric],
f[imetric], parameters[imetric]);
1311 sprintf(name,
"meshAdapt-%d.msh", ITER);
1315 if(ITER++ >= niter)
break;
1316 if(ITER > 3 && fabs((
double)(nbElems - nbElemsOld)) < 0.01 * nbElemsOld)
1319 nbElemsOld = nbElems;
1324 Msg::Info(
" - Adapt mesh iter. = %d ", ITER);
1325 std::vector<MElement *> elements;
1329 if((*fit)->quadrangles.size())
return -1;
1330 for(
unsigned i = 0; i < (*fit)->triangles.size(); i++) {
1331 elements.push_back((*fit)->triangles[i]);
1337 if((*rit)->hexahedra.size())
return -1;
1338 for(
unsigned i = 0; i < (*rit)->tetrahedra.size(); i++) {
1339 elements.push_back((*rit)->tetrahedra[i]);
1344 if(elements.size() == 0)
return -1;
1348 for(std::size_t imetric = 0; imetric < technique.size(); imetric++) {
1349 metric->
addMetric(technique[imetric],
f[imetric], parameters[imetric]);
1372 sprintf(name,
"meshAdapt-%d.msh", ITER);
1376 if(++ITER >= niter)
break;
1377 if(ITER > 3 && fabs((
double)(nbElems - nbElemsOld)) < 0.01 * nbElemsOld)
1380 nbElemsOld = nbElems;
1404 #if defined(HAVE_MESH)
1405 if(!barycentric) {
RefineMesh(
this, linear, splitIntoQuads, splitIntoHexas); }
1423 #if defined(HAVE_MESH)
1439 #if defined(HAVE_MESH)
1456 #if defined(HAVE_MESH)
1458 SetOrderN(
this, order, linear, incomplete, onlyVisible);
1476 std::size_t numEle3D = 0;
1477 bool toMesh3D =
false;
1484 if(countDiscrete && numEle3D)
return 3;
1489 if(numEle3D && toMesh3D)
return 3;
1491 std::size_t numEle2D = 0;
1492 bool toMesh2D =
false, meshDone2D =
true;
1497 if(countDiscrete && numEle2D)
return 2;
1505 if(numEle2D && toMesh2D && meshDone2D)
return 2;
1507 std::size_t numEle1D = 0;
1508 bool toMesh1D =
false, meshDone1D =
true;
1513 if(countDiscrete && numEle1D)
return 1;
1521 if(numEle1D && toMesh1D && meshDone1D)
return 1;
1524 if((*it)->mesh_vertices.size())
return 0;
1531 std::vector<GEntity *> entities;
1534 for(std::size_t i = 0; i < entities.size(); i++)
1535 if(entities[i]->dim() == dim || dim < 0)
1536 n += entities[i]->getNumMeshVertices();
1542 std::vector<GEntity *> entities;
1545 for(std::size_t i = 0; i < entities.size(); i++)
1546 if(entities[i]->dim() == dim || dim < 0)
1547 n += entities[i]->getNumMeshElements();
1553 std::vector<GEntity *> entities;
1556 for(std::size_t i = 0; i < entities.size(); i++)
1563 std::pair<MEdge, std::size_t> key(std::move(edge),
1565 std::pair<hashmapMEdge::iterator, bool> it =
_mapEdgeNum.insert(std::move(key));
1566 return it.first->second;
1585 std::pair<MFace, std::size_t> key(std::move(face),
1587 std::pair<hashmapMFace::iterator, bool> it =
_mapFaceNum.insert(std::move(key));
1588 return it.first->second;
1606 #if defined(HAVE_POST)
1610 for(std::size_t i = 0; i <
PView::list.size(); i++) {
1613 if(d && d->
getType() == type) {
1627 std::vector<GEntity *> entities;
1630 #if defined(HAVE_POST)
1633 std::map<MVertex *, int> old;
1634 std::vector<stepData<double> *> data;
1637 for(std::size_t i = 0; i < entities.size(); i++) {
1649 bool saveOnlyPhysicals =
false;
1651 for(std::size_t i = 0; i < entities.size(); i++) {
1652 if(entities[i]->physicals.size()) {
1653 saveOnlyPhysicals =
true;
1661 if(saveOnlyPhysicals || pruneOrphans) {
1662 Msg::Debug(
"Renumbering for potentially partial mesh save");
1667 for(std::size_t i = 0; i < entities.size(); i++) {
1671 for(std::size_t i = 0; i < entities.size(); i++) {
1677 for(std::size_t i = 0; i < entities.size(); i++) {
1679 if(!((pruneOrphans && ge->
isOrphan()) ||
1680 (saveOnlyPhysicals && ge->
physicals.empty()))) {
1689 for(std::size_t i = 0; i < entities.size(); i++) {
1696 for(std::size_t i = 0; i < entities.size(); i++) {
1706 for(std::size_t i = 0; i < entities.size(); i++) {
1714 #if defined(HAVE_POST)
1717 int n = data.size();
1718 Msg::Info(
"Renumbering nodal model data (%d step%s)", n, n > 1 ?
"s" :
"");
1719 std::map<int, int> remap;
1720 for(std::size_t i = 0; i < entities.size(); i++) {
1724 remap[old[v]] = v->
getNum();
1727 for(
auto d : data) { d->renumberData(remap); }
1736 std::vector<GEntity *> entities;
1739 #if defined(HAVE_POST)
1742 std::map<MElement *, int> old;
1743 std::vector<stepData<double> *> data[2];
1746 if(data[0].size() || data[1].size()) {
1747 for(std::size_t i = 0; i < entities.size(); i++) {
1759 bool saveOnlyPhysicals =
false;
1761 for(std::size_t i = 0; i < entities.size(); i++) {
1762 if(entities[i]->physicals.size()) {
1763 saveOnlyPhysicals =
true;
1771 if(saveOnlyPhysicals || pruneOrphans) {
1772 for(std::size_t i = 0; i < entities.size(); i++) {
1774 if(!((pruneOrphans && ge->
isOrphan()) ||
1775 (saveOnlyPhysicals && ge->
physicals.empty()))) {
1781 for(std::size_t i = 0; i < entities.size(); i++) {
1783 if(((pruneOrphans && ge->
isOrphan()) ||
1784 (saveOnlyPhysicals && ge->
physicals.empty()))) {
1793 for(std::size_t i = 0; i < entities.size(); i++) {
1801 #if defined(HAVE_POST)
1803 if(data[0].size() || data[1].size()) {
1804 int n = data[0].size() + data[1].size();
1805 Msg::Info(
"Renumbering element model data (%d step%s)", n,
1807 std::map<int, int> remap;
1808 for(std::size_t i = 0; i < entities.size(); i++) {
1812 remap[old[e]] = e->
getNum();
1815 for(
int i = 0; i < 2; i++) {
1816 for(
auto d : data[i]) { d->renumberData(remap); }
1831 (*it)->getNumMeshElements(
c);
1832 if(
c[0] +
c[1] +
c[2] +
c[3] +
c[4] +
c[5])
return 3;
1834 (*it)->getNumMeshElements(
c);
1835 if(
c[0] +
c[1] +
c[2])
return 2;
1837 (*it)->getNumMeshElements(
c);
1849 Msg::Debug(
"Rebuilding mesh element octree");
1855 double xyz[3] = {p.
x(), p.
y(), p.
z()}, uvw[3];
1872 Msg::Debug(
"Rebuilding mesh element octree");
1881 if(!onlyIfNecessary ||
1887 Msg::Debug(
"We have a dense node numbering in the cache");
1892 "We have a fairly dense node numbering - still using cache vector");
1895 std::vector<GEntity *> entities;
1900 for(std::size_t i = 0; i < entities.size(); i++)
1901 for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
1903 entities[i]->mesh_vertices[j];
1906 for(std::size_t i = 0; i < entities.size(); i++)
1907 for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
1909 entities[i]->mesh_vertices[j];
1916 if(!onlyIfNecessary ||
1923 Msg::Debug(
"We have a dense element numbering in the cache");
1928 "We have a fairly dense element numbering - still using cache vector");
1931 std::vector<GEntity *> entities;
1936 for(std::size_t i = 0; i < entities.size(); i++)
1937 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
1938 MElement *e = entities[i]->getMeshElement(j);
1940 std::make_pair(e, entities[i]->tag());
1944 for(std::size_t i = 0; i < entities.size(); i++)
1945 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
1946 MElement *e = entities[i]->getMeshElement(j);
1977 #pragma omp critical
1988 std::vector<MVertex *> &v)
1991 std::map<int, std::vector<GEntity *> > groups;
1993 std::map<int, std::vector<GEntity *> >::const_iterator it = groups.find(num);
1994 if(it == groups.end())
return;
1995 const std::vector<GEntity *> &entities = it->second;
1996 std::set<MVertex *, MVertexPtrLessThan> sv;
1997 for(std::size_t i = 0; i < entities.size(); i++) {
1998 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
1999 MElement *e = entities[i]->getMeshElement(j);
2004 v.insert(v.begin(), sv.begin(), sv.end());
2018 std::pair<MElement*, int> ret;
2023 entityTag = ret.second;
2044 std::vector<T *> tmp;
2045 std::size_t n = elements.size();
2046 for(std::size_t i = 0; i < n; i++) {
2047 if(all || !elements[i]->getVisibility())
2050 tmp.push_back(elements[i]);
2054 return n - elements.size();
2061 bool all = !(*it)->getVisibility();
2068 (*it)->deleteVertexArrays();
2071 bool all = !(*it)->getVisibility();
2075 (*it)->deleteVertexArrays();
2078 bool all = !(*it)->getVisibility();
2080 (*it)->deleteVertexArrays();
2091 std::vector<T *> tmp;
2092 for(std::size_t i = 0; i < elements.size(); i++) {
2093 if(all || !elements[i]->getVisibility()) {
2094 elements[i]->reverse();
2095 elements[i]->setVisibility(1);
2106 bool all = !(*it)->getVisibility();
2113 (*it)->deleteVertexArrays();
2114 if(all) (*it)->setVisibility(1);
2117 bool all = !(*it)->getVisibility();
2121 (*it)->deleteVertexArrays();
2122 if(all) (*it)->setVisibility(1);
2125 bool all = !(*it)->getVisibility();
2127 (*it)->deleteVertexArrays();
2128 if(all) (*it)->setVisibility(1);
2138 std::vector<GEntity *> entities;
2142 for(std::size_t i = 0; i < entities.size(); i++)
2143 for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++)
2144 entities[i]->mesh_vertices[j]->setIndex(-1);
2150 for(std::size_t i = 0; i < entities.size(); i++) {
2151 if(all || entities[i]->physicals.size() ||
2152 (entities[i]->getParentEntity() &&
2153 entities[i]->getParentEntity()->physicals.size())) {
2154 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
2155 MElement *e = entities[i]->getMeshElement(j);
2157 if(singlePartition <= 0 || e->getPartition() == singlePartition)
2167 std::size_t numVertices = 0;
2169 for(std::size_t i = 0; i < entities.size(); i++) {
2170 for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++) {
2171 MVertex *v = entities[i]->mesh_vertices[j];
2191 std::vector<GEntity *> entities;
2193 for(std::size_t i = 0; i < entities.size(); i++)
2194 for(std::size_t j = 0; j < entities[i]->mesh_vertices.size(); j++) {
2195 MVertex *v = entities[i]->mesh_vertices[j];
2204 #pragma omp atomic write
2209 int numPart, std::vector<std::pair<MElement *, int> > elementPartition)
2211 #if defined(HAVE_MESH) && (defined(HAVE_METIS))
2214 if(elementPartition.empty())
2221 Msg::Error(
"Mesh or Metis module not compiled");
2228 #if defined(HAVE_MESH)
2238 #if defined(HAVE_MESH) && (defined(HAVE_METIS))
2242 Msg::Error(
"Mesh or Metis module not compiled");
2248 std::map<
int, std::vector<MElement *> > &entityMap,
2249 std::map<
int, std::map<int, std::string> > &physicalMap)
2253 std::map<int, std::vector<MElement *> >::iterator it;
2254 for(it = entityMap.begin(); it != entityMap.end(); it++) {
2268 const std::vector<MElement *> &src)
2270 for(std::size_t i = 0; i < src.size(); i++) dst.push_back((T *)src[i]);
2274 std::map<
int, std::vector<MElement *> > &map)
2276 std::map<int, std::vector<MElement *> >::const_iterator it = map.begin();
2277 for(; it != map.end(); ++it) {
2278 if(!it->second.size())
continue;
2279 int type = it->second[0]->getType();
2284 double x = it->second[0]->getVertex(0)->x();
2285 double y = it->second[0]->getVertex(0)->y();
2286 double z = it->second[0]->getVertex(0)->z();
2299 e =
new discreteEdge(
this, it->first,
nullptr,
nullptr);
2348 std::map<
int, std::vector<MElement *> > &map)
2350 std::map<int, std::vector<MElement *> >::const_iterator it;
2351 for(it = map.begin(); it != map.end(); ++it)
2352 for(std::size_t i = 0; i < it->second.size(); ++i)
2353 it->second[i]->updateParent(
this);
2358 std::vector<T *> &elements,
2361 for(std::size_t i = 0; i < elements.size(); i++) {
2362 for(std::size_t j = 0; j < elements[i]->getNumVertices(); j++) {
2363 if(force || !elements[i]->getVertex(j)->onWhat() ||
2364 elements[i]->getVertex(j)->onWhat()->dim() > ge->
dim())
2365 elements[i]->getVertex(j)->setEntity(ge);
2371 const std::vector<std::pair<int, int> > &dimTags)
2373 std::vector<discreteEdge *> e;
2374 std::vector<discreteFace *>
f;
2375 std::vector<discreteRegion *> r;
2377 if(dimTags.empty()) {
2380 if(de) e.push_back(de);
2384 if(
df)
f.push_back(
df);
2388 if(dr) r.push_back(dr);
2392 for(std::size_t i = 0; i < dimTags.size(); i++) {
2393 int dim = dimTags[i].first;
2394 int tag = dimTags[i].second;
2400 Msg::Error(
"No discrete curve with tag %d", tag);
2407 Msg::Error(
"No discrete surface with tag %d", tag);
2415 Msg::Error(
"No discrete volume with tag %d", tag);
2423 for(std::size_t i = 0; i < e.size(); i++) {
2424 if(e[i]->createGeometry())
2425 Msg::Error(
"Could not create geometry of discrete curve %d",
2430 "Done creating geometry of discrete curves "
2431 "(Wall %gs, CPU %gs)",
2436 Msg::StatusBar(
true,
"Creating geometry of discrete surfaces...");
2439 for(std::size_t i = 0; i <
f.size(); i++) {
2441 if(
f[i]->createGeometry())
2442 Msg::Error(
"Could not create geometry of discrete surface %d",
2449 "Done creating geometry of discrete surfaces "
2450 "(Wall %gs, CPU %gs)",
2455 Msg::StatusBar(
true,
"Creating geometry of discrete volumes...");
2457 for(std::size_t i = 0; i < r.size(); i++) {
2458 if(r[i]->createGeometry())
2459 Msg::Error(
"Could not create geometry of discrete volume %d",
2464 "Done creating geometry of discrete volumes "
2465 "(Wall %gs, CPU %gs)",
2499 for(; it !=
vertices.end(); ++it) {
2513 for(std::size_t i = 0; i <
vertices.size(); i++) {
2529 std::vector<GEntity *> entities;
2530 std::set<MVertex *, MVertexPtrLessThan> vertSet;
2532 for(std::size_t i = 0; i < entities.size(); i++) {
2533 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
2534 MElement *e = entities[i]->getMeshElement(j);
2541 entities[i]->mesh_vertices.clear();
2543 std::vector<MVertex *>
vertices(vertSet.begin(), vertSet.end());
2569 int dim, std::map<
int, std::map<int, std::string> > &map)
2571 std::map<int, std::map<int, std::string> >::const_iterator it = map.begin();
2572 for(; it != map.end(); ++it) {
2582 for(
auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
2587 if(it2->second.size() && it2->second !=
"unnamed")
2589 std::make_pair(std::make_pair(dim, it2->first), it2->second));
2600 Msg::StatusBar(
true,
"Checking mesh coherence (%d elements)...", numEle);
2606 std::vector<GEntity *> entities;
2611 Msg::Info(
"Checking for duplicate nodes...");
2613 for(std::size_t i = 0; i < entities.size(); i++)
2615 entities[i]->mesh_vertices.end());
2617 std::set<MVertex *, MVertexPtrLessThan> duplicates;
2620 Msg::Error(
"%d duplicate node%s: see `duplicate_node.pos'", num,
2621 num > 1 ?
"s" :
"");
2622 FILE *fp =
Fopen(
"duplicate_nodes.pos",
"w");
2624 fprintf(fp,
"View \"duplicate vertices\"{\n");
2625 for(
auto it = duplicates.begin(); it != duplicates.end(); it++) {
2627 fprintf(fp,
"SP(%.16g,%.16g,%.16g){%lu};\n", v->
x(), v->
y(), v->
z(),
2630 fprintf(fp,
"};\n");
2638 Msg::Info(
"Checking for duplicate elements...");
2640 for(std::size_t i = 0; i < entities.size(); i++) {
2641 for(std::size_t j = 0; j < entities[i]->getNumMeshElements(); j++) {
2642 MElement *e = entities[i]->getMeshElement(j);
2645 Msg::Warning(
"Element %d of dimension %d on entity %d has negative "
2646 "volume", e->
getNum(), e->
getDim(), entities[i]->tag());
2647 else if(vol < eps * eps * eps)
2648 Msg::Warning(
"Element %d of dimension %d on entity %d has zero volume",
2657 if(num)
Msg::Error(
"%d duplicate element%s", num, num > 1 ?
"s" :
"");
2662 Msg::Info(
"Checking for isolated nodes...");
2663 std::vector<GEntity *> entities2;
2665 std::set<MVertex *, MVertexPtrLessThan> allv;
2666 for(std::size_t i = 0; i < entities2.size(); i++) {
2667 for(std::size_t j = 0; j < entities2[i]->getNumMeshElements(); j++) {
2668 MElement *e = entities2[i]->getMeshElement(j);
2676 Msg::Warning(
"%d node%s not connected to any %dD elements", diff,
2685 const std::vector<GEntity*> &ents)
2695 std::vector<GEntity*> entities(ents);
2702 for(std::size_t i = 0; i < entities.size(); i++) {
2712 std::map<MVertex *, MVertex *> duplicates;
2713 for(std::size_t i = 0; i < entities.size(); i++) {
2725 int num = (int)duplicates.size();
2726 Msg::Info(
"Found %d duplicate nodes ", num);
2733 for(std::size_t i = 0; i < entities.size(); i++) {
2741 auto it = duplicates.find(e->
getVertex(k));
2742 if(it != duplicates.end()) e->
setVertex(k, it->second);
2747 if(corrVtcs.size()) {
2748 std::map<MVertex *, MVertex *>::iterator cIter;
2749 for(cIter = duplicates.begin(); cIter != duplicates.end(); ++cIter) {
2750 MVertex *oldTgt = cIter->first;
2751 MVertex *newTgt = cIter->second;
2752 auto cvIter = corrVtcs.find(oldTgt);
2753 if(cvIter != corrVtcs.end()) {
2754 MVertex *src = cvIter->second;
2755 corrVtcs.erase(cvIter);
2756 corrVtcs[newTgt] = src;
2759 for(cIter = corrVtcs.begin(); cIter != corrVtcs.end(); ++cIter) {
2760 MVertex *oldSrc = cIter->second;
2761 auto nIter = duplicates.find(oldSrc);
2762 if(nIter != duplicates.end()) {
2764 MVertex *newSrc = nIter->second;
2765 corrVtcs[tgt] = newSrc;
2776 std::vector<MVertex *> to_delete;
2777 for(
auto it = duplicates.begin(); it != duplicates.end(); it++)
2778 to_delete.push_back(it->first);
2779 for(std::size_t i = 0; i < to_delete.size(); i++)
delete to_delete[i];
2786 Msg::Info(
"Removed %d duplicate mesh node%s", num, num > 1 ?
"s" :
"");
2797 std::vector<GEntity*> entities(ents);
2800 for(
auto &e : entities) {
2801 std::vector<int> types;
2802 e->getElementTypes(types);
2803 for(
auto t : types) {
2804 std::set<MElement*, MElementPtrLessThanVertices> uniq;
2805 for(std::size_t i = 0; i < e->getNumMeshElementsByType(t); i++) {
2806 MElement *ele = e->getMeshElementByType(t, i);
2809 int diff = e->getNumMeshElementsByType(t) - uniq.size();
2812 Msg::Info(
"Removed %d duplicate element%s in entity %d of dimension %d",
2813 diff, diff > 1 ?
"s" :
"", e->tag(), e->dim());
2814 e->removeElements(t);
2815 for(
auto ele : uniq) e->addElement(t, ele);
2842 if(src !=
nullptr && src != tgt) {
2845 std::map<MEdge, MLine *, MEdgeLessThan> srcLines;
2849 Msg::Debug(
"Master element %d is not a line",
2870 for(
int iVtx = 0; iVtx < 2; iVtx++) {
2875 auto srcIter = v2v.find(tgtVtx);
2876 if(srcIter == v2v.end() || !srcIter->second) {
2877 srcIter = geV2v.find(tgtVtx);
2878 if(srcIter == geV2v.end() || !srcIter->second) {
2880 "Could not find periodic counterpart of node %d on curve %d "
2881 "or on entity %d of dimension %d",
2886 tgtVtcs[iVtx] = srcIter->second;
2889 tgtVtcs[iVtx] = srcIter->second;
2892 MEdge tgtEdge(tgtVtcs[0], tgtVtcs[1]);
2894 auto sIter = srcLines.find(tgtEdge);
2896 if(sIter == srcLines.end() || !sIter->second) {
2898 "Could not find periodic counterpart of mesh edge %d-%d on "
2899 "curve %d for mesh edge %d-%d on curve %d",
2905 MLine *srcLine = sIter->second;
2918 if(src !=
nullptr && src != tgt) {
2919 std::map<MFace, MElement *, MFaceLessThan> srcElmts;
2924 if(
dynamic_cast<MTriangle *
>(srcElmt)) nbVtcs = 3;
2925 if(
dynamic_cast<MQuadrangle *
>(srcElmt)) nbVtcs = 4;
2926 std::vector<MVertex *> vtcs;
2927 vtcs.reserve(nbVtcs);
2928 for(
int iVtx = 0; iVtx < nbVtcs; iVtx++) {
2929 vtcs.push_back(srcElmt->
getVertex(iVtx));
2931 srcElmts[
MFace(vtcs)] = srcElmt;
2940 if(tgtTri) nbVtcs = 3;
2941 if(tgtQua) nbVtcs = 4;
2943 std::vector<MVertex *> vtcs;
2944 for(
int iVtx = 0; iVtx < nbVtcs; iVtx++) {
2951 auto vIter = v2v.find(vtx);
2952 if(vIter == v2v.end() || !vIter->second) {
2953 vIter = geV2v.find(vtx);
2954 if(vIter == geV2v.end() || !vIter->second) {
2955 Msg::Debug(
"Could not find periodic counterpart of node %d in "
2956 "surface %d or in entity %d of dimension %d",
2961 vtcs.push_back(vIter->second);
2964 vtcs.push_back(vIter->second);
2966 MFace tgtFace(vtcs);
2968 auto mIter = srcElmts.find(tgtFace);
2969 if(mIter == srcElmts.end()) {
2970 std::ostringstream faceDef;
2971 for(
int iVtx = 0; iVtx < nbVtcs; iVtx++) {
2972 faceDef << vtcs[iVtx]->getNum() <<
" ";
2974 Msg::Debug(
"Could not find periodic counterpart of mesh face %s in "
2975 "surface %d connected to surface %d",
2976 faceDef.str().c_str(), tgt->
tag(), src->
tag());
2980 const MFace &srcFace = mIter->first;
2982 std::vector<MVertex *> srcVtcs;
2984 if((tgtTri && !
dynamic_cast<MTriangle *
>(srcElmt)) ||
2985 (tgtQua && !
dynamic_cast<MQuadrangle *
>(srcElmt))) {
2986 Msg::Error(
"Invalid source/target elements");
2995 "Could not find correspondence between mesh face %d-%d-%d "
2996 "(slave) and %d-%d-%d (master)",
3009 Msg::Debug(
"Done aligning periodic boundaries");
3013 const MFace &
f, std::multimap<MFace, MElement *, MFaceLessThan> &e2f,
3014 std::set<MElement *> &group, std::set<MFace, MFaceLessThan> &touched,
3018 std::stack<MFace> _stack;
3021 while(!_stack.empty()) {
3022 MFace ff = _stack.top();
3024 if(touched.find(ff) == touched.end()) {
3026 for(
auto it = e2f.lower_bound(ff); it != e2f.upper_bound(ff); ++it) {
3027 group.insert(it->second);
3028 for(
int i = 0; i < it->second->getNumFaces(); ++i) {
3029 _stack.push(it->second->getFace(i));
3037 std::vector<std::vector<MElement *> > ®s)
3039 std::multimap<MFace, MElement *, MFaceLessThan> e2f;
3040 for(std::size_t i = 0; i < elements.size(); ++i) {
3041 for(
int j = 0; j < elements[i]->getNumFaces(); j++) {
3042 e2f.insert(std::make_pair(elements[i]->getFace(j), elements[i]));
3045 while(!e2f.empty()) {
3046 std::set<MElement *> group;
3047 std::set<MFace, MFaceLessThan> touched;
3049 std::vector<MElement *> temp;
3050 temp.insert(temp.begin(), group.begin(), group.end());
3051 regs.push_back(temp);
3052 for(
auto it = touched.begin(); it != touched.end(); ++it) e2f.erase(*it);
3058 const MEdge &e, std::multimap<MEdge, MElement *, MEdgeLessThan> &e2e,
3059 std::set<MElement *> &group, std::set<MEdge, MEdgeLessThan> &touched)
3062 std::stack<MEdge> _stack;
3065 while(!_stack.empty()) {
3066 MEdge ee = _stack.top();
3068 if(touched.find(ee) == touched.end()) {
3070 for(
auto it = e2e.lower_bound(ee); it != e2e.upper_bound(ee); ++it) {
3071 group.insert(it->second);
3072 for(
int i = 0; i < it->second->getNumEdges(); ++i) {
3073 _stack.push(it->second->getEdge(i));
3081 std::vector<std::vector<MElement *> > &
faces)
3083 std::multimap<MEdge, MElement *, MEdgeLessThan> e2e;
3084 for(std::size_t i = 0; i < elements.size(); ++i) {
3085 for(
int j = 0; j < elements[i]->getNumEdges(); j++) {
3086 e2e.insert(std::make_pair(elements[i]->getEdge(j), elements[i]));
3089 while(!e2e.empty()) {
3090 std::set<MElement *> group;
3091 std::set<MEdge, MEdgeLessThan> touched;
3093 std::vector<MElement *> temp;
3094 temp.insert(temp.begin(), group.begin(), group.end());
3095 faces.push_back(temp);
3096 for(
auto it = touched.begin(); it != touched.end(); ++it) e2e.erase(*it);
3098 return faces.size();
3103 Msg::Info(
"Making discrete regions simply connected...");
3105 std::vector<discreteRegion *> discRegions;
3110 std::set<MVertex *> touched;
3112 for(
auto itR = discRegions.begin(); itR != discRegions.end(); itR++) {
3113 std::vector<MElement *> allElements((*itR)->getNumMeshElements());
3114 for(std::size_t i = 0; i < (*itR)->getNumMeshElements(); i++)
3115 allElements[i] = (*itR)->getMeshElement(i);
3117 std::vector<std::vector<MElement *> > conRegions;
3119 if(nbRegions > 1)
remove(*itR);
3121 for(
int ire = 0; ire < nbRegions; ire++) {
3126 std::vector<MElement *> myElements = conRegions[ire];
3127 std::set<MVertex *> myVertices;
3128 for(std::size_t i = 0; i < myElements.size(); i++) {
3130 std::vector<MVertex *> verts;
3132 for(std::size_t k = 0; k < verts.size(); k++) {
3133 if(verts[k]->onWhat() && verts[k]->onWhat()->dim() == 3) {
3134 if(touched.find(verts[k]) == touched.end()) {
3135 verts[k]->setEntity(r);
3136 myVertices.insert(verts[k]);
3137 touched.insert(verts[k]);
3157 Msg::Info(
"Done making discrete regions simply connected");
3162 Msg::Info(
"Making discrete faces simply connected...");
3164 std::vector<discreteFace *> discFaces;
3169 std::set<MVertex *> touched;
3171 for(
auto itF = discFaces.begin(); itF != discFaces.end(); itF++) {
3172 std::vector<MElement *> allElements((*itF)->getNumMeshElements());
3173 for(std::size_t i = 0; i < (*itF)->getNumMeshElements(); i++)
3174 allElements[i] = (*itF)->getMeshElement(i);
3176 std::vector<std::vector<MElement *> > conFaces;
3178 if(nbFaces > 1)
remove(*itF);
3180 for(
int ifa = 0; ifa < nbFaces; ifa++) {
3184 std::vector<MElement *> myElements = conFaces[ifa];
3185 std::set<MVertex *> myVertices;
3186 for(std::size_t i = 0; i < myElements.size(); i++) {
3188 std::vector<MVertex *> verts;
3190 for(std::size_t k = 0; k < verts.size(); k++) {
3191 if(verts[k]->onWhat() && verts[k]->onWhat()->dim() == 2) {
3192 if(touched.find(verts[k]) == touched.end()) {
3193 verts[k]->setEntity(
f);
3194 myVertices.insert(verts[k]);
3195 touched.insert(verts[k]);
3207 f->mesh_vertices.insert(
f->mesh_vertices.begin(), myVertices.begin(),
3212 Msg::Info(
"Done making discrete faces simply connected");
3219 Msg::Info(
"Make simply connected regions and surfaces");
3220 std::vector<int> regs;
3221 for(
auto it = elements[4].begin(); it != elements[4].end(); it++)
3222 regs.push_back(it->first);
3223 std::multimap<MFace, MElement *, MFaceLessThan> f2e;
3224 if(regs.size() > 2) {
3225 for(std::size_t i = 0; i < regs.size(); i++) {
3226 for(std::size_t j = 0; j < elements[4][regs[i]].size(); j++) {
3227 MElement *el = elements[4][regs[i]][j];
3229 f2e.insert(std::make_pair(el->
getFace(k), el));
3233 for(std::size_t i = 0; i < regs.size(); i++) {
3235 std::vector<MElement *> allElements;
3236 for(std::size_t j = 0; j < elements[4][ri].size(); j++)
3237 allElements.push_back(elements[4][ri][j]);
3238 std::vector<std::vector<MElement *> > conRegions;
3240 Msg::Info(
"%d connected regions (reg=%d)", nbConRegions, ri);
3241 std::size_t maxNumEl = 1;
3242 for(
int j = 0; j < nbConRegions; j++)
3243 if(conRegions[j].size() > maxNumEl) maxNumEl = conRegions[j].size();
3244 for(
int j = 0; j < nbConRegions; j++) {
3246 if(conRegions[j].size() < maxNumEl * 1.e-4) {
3249 if(regs.size() == 2)
3252 for(std::size_t k = 0; k < conRegions[j].size(); k++) {
3256 auto itl = f2e.lower_bound(mf);
3257 for(; itl != f2e.upper_bound(mf); itl++) {
3258 if(itl->second != el)
break;
3261 bool sameRegion =
false;
3262 for(std::size_t m = 0; m < conRegions[j].size(); m++)
3263 if(conRegions[j][m] == el2) {
3267 if(sameRegion)
continue;
3268 for(std::size_t m = 0; m < regs.size(); m++) {
3270 if(rm == ri)
continue;
3271 for(std::size_t n = 0; n < elements[4][rm].size(); n++)
3272 if(elements[4][rm][n] == el2) {
3283 Msg::Warning(
"Element not found for simply connected regions");
3286 for(std::size_t k = 0; k < conRegions[j].size(); k++) {
3289 for(; l < elements[4][ri].size(); l++)
3290 if(elements[4][ri][l] == el)
break;
3291 elements[4][ri].erase(elements[4][ri].begin() + l);
3292 elements[4][r2].push_back(el);
3298 std::vector<int>
faces;
3299 for(
auto it = elements[2].begin(); it != elements[2].end(); it++)
3300 faces.push_back(it->first);
3301 std::multimap<MEdge, MElement *, MEdgeLessThan> e2e;
3302 if(
faces.size() > 2) {
3303 for(std::size_t i = 0; i <
faces.size(); i++) {
3304 for(std::size_t j = 0; j < elements[2][
faces[i]].size(); j++) {
3307 e2e.insert(std::make_pair(el->
getEdge(k), el));
3311 for(std::size_t i = 0; i <
faces.size(); i++) {
3313 std::vector<MElement *> allElements;
3314 for(std::size_t j = 0; j < elements[2][fi].size(); j++)
3315 allElements.push_back(elements[2][fi][j]);
3316 std::vector<std::vector<MElement *> > conSurfaces;
3318 Msg::Info(
"%d connected surfaces (reg=%d)", nbConSurfaces, fi);
3319 std::size_t maxNumEl = 1;
3320 for(
int j = 0; j < nbConSurfaces; j++)
3321 if(conSurfaces[j].size() > maxNumEl) maxNumEl = conSurfaces[j].size();
3322 for(
int j = 0; j < nbConSurfaces; j++) {
3324 if(conSurfaces[j].size() < maxNumEl * 1.e-4) {
3327 if(
faces.size() == 2)
3330 for(std::size_t k = 0; k < conSurfaces[j].size(); k++) {
3334 auto itl = e2e.lower_bound(me);
3335 for(; itl != e2e.upper_bound(me); itl++) {
3336 if(itl->second != el)
break;
3339 bool sameSurface =
false;
3340 for(std::size_t m = 0; m < conSurfaces[j].size(); m++)
3341 if(conSurfaces[j][m] == el2) {
3345 if(sameSurface)
continue;
3346 for(std::size_t m = 0; m <
faces.size(); m++) {
3348 if(fm == fi)
continue;
3349 for(std::size_t n = 0; n < elements[2][fm].size(); n++)
3350 if(elements[2][fm][n] == el2) {
3361 Msg::Warning(
"Element not found for simply connected surfaces");
3363 for(std::size_t k = 0; k < conSurfaces[j].size(); k++) {
3366 for(; l < elements[2][fi].size(); l++)
3367 if(elements[2][fi][l] == el)
break;
3368 elements[2][fi].erase(elements[2][fi].begin() + l);
3369 elements[2][f2].push_back(el);
3383 std::map<int, std::vector<MElement *> > elements[11];
3384 std::map<int, std::map<int, std::string> > physicals[4];
3385 std::map<int, MVertex *> vertexMap;
3394 buildCutMesh(
this, ls, elements, vertexMap, physicals, cutElem);
3398 for(
int i = 0; i < (int)(
sizeof(elements) /
sizeof(elements[0])); i++)
3403 for(
int i = 0; i < 4; i++) {
3405 auto it = physicals[i].begin();
3406 for(; it != physicals[i].end(); it++) {
3407 auto it2 = it->second.begin();
3408 for(; it2 != it->second.end(); it2++)
3409 if(it2->second !=
"")
3456 std::vector<GEntity *> entities;
3458 for(std::size_t i = 0; i < entities.size(); i++)
3459 entities[i]->addPhysicalEntity(PhysicalNumber);
3464 std::vector<double> p1,
3465 std::vector<double> p2)
3467 if(p1.size() != 3 || p2.size() != 3)
return;
3473 bool forReparametrization,
3474 double curveAngleThreshold)
3476 classifyFaces(
this, angleThreshold, includeBoundary, forReparametrization,
3477 curveAngleThreshold);
3481 const std::vector<int> &domain,
3482 const std::vector<int> &subdomain,
3483 const std::vector<int> &dim)
3485 std::pair<const std::vector<int>,
const std::vector<int> > p(domain,
3487 std::pair<const std::string, const std::vector<int> > p2(type, dim);
3498 newPhysicals.clear();
3502 #if defined(HAVE_KBIPACK)
3507 typedef std::pair<const std::vector<int>,
const std::vector<int> > dpair;
3508 typedef std::pair<const std::string, const std::vector<int> > tpair;
3509 std::set<dpair> domains;
3511 domains.insert(it->first);
3512 Msg::Info(
"Number of cell complexes to construct: %d", domains.size());
3514 for(
auto it = domains.begin(); it != domains.end(); it++) {
3515 std::pair<std::multimap<dpair, tpair>::iterator,
3516 std::multimap<dpair, tpair>::iterator>
3518 bool prepareToRestore = (itp.first != --itp.second);
3520 std::vector<int> imdomain;
3521 Homology *homology =
3522 new Homology(
this, itp.first->first.first, itp.first->first.second,
3523 imdomain, prepareToRestore);
3525 for(
auto itt = itp.first; itt != itp.second; itt++) {
3526 std::string type = itt->second.first;
3527 std::vector<int> dim0 = itt->second.second;
3529 for(
int i = 0; i <
getDim(); i++) dim0.push_back(i);
3530 std::vector<int> dim;
3532 std::stringstream ss;
3533 for(std::size_t i = 0; i < dim0.size(); i++) {
3535 if(d >= 0 && d <=
getDim()) {
3538 if(type ==
"Homology") ss <<
"_";
3539 if(type ==
"Cohomology") ss <<
"^";
3541 if(i < dim0.size() - 1 && dim0.at(i + 1) >= 0 &&
3542 dim0.at(i + 1) <=
getDim())
3546 std::string dims = ss.str();
3548 if(type !=
"Homology" && type !=
"Cohomology" && type !=
"Betti") {
3549 Msg::Error(
"Unknown type of homology computation: %s", type.c_str());
3551 else if(dim.empty()) {
3552 Msg::Error(
"Invalid homology computation dimensions given");
3554 else if(type ==
"Betti") {
3555 homology->findBettiNumbers();
3557 else if(type ==
"Homology" && !homology->isHomologyComputed(dim)) {
3558 homology->findHomologyBasis(dim);
3559 Msg::Info(
"Homology space basis chains to save: %s", dims.c_str());
3560 for(std::size_t i = 0; i < dim.size(); i++) {
3561 std::vector<int> p = homology->addChainsToModel(dim.at(i));
3562 for(
auto t : p) newPhysicals.push_back({dim.at(i), t});
3565 else if(type ==
"Cohomology" && !homology->isCohomologyComputed(dim)) {
3566 homology->findCohomologyBasis(dim);
3567 Msg::Info(
"Cohomology space basis cochains to save: %s", dims.c_str());
3568 for(std::size_t i = 0; i < dim.size(); i++) {
3569 std::vector<int> p = homology->addCochainsToModel(dim.at(i));
3570 for(
auto t : p) newPhysicals.push_back({dim.at(i), t});
3581 "Done homology and cohomology computation "
3582 "(Wall %gs, CPU %gs)",
3586 Msg::Error(
"Homology computation requires KBIPACK");
3592 #if defined(HAVE_HXT) && defined(HAVE_P4EST)
3594 int myId = fields->
newId();
3595 fields->
newField(myId, std::string(
"AutomaticMeshSizeField"));
3598 Msg::Error(
"Size field computation requires both HXT and P4EST");
3602 #if !defined(HAVE_ACIS)
3610 Msg::Error(
"Gmsh must be compiled with ACIS support to load '%s'",
3617 #if !defined(HAVE_PARASOLID)
3625 Msg::Error(
"Gmsh must be compiled with Parasolid support to read '%s'",
3632 Msg::Error(
"Gmsh must be compiled with Parasolid support to write '%s'",
3639 Msg::Error(
"Gmsh must be compiled with Parasolid support to read '%s'",
3646 Msg::Error(
"Gmsh must be compiled with Parasolid support to write '%s'",