15 std::vector<MElement *> &subdomainElements,
16 std::vector<MElement *> &nondomainElements,
17 std::vector<MElement *> &nonsubdomainElements,
18 std::vector<MElement *> &immuneElements,
19 bool saveOriginalComplex)
20 : _model(model), _dim(0), _simplicial(true), _saveorig(saveOriginalComplex),
32 for(
int i = 0; i < 4; i++)
39 for(
int dim = 0; dim < 4; dim++) {
53 Msg::Debug(
" %d volumes, %d faces, %d edges, and %d vertices",
57 Msg::Debug(
" %d volumes, %d faces, %d edges, and %d vertices",
61 Msg::Debug(
" %d volumes, %d faces, %d edges, and %d vertices",
68 std::pair<Cell *, double> smallestElement[4];
69 std::pair<Cell *, double> biggestElement[4];
70 for(
int i = 0; i < 4; i++) {
71 smallestElement[i].second = -1.;
72 biggestElement[i].second = -1.;
78 for(std::size_t i = 0; i < elements.size(); i++) {
83 Msg::Error(
"Mesh element type %d not implemented in homology solver",
90 if(!maybeCell.second) {
91 delete maybeCell.first;
96 Cell *cell = maybeCell.first;
97 std::pair<citer, bool> insert =
_cells[cell->
getDim()].insert(cell);
100 cell = *(insert.first);
107 double size = fabs(
element->getVolume());
108 if(smallestElement[dim].second < 0. || smallestElement[dim].second > size)
109 smallestElement[dim] = std::make_pair(cell, size);
110 if(biggestElement[dim].second < 0. || biggestElement[dim].second < size)
111 biggestElement[dim] = std::make_pair(cell, size);
117 for(
int dim = 3; dim > 0; dim--) {
121 Msg::Info(
" - Creating domain %d-cells", dim);
123 Msg::Info(
" - Creating subdomain %d-cells", dim);
130 if(!maybeCell.second) {
131 delete maybeCell.first;
134 Cell *newCell = maybeCell.first;
135 std::pair<citer, bool> insert =
139 newCell = *(insert.first);
160 if(elements.empty())
return true;
161 Msg::Debug(
"Removing %d elements and their subcells from the cell complex.",
162 (
int)elements.size());
163 std::set<Cell *, CellPtrLessThan> removed[4];
165 for(std::size_t i = 0; i < elements.size(); i++) {
170 Msg::Error(
"Mesh element type %d not implemented in homology solver",
176 auto cit =
_cells[dim].find(cell);
179 removed[dim].insert(cell);
185 for(
int dim = 3; dim > 0; dim--) {
186 for(
auto cit = removed[dim].begin(); cit != removed[dim].end(); cit++) {
191 auto cit2 =
_cells[dim - 1].find(newCell);
194 removed[dim - 1].insert(newCell);
201 for(
int dim = 3; dim >= 0; dim--) {
202 for(
auto cit = removed[dim].begin(); cit != removed[dim].end(); cit++) {
206 Msg::Debug(
"Removed %d volumes, %d faces, %d edges, and %d vertices from the "
208 (
int)removed[3].size(), (
int)removed[2].size(),
209 (
int)removed[1].size(), (
int)removed[0].size());
215 for(std::size_t i = 0; i < elements.size(); i++) {
219 auto cit =
_cells[dim].find(cell);
220 if(cit !=
lastCell(dim)) (*cit)->setImmune(
true);
228 for(
int i = 0; i < 4; i++) {
229 for(
auto cit =
_cells[i].begin(); cit !=
_cells[i].end(); cit++) {
247 std::pair<citer, bool> insertInfo =
_cells[cell->
getDim()].insert(cell);
248 if(!insertInfo.second) {
250 Cell *oldCell = (*insertInfo.first);
258 std::map<Cell *, short int, CellPtrLessThan> coboundary;
260 std::map<Cell *, short int, CellPtrLessThan> boundary;
263 for(
auto it = coboundary.begin(); it != coboundary.end(); it++) {
264 Cell *cbdCell = (*it).first;
268 for(
auto it = boundary.begin(); it != boundary.end(); it++) {
269 Cell *bdCell = (*it).first;
274 int erased =
_cells[dim].erase(cell);
282 Msg::Debug(
"Tried to remove a cell from the cell complex \n");
288 std::map<Cell *, short int, CellPtrLessThan> &cells, std::queue<Cell *> &Q,
289 std::set<Cell *, CellPtrLessThan> &Qset)
291 for(
auto cit = cells.begin(); cit != cells.end(); cit++) {
292 Cell *cell = (*cit).first;
293 auto it = Qset.find(cell);
294 if(it == Qset.end()) {
302 std::vector<Cell *> &omittedCells)
304 int coreductions = 0;
306 std::queue<Cell *> Q;
307 std::set<Cell *, CellPtrLessThan> Qset;
310 Qset.insert(startCell);
312 std::map<Cell *, short int, CellPtrLessThan> bd_s;
313 std::map<Cell *, short int, CellPtrLessThan> cbd_c;
326 bd_s.begin()->first->getCoboundary(cbd_c);
329 if(bd_s.begin()->first->getDim() == omit) {
330 omittedCells.push_back(bd_s.begin()->first);
345 if(dim < 1 || dim > 3)
return 0;
348 for(
int i = 0; i < 4; i++) numCells[i] =
getSize(i);
378 Msg::Debug(
"Cell complex %d-reduction removed %dv, %df, %de, %dn", dim,
385 std::vector<Cell *> &omittedCells)
387 if(dim < 1 || dim > 3)
return 0;
390 for(
int i = 0; i < 4; i++) numCells[i] =
getSize(i);
405 if(dim - 1 == omit) {
419 Msg::Debug(
"Cell complex %d-coreduction removed %dv, %df, %de, %dn", dim,
428 std::size_t size = 0;
430 for(
int i = 0; i < 4; i++) size +=
_cells[i].size();
432 for(
int i = 0; i < 4; i++) size +=
_ocells[i].size();
436 return _cells[dim].size();
450 str =
"relative domain";
465 std::vector<Cell *> omittedCells;
466 omittedCells.push_back(cell);
470 for(
int i = 0; i < 4; i++) numCells[i] =
getSize(i);
473 for(
int j = 3; j > 0; j--)
478 for(
int j = 1; j <=
getDim(); j++)
485 std::string domainstr =
"";
488 Msg::Debug(
"Cell complex %d-omit removed %dv, %df, %de, %dn (total %d)",
506 std::vector<Cell *> empty;
507 for(
int i = 3; i > 0; i--) count = count +
reduction(i, -1, empty);
509 if(omit && !homseq) {
510 std::vector<Cell *> newCells;
516 newCells.push_back(
_omitCell(cell,
false));
519 for(std::size_t i = 0; i < newCells.size(); i++) {
533 for(
int i = 3; i > 0; i--)
reduction(i, -1, empty);
540 for(
int i = 3; i > 0; i--)
reduction(i, -1, empty);
547 for(
int i = 3; i > 0; i--)
reduction(i, -1, empty);
557 std::vector<Cell *> toRemove;
558 for(
int i = 0; i < 4; i++) {
564 for(std::size_t i = 0; i < toRemove.size(); i++)
removeCell(toRemove[i]);
570 if(dim < 0 || dim > 3)
return;
571 std::vector<Cell *> toRemove;
573 toRemove.push_back(*cit);
575 for(std::size_t i = 0; i < toRemove.size(); i++)
removeCell(toRemove[i]);
587 std::vector<Cell *> empty;
588 for(
int dim = 0; dim < 4; dim++) {
593 if(count != 0)
break;
601 std::vector<Cell *> newCells;
608 Msg::Debug(
"Omitted a cell in the smallest mesh element with volume %g",
614 Msg::Debug(
"Omitted a cell in the biggest mesh element with volume %g",
619 newCells.push_back(
_omitCell(cell,
true));
621 for(std::size_t i = 0; i < newCells.size(); i++) {
635 for(
int i = 1; i < 4; i++)
coreduction(i, -1, empty);
642 for(
int i = 1; i < 4; i++)
coreduction(i, -1, empty);
649 for(
int i = 1; i < 4; i++)
coreduction(i, -1, empty);
662 for(
int i = 1; i <= 3; i++)
cocombine(i - 1);
668 if(dim < 1 || dim > 3)
return 0;
671 for(
int i = 0; i < 4; i++) numCells[i] =
getSize(i);
675 std::queue<Cell *> Q;
676 std::set<Cell *, CellPtrLessThan> Qset;
677 std::map<Cell *, short int, CellPtrLessThan> bd_c;
684 Msg::Info(
" - %d volumes, %d faces, %d edges, and %d vertices",
692 while(Q.size() != 0) {
698 int or1 = it->second.get();
701 while(it->second.get() == 0) it++;
702 int or2 = it->second.get();
703 Cell *c2 = it->first;
709 c1->getBoundary(bd_c);
723 if(
c1->isCombined()) {
737 Msg::Debug(
"Cell complex %d-combine removed %dv, %df, %de, %dn", dim,
746 if(dim < 0 || dim > 2)
return 0;
749 for(
int i = 0; i < 4; i++) numCells[i] =
getSize(i);
753 std::queue<Cell *> Q;
754 std::set<Cell *, CellPtrLessThan> Qset;
755 std::map<Cell *, short int, CellPtrLessThan> cbd_c;
762 Msg::Info(
" - %d volumes, %d faces, %d edges, and %d vertices",
771 while(Q.size() != 0) {
776 int or1 = it->second.get();
779 while(it->second.get() == 0) it++;
780 int or2 = it->second.get();
781 Cell *c2 = it->first;
787 c1->getCoboundary(cbd_c);
801 if(
c1->isCombined()) {
815 Msg::Debug(
"Cell complex %d-cocombine removed %dv, %df, %de, %dn", dim,
825 for(
int i = 0; i < 4; i++) {
828 std::map<Cell *, short int, CellPtrLessThan> boundary;
830 for(
auto it = boundary.begin(); it != boundary.end(); it++) {
831 Cell *bdCell = (*it).first;
832 int ori = (*it).second;
835 Msg::Debug(
"Boundary cell not in cell complex! Boundary removed");
840 Msg::Debug(
"Incoherent boundary/coboundary pair! Fixed");
845 std::map<Cell *, short int, CellPtrLessThan> coboundary;
847 for(
auto it = coboundary.begin(); it != coboundary.end(); it++) {
848 Cell *cbdCell = (*it).first;
849 int ori = (*it).second;
852 Msg::Debug(
"Coboundary cell not in cell complex! Coboundary removed");
857 Msg::Debug(
"Incoherent coboundary/boundary pair! Fixed");
886 if((domain == 0 && !cell->
inSubdomain()) || domain == 1 ||
907 if(num < 0)
Msg::Debug(
"Domain cell counts not in sync.");
921 if((domain == 1) || (domain == 0 && !cell->
inSubdomain()) ||
925 Msg::Debug(
"Domain cell counts not in sync.");
941 for(
int i = 0; i < 4; i++) {
942 for(
auto cit =
_cells[i].begin(); cit !=
_cells[i].end(); cit++) {