FVGenericSelection.cpp
1 /*---------------------------------------------------------------------------*\
2  *
3  * mimmo
4  *
5  * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6  *
7  * -------------------------------------------------------------------------
8  * License
9  * This file is part of mimmo.
10  *
11  * mimmo is free software: you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License v3 (LGPL)
13  * as published by the Free Software Foundation.
14  *
15  * mimmo is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with mimmo. If not, see <http://www.gnu.org/licenses/>.
22  *
23  \ *---------------------------------------------------------------------------*/
24 
25 #include "FVMeshSelection.hpp"
26 
27 namespace mimmo {
28 
39  m_topo = std::min(2, std::max(1, topo)); /*default to volume bulk-surface boundary geometry*/
40  m_dual = false; /*default to exact selection*/
41  m_bndgeometry= nullptr;
42  m_selectEngine = nullptr;
43 };
44 
49 
54  m_topo = other.m_topo;
55  m_dual = other.m_dual;
58 };
59 
64  swap(other);
65  return *this;
66 };
67 
74 {
75  std::swap(m_topo, x.m_topo);
76  std::swap(m_dual, x.m_dual);
77  std::swap(m_bndgeometry, x.m_bndgeometry);
78  std::swap(m_selectEngine, x.m_selectEngine);
80 }
81 
85 void
87 
88  bool built = true;
89 
90  built = (built && createPortIn<mimmo::MimmoSharedPointer<MimmoObject>, FVGenericSelection>(this, &FVGenericSelection::setGeometry, M_GEOM, true));
91  built = (built && createPortIn<mimmo::MimmoSharedPointer<MimmoObject>, FVGenericSelection>(this, &FVGenericSelection::setBoundaryGeometry, M_GEOM2, true));
92  built = (built && createPortIn<bool, FVGenericSelection>(this, &FVGenericSelection::setDual,M_VALUEB));
93 
94  built = (built && createPortOut<mimmo::MimmoSharedPointer<MimmoObject>, FVGenericSelection>(this, &FVGenericSelection::getVolumePatch, M_GEOM));
95  built = (built && createPortOut<mimmo::MimmoSharedPointer<MimmoObject>, FVGenericSelection>(this, &FVGenericSelection::getBoundaryPatch, M_GEOM2));
96  built = (built && createPortOut<mimmo::MimmoSharedPointer<MimmoObject>, FVGenericSelection>(this, &FVGenericSelection::getInternalBoundaryPatch, M_GEOM3));
97 
98  m_arePortsBuilt = built;
99 };
100 
106 void
108  if(target == nullptr) return;
109  int type = target->getType();
110  if(m_topo == 1 && type != 2) return;
111  if(m_topo == 2 && type != 1) return;
112  m_geometry = target;
113 };
114 
119 void
121  if(target == nullptr) return;
122  int type = target->getType();
123  if(m_topo == 1 && type != 1) return;
124  if(m_topo == 2 && type != 4) return;
125  m_bndgeometry = target;
126 };
127 
128 
136 void
138  m_dual = flag;
139 }
140 
145 void
147  if(selectBlock == nullptr) return;
148  m_selectEngine = selectBlock;
149 }
150 
151 
158  return m_volpatch;
159 };
160 
167  return m_bndpatch;
168 };
169 
170 
177  return m_intbndpatch;
178 };
179 
186  return m_volpatch;
187 };
188 
195  return m_bndpatch;
196 };
197 
204  return m_intbndpatch;
205 };
206 
207 
208 
213 bool
215  return m_dual;
216 };
217 
218 
223 void
225 
226  if(m_geometry == nullptr || m_bndgeometry == nullptr) {
227  throw std::runtime_error (m_name + " : nullptr pointer to one or both bulk/boundary targets found");
228  return;
229  }
230 
231  if(m_selectEngine == nullptr) {
232  throw std::runtime_error (m_name + " : no valid selection engine found");
233  return;
234  }
235 
237  (*m_log)<<"Warning in "+m_name + " : id-vertex uncoherent bulk/boundary geometry linked"<<std::endl;
238  }
239 
240  //selecting bulk
241  m_selectEngine->setGeometry(m_geometry);
242  m_selectEngine->execute();
243  m_volpatch = m_selectEngine->getPatch();
244 
245  //selecting boundary
246  m_selectEngine->setGeometry(m_bndgeometry);
247  m_selectEngine->execute();
248  m_bndpatch = m_selectEngine->getPatch();
249 
250  //clean up the boundary. THis is necessary since the selection on bulk and boundary
251  // may lead to a situation in which some vertex nodes in the boundary patch selected are not
252  // in the pot of the bulk patch selected
254 
255  //create the internal patch;
257 
258 
259 
260 };
261 
264 void
266  //check boundary subpatch vertices and retain only those inside bulk subpatch.
267  //local cleaning on rank;
268  livector1D boundaryClearedVerts;
269  bitpit::PiercedVector<bitpit::Vertex> & bulkV = m_volpatch->getVertices();
270  boundaryClearedVerts.reserve(m_bndpatch->getNVertices());
271  long id;
272  for(const bitpit::Vertex & vert : m_bndpatch->getVertices()){
273  id = vert.getId();
274  if(bulkV.exists(id)) boundaryClearedVerts.push_back(id);
275  }
276 
277  std::unordered_set<long> survivedCells;
278  {
279  livector1D temp = m_bndpatch->getCellFromVertexList(boundaryClearedVerts, true); // true strictly cell defined by this set.
280  survivedCells.insert(temp.begin(), temp.end());
281  }
282  livector1D toDeleteCells;
283  livector1D bndC = m_bndpatch->getCells().getIds();
284 
285  toDeleteCells.reserve(bndC.size() - survivedCells.size());
286  for(long id: bndC){
287  if(survivedCells.count(id) > 0) continue;
288  toDeleteCells.push_back(id);
289  }
290  toDeleteCells.shrink_to_fit();
291 
292  bool checkAllClean = toDeleteCells.empty();
293 #if MIMMO_ENABLE_MPI
294  MPI_Allreduce(MPI_IN_PLACE, &checkAllClean,1, MPI_C_BOOL, MPI_LAND, m_communicator);
295 #endif
296 
297  if(!checkAllClean){
298  //unsync all mimmoobject tracking structures
299  m_bndpatch->setUnsyncAll();
300  //delete the selected cells
301  m_bndpatch->getPatch()->deleteCells(toDeleteCells);
302 #if MIMMO_ENABLE_MPI
303  //delete possible isolated ghosts
304  m_bndpatch->deleteOrphanGhostCells();
305 #endif
306  //check for orphans vertices and delete it
307  if(m_bndpatch->getPatch()->countOrphanVertices() > 0){
308  m_bndpatch->getPatch()->deleteOrphanVertices();
309  }
310  m_bndpatch->getPatch()->squeezeVertices();
311  m_bndpatch->getPatch()->squeezeCells();
312 
313  m_bndpatch->update();
314  }
315 }
316 
317 
324 
325  //get the vertices retained by the real boundary
326  livector1D realBoundaryVertices = m_bndpatch->getVertices().getIds();
327 
328  //check interfaces of volpatch
329  bool resetVolInterfaces = (m_volpatch->getInterfacesSyncStatus() == SyncStatus::NONE);
330  m_volpatch->updateInterfaces();
331 
332  MimmoSharedPointer<MimmoObject> m_patch = m_volpatch->extractBoundaryMesh();
333 
334  if(resetVolInterfaces){
335  m_volpatch->destroyInterfaces();
336  }
337 
338  //remove cells shared with the real boundary, from this "internal" pot.
339  livector1D sharedCells = m_patch->getCellFromVertexList(realBoundaryVertices, true); //strict=true means cells defined by this vertices list.
340 
341  //unsync all mimmoobject tracking structures
342  m_patch->setUnsyncAll();
343  //delete cells and orphans.
344  m_patch->getPatch()->deleteCells(sharedCells);
345 #if MIMMO_ENABLE_MPI
346  m_patch->deleteOrphanGhostCells();
347 #endif
348  if(m_patch->getPatch()->countOrphanVertices() > 0){
349  m_patch->getPatch()->deleteOrphanVertices();
350  }
351  m_patch->getPatch()->squeezeVertices();
352  m_patch->getPatch()->squeezeCells();
353 
354  m_patch->update();
355 
356  return m_patch;
357 }
362 void
364 
365  std::string originalname = m_name;
366  if(getVolumePatch()){
367  m_name = originalname + "_Volume_Patch";
369  }
370  if(getBoundaryPatch()){
371  m_name = originalname + "_Boundary_Patch";
373  }
375  m_name = originalname + "_InternalBoundary_Patch";
377  }
378  m_name = originalname;
379 
380 }
381 
385 bool
387 
388  m_geometry->update();
389  m_bndgeometry->update();
390 
391  //check if boundary and bulk are globally empty or not.
392  std::array<bool,2> emptyCompound = {{m_geometry->isEmpty(), m_bndgeometry->isEmpty()}};
393 #if MIMMO_ENABLE_MPI
394  MPI_Allreduce(MPI_IN_PLACE, &emptyCompound,2, MPI_C_BOOL, MPI_LAND, m_communicator);
395 #endif
396  //if they differ return false.
397  if(emptyCompound[0] != emptyCompound[1]) return false;
398 
399  bool check = true;
400  //analyze vertices
401  livector1D boundaryIds = m_bndgeometry->getVerticesIds(true); //only internals nodes.
402  std::unordered_set<long> bulkset;
403  {
404  livector1D bulkIds = m_geometry->extractBoundaryVertexID(false); //only rank internals
405  bulkset.insert(bulkIds.begin(), bulkIds.end());
406  }
407  if(!boundaryIds.empty()){
408  for(long id: boundaryIds){
409  check = check && (bulkset.count(id) > 0);
410  }
411  }
412 
413 #if MIMMO_ENABLE_MPI
414  MPI_Allreduce(MPI_IN_PLACE, &check, 1, MPI_C_BOOL, MPI_LAND, m_communicator);
415 #endif
416 
417 
418  return check;
419 }
420 
421 }
void setDual(bool flag=false)
MimmoSharedPointer< MimmoObject > m_intbndpatch
MimmoSharedPointer< MimmoObject > m_bndgeometry
#define M_GEOM
MimmoSharedPointer< MimmoObject > createInternalBoundaryPatch()
Interface for applying selection methods simultaneously on bulk+boundary compound meshes.
FVGenericSelection & operator=(FVGenericSelection other)
std::vector< long > livector1D
#define M_GEOM2
BaseManipulation is the base class of any manipulation object of the library.
void setBoundaryGeometry(mimmo::MimmoSharedPointer< MimmoObject >)
MimmoSharedPointer< MimmoObject > m_bndpatch
void write(MimmoSharedPointer< MimmoObject > geometry)
const mimmo::MimmoSharedPointer< MimmoObject > getBoundaryPatch() const
MimmoSharedPointer< GenericSelection > m_selectEngine
MimmoSharedPointer< MimmoObject > m_geometry
#define M_GEOM3
MimmoSharedPointer< MimmoObject > m_volpatch
void setSelection(MimmoSharedPointer< GenericSelection > selectBlock)
const mimmo::MimmoSharedPointer< MimmoObject > getInternalBoundaryPatch() const
const mimmo::MimmoSharedPointer< MimmoObject > getVolumePatch() const
MimmoSharedPointer is a custom implementation of shared pointer.
void swap(BaseManipulation &x) noexcept
void setGeometry(mimmo::MimmoSharedPointer< MimmoObject >)
#define M_VALUEB
void swap(FVGenericSelection &x) noexcept