27#include <unordered_map>
28#include <unordered_set>
29#if BITPIT_ENABLE_MPI==1
33#include "bitpit_CG.hpp"
34#include "bitpit_common.hpp"
36#include "patch_info.hpp"
37#include "patch_kernel.hpp"
38#include "patch_manager.hpp"
51#if BITPIT_ENABLE_MPI==1
82 : m_adaptionMode(adaptionMode)
83#if BITPIT_ENABLE_MPI==1
84 , m_partitioningMode(partitioningMode)
88#if BITPIT_ENABLE_MPI==1
89 initialize(communicator, haloSize);
98#if BITPIT_ENABLE_MPI==1
131 : m_adaptionMode(adaptionMode)
132#if BITPIT_ENABLE_MPI==1
133 , m_partitioningMode(partitioningMode)
137#if BITPIT_ENABLE_MPI==1
138 initialize(communicator, haloSize);
150#if BITPIT_ENABLE_MPI==1
185 : m_adaptionMode(adaptionMode)
186#if BITPIT_ENABLE_MPI==1
187 , m_partitioningMode(partitioningMode)
191#if BITPIT_ENABLE_MPI==1
192 initialize(communicator, haloSize);
214 m_vertices(other.m_vertices),
215 m_cells(other.m_cells),
216 m_interfaces(other.m_interfaces),
217 m_alteredCells(other.m_alteredCells),
218 m_alteredInterfaces(other.m_alteredInterfaces),
219 m_nInternalVertices(other.m_nInternalVertices),
220#if BITPIT_ENABLE_MPI==1
221 m_nGhostVertices(other.m_nGhostVertices),
223 m_lastInternalVertexId(other.m_lastInternalVertexId),
224#if BITPIT_ENABLE_MPI==1
225 m_firstGhostVertexId(other.m_firstGhostVertexId),
227 m_nInternalCells(other.m_nInternalCells),
228#if BITPIT_ENABLE_MPI==1
229 m_nGhostCells(other.m_nGhostCells),
231 m_lastInternalCellId(other.m_lastInternalCellId),
232#if BITPIT_ENABLE_MPI==1
233 m_firstGhostCellId(other.m_firstGhostCellId),
236 m_vtkWriteTarget(other.m_vtkWriteTarget),
237 m_vtkVertexMap(other.m_vtkVertexMap),
238 m_boxFrozen(other.m_boxFrozen),
239 m_boxDirty(other.m_boxDirty),
240 m_boxMinPoint(other.m_boxMinPoint),
241 m_boxMaxPoint(other.m_boxMaxPoint),
242 m_boxMinCounter(other.m_boxMinCounter),
243 m_boxMaxCounter(other.m_boxMaxCounter),
244 m_adjacenciesBuildStrategy(other.m_adjacenciesBuildStrategy),
245 m_interfacesBuildStrategy(other.m_interfacesBuildStrategy),
246 m_adaptionMode(other.m_adaptionMode),
247 m_adaptionStatus(other.m_adaptionStatus),
248 m_dimension(other.m_dimension),
249 m_toleranceCustom(other.m_toleranceCustom),
250 m_tolerance(other.m_tolerance)
251#if BITPIT_ENABLE_MPI==1
252 , m_partitioningMode(other.m_partitioningMode),
253 m_partitioningStatus(other.m_partitioningStatus),
254 m_owner(other.m_owner),
255 m_haloSize(other.m_haloSize),
256 m_partitioningCellsTag(other.m_partitioningCellsTag),
257 m_partitioningVerticesTag(other.m_partitioningVerticesTag),
258 m_partitioningSerialization(other.m_partitioningSerialization),
259 m_partitioningOutgoings(other.m_partitioningOutgoings),
260 m_partitioningGlobalExchanges(other.m_partitioningGlobalExchanges),
261 m_partitioningInfoDirty(other.m_partitioningInfoDirty),
262 m_ghostVertexInfo(other.m_ghostVertexInfo),
263 m_ghostVertexExchangeTargets(other.m_ghostVertexExchangeTargets),
264 m_ghostVertexExchangeSources(other.m_ghostVertexExchangeSources),
265 m_ghostCellInfo(other.m_ghostCellInfo),
266 m_ghostCellExchangeTargets(other.m_ghostCellExchangeTargets),
267 m_ghostCellExchangeSources(other.m_ghostCellExchangeSources)
270#if BITPIT_ENABLE_MPI==1
275 initializeSerialCommunicator();
279 importVertexIndexGenerator(other);
280 importInterfaceIndexGenerator(other);
281 importCellIndexGenerator(other);
287 replaceVTKStreamer(&other,
this);
297 m_vertices(std::move(other.m_vertices)),
298 m_cells(std::move(other.m_cells)),
299 m_interfaces(std::move(other.m_interfaces)),
300 m_alteredCells(std::move(other.m_alteredCells)),
301 m_alteredInterfaces(std::move(other.m_alteredInterfaces)),
302 m_vertexIdGenerator(std::move(other.m_vertexIdGenerator)),
303 m_interfaceIdGenerator(std::move(other.m_interfaceIdGenerator)),
304 m_cellIdGenerator(std::move(other.m_cellIdGenerator)),
305 m_nInternalVertices(std::move(other.m_nInternalVertices)),
306#if BITPIT_ENABLE_MPI==1
307 m_nGhostVertices(std::move(other.m_nGhostVertices)),
309 m_lastInternalVertexId(std::move(other.m_lastInternalVertexId)),
310#if BITPIT_ENABLE_MPI==1
311 m_firstGhostVertexId(std::move(other.m_firstGhostVertexId)),
313 m_nInternalCells(std::move(other.m_nInternalCells)),
314#if BITPIT_ENABLE_MPI==1
315 m_nGhostCells(std::move(other.m_nGhostCells)),
317 m_lastInternalCellId(std::move(other.m_lastInternalCellId)),
318#if BITPIT_ENABLE_MPI==1
319 m_firstGhostCellId(std::move(other.m_firstGhostCellId)),
321 m_vtk(std::move(other.m_vtk)),
322 m_vtkWriteTarget(std::move(other.m_vtkWriteTarget)),
323 m_vtkVertexMap(std::move(other.m_vtkVertexMap)),
324 m_boxFrozen(std::move(other.m_boxFrozen)),
325 m_boxDirty(std::move(other.m_boxDirty)),
326 m_boxMinPoint(std::move(other.m_boxMinPoint)),
327 m_boxMaxPoint(std::move(other.m_boxMaxPoint)),
328 m_boxMinCounter(std::move(other.m_boxMinCounter)),
329 m_boxMaxCounter(std::move(other.m_boxMaxCounter)),
330 m_adjacenciesBuildStrategy(std::move(other.m_adjacenciesBuildStrategy)),
331 m_interfacesBuildStrategy(std::move(other.m_interfacesBuildStrategy)),
332 m_adaptionMode(std::move(other.m_adaptionMode)),
333 m_adaptionStatus(std::move(other.m_adaptionStatus)),
334 m_id(std::move(other.m_id)),
335 m_dimension(std::move(other.m_dimension)),
336 m_toleranceCustom(std::move(other.m_toleranceCustom)),
337 m_tolerance(std::move(other.m_tolerance)),
338 m_rank(std::move(other.m_rank)),
339 m_nProcessors(std::move(other.m_nProcessors))
340#if BITPIT_ENABLE_MPI==1
341 , m_communicator(std::move(MPI_COMM_NULL)),
342 m_partitioningMode(other.m_partitioningMode),
343 m_partitioningStatus(std::move(other.m_partitioningStatus)),
344 m_owner(std::move(other.m_owner)),
345 m_haloSize(std::move(other.m_haloSize)),
346 m_partitioningCellsTag(std::move(other.m_partitioningCellsTag)),
347 m_partitioningVerticesTag(std::move(other.m_partitioningVerticesTag)),
348 m_partitioningSerialization(std::move(other.m_partitioningSerialization)),
349 m_partitioningOutgoings(std::move(other.m_partitioningOutgoings)),
350 m_partitioningGlobalExchanges(std::move(other.m_partitioningGlobalExchanges)),
351 m_partitioningInfoDirty(std::move(other.m_partitioningInfoDirty)),
352 m_ghostVertexInfo(std::move(other.m_ghostVertexInfo)),
353 m_ghostVertexExchangeTargets(std::move(other.m_ghostVertexExchangeTargets)),
354 m_ghostVertexExchangeSources(std::move(other.m_ghostVertexExchangeSources)),
355 m_ghostCellInfo(std::move(other.m_ghostCellInfo)),
356 m_ghostCellExchangeTargets(std::move(other.m_ghostCellExchangeTargets)),
357 m_ghostCellExchangeSources(std::move(other.m_ghostCellExchangeSources))
370 replaceVTKStreamer(&other,
this);
372#if BITPIT_ENABLE_MPI==1
374 std::swap(m_communicator, other.m_communicator);
385 VTKBaseStreamer::operator=(std::move(other));
386 m_vertices = std::move(other.m_vertices);
387 m_cells = std::move(other.m_cells);
388 m_interfaces = std::move(other.m_interfaces);
389 m_alteredCells = std::move(other.m_alteredCells);
390 m_alteredInterfaces = std::move(other.m_alteredInterfaces);
391 m_vertexIdGenerator = std::move(other.m_vertexIdGenerator);
392 m_interfaceIdGenerator = std::move(other.m_interfaceIdGenerator);
393 m_cellIdGenerator = std::move(other.m_cellIdGenerator);
394 m_nInternalVertices = std::move(other.m_nInternalVertices);
395#if BITPIT_ENABLE_MPI==1
396 m_nGhostVertices = std::move(other.m_nGhostVertices);
398 m_lastInternalVertexId = std::move(other.m_lastInternalVertexId);
399#if BITPIT_ENABLE_MPI==1
400 m_firstGhostVertexId = std::move(other.m_firstGhostVertexId);
402 m_nInternalCells = std::move(other.m_nInternalCells);
403#if BITPIT_ENABLE_MPI==1
404 m_nGhostCells = std::move(other.m_nGhostCells);
406 m_lastInternalCellId = std::move(other.m_lastInternalCellId);
407#if BITPIT_ENABLE_MPI==1
408 m_firstGhostCellId = std::move(other.m_firstGhostCellId);
410 m_vtk = std::move(other.m_vtk);
411 m_vtkWriteTarget = std::move(other.m_vtkWriteTarget);
412 m_vtkVertexMap = std::move(other.m_vtkVertexMap);
413 m_boxFrozen = std::move(other.m_boxFrozen);
414 m_boxDirty = std::move(other.m_boxDirty);
415 m_boxMinPoint = std::move(other.m_boxMinPoint);
416 m_boxMaxPoint = std::move(other.m_boxMaxPoint);
417 m_boxMinCounter = std::move(other.m_boxMinCounter);
418 m_boxMaxCounter = std::move(other.m_boxMaxCounter);
419 m_adjacenciesBuildStrategy = std::move(other.m_adjacenciesBuildStrategy);
420 m_interfacesBuildStrategy = std::move(other.m_interfacesBuildStrategy);
421 m_adaptionMode = std::move(other.m_adaptionMode);
422 m_adaptionStatus = std::move(other.m_adaptionStatus);
423 m_id = std::move(other.m_id);
424 m_dimension = std::move(other.m_dimension);
425 m_toleranceCustom = std::move(other.m_toleranceCustom);
426 m_tolerance = std::move(other.m_tolerance);
427 m_rank = std::move(other.m_rank);
428 m_nProcessors = std::move(other.m_nProcessors);
429#if BITPIT_ENABLE_MPI==1
430 m_communicator = std::move(MPI_COMM_NULL);
431 m_partitioningMode = std::move(other.m_partitioningMode);
432 m_partitioningStatus = std::move(other.m_partitioningStatus);
433 m_owner = std::move(other.m_owner);
434 m_haloSize = std::move(other.m_haloSize);
435 m_partitioningCellsTag = std::move(other.m_partitioningCellsTag);
436 m_partitioningVerticesTag = std::move(other.m_partitioningVerticesTag);
437 m_partitioningSerialization = std::move(other.m_partitioningSerialization);
438 m_partitioningOutgoings = std::move(other.m_partitioningOutgoings);
439 m_partitioningGlobalExchanges = std::move(other.m_partitioningGlobalExchanges);
440 m_partitioningInfoDirty = std::move(other.m_partitioningInfoDirty);
441 m_ghostVertexInfo = std::move(other.m_ghostVertexInfo);
442 m_ghostVertexExchangeTargets = std::move(other.m_ghostVertexExchangeTargets);
443 m_ghostVertexExchangeSources = std::move(other.m_ghostVertexExchangeSources);
444 m_ghostCellInfo = std::move(other.m_ghostCellInfo);
445 m_ghostCellExchangeTargets = std::move(other.m_ghostCellExchangeTargets);
446 m_ghostCellExchangeSources = std::move(other.m_ghostCellExchangeSources);
460 replaceVTKStreamer(&other,
this);
462#if BITPIT_ENABLE_MPI==1
464 std::swap(m_communicator, other.m_communicator);
473#if BITPIT_ENABLE_MPI==1
480void PatchKernel::initialize(MPI_Comm communicator, std::size_t haloSize)
482void PatchKernel::initialize()
486 m_id = PatchManager::AUTOMATIC_ID;
489 m_nInternalVertices = 0;
490#if BITPIT_ENABLE_MPI==1
491 m_nGhostVertices = 0;
494 m_lastInternalVertexId = Vertex::NULL_ID;
495#if BITPIT_ENABLE_MPI==1
496 m_firstGhostVertexId = Vertex::NULL_ID;
500 m_nInternalCells = 0;
501#if BITPIT_ENABLE_MPI==1
505 m_lastInternalCellId = Cell::NULL_ID;
506#if BITPIT_ENABLE_MPI==1
507 m_firstGhostCellId = Cell::NULL_ID;
514 setVertexAutoIndexing(
true);
515 setInterfaceAutoIndexing(
true);
516 setCellAutoIndexing(
true);
519 setAdjacenciesBuildStrategy(ADJACENCIES_NONE);
522 setInterfacesBuildStrategy(INTERFACES_NONE);
525 setAdaptionStatus(ADAPTION_CLEAN);
527#if BITPIT_ENABLE_MPI==1
529 initializeCommunicator(communicator);
532 initializeHaloSize(haloSize);
535 setPartitioningStatus(PARTITIONING_CLEAN);
538 m_partitioningCellsTag = -1;
539 m_partitioningVerticesTag = -1;
542 if (isPartitioned()) {
543 updatePartitioningInfo(
true);
547 initializeSerialCommunicator();
554 setBoundingBoxFrozen(
false);
558 m_vtkWriteTarget = WRITE_TARGET_CELLS_ALL;
561 std::ostringstream convert;
564 m_vtk.setName(convert.str());
565 m_vtk.setCodex(VTKFormat::APPENDED);
568 m_vtk.setGeomData<
double>(VTKUnstructuredField::POINTS,
this);
569 m_vtk.setGeomData<
long>(VTKUnstructuredField::OFFSETS,
this);
570 m_vtk.setGeomData<
int>(VTKUnstructuredField::TYPES,
this);
571 m_vtk.setGeomData<
long>(VTKUnstructuredField::CONNECTIVITY,
this);
572 m_vtk.setGeomData<
long>(VTKUnstructuredField::FACE_STREAMS,
this);
573 m_vtk.setGeomData<
long>(VTKUnstructuredField::FACE_OFFSETS,
this);
576 m_vtk.addData<
long>(
"cellIndex", VTKFieldType::SCALAR, VTKLocation::CELL,
this);
577 m_vtk.addData<
int>(
"PID", VTKFieldType::SCALAR, VTKLocation::CELL,
this);
578 m_vtk.addData<
long>(
"vertexIndex", VTKFieldType::SCALAR, VTKLocation::POINT,
this);
579#if BITPIT_ENABLE_MPI==1
580 m_vtk.addData<
long>(
"cellGlobalIndex", VTKFieldType::SCALAR, VTKLocation::CELL,
this);
581 m_vtk.addData<
int>(
"cellRank", VTKFieldType::SCALAR, VTKLocation::CELL,
this);
582 m_vtk.addData<
int>(
"cellHaloLayer", VTKFieldType::SCALAR, VTKLocation::CELL,
this);
583 m_vtk.addData<
int>(
"vertexRank", VTKFieldType::SCALAR, VTKLocation::POINT,
this);
587#if BITPIT_ENABLE_MPI!=1
591void PatchKernel::initializeSerialCommunicator()
603#if BITPIT_ENABLE_MPI==1
609 }
catch (
const std::runtime_error &e) {
610 log::cout() <<
"Unable to unregister the patch" << std::endl;
611 log::cout() <<
" Error message: " << e.what() << std::endl;
627 std::vector<adaption::Info> adaptionData;
633 if (!squeezeStorage && !
isDirty(
true)) {
638 finalizeAlterations(squeezeStorage);
643 mergeAdaptionInfo(
adaption(trackAdaption, squeezeStorage), adaptionData);
666 throw std::runtime_error (
"This function has not been implemented for the specified patch.");
681 std::vector<adaption::Info> adaptionData;
685 if (adaptionMode == ADAPTION_DISABLED) {
690 if (adaptionStatus == ADAPTION_CLEAN) {
692 }
else if (adaptionStatus != ADAPTION_DIRTY) {
693 throw std::runtime_error (
"An adaption is already in progress.");
721 std::vector<adaption::Info> adaptionData;
725 if (adaptionMode == ADAPTION_DISABLED) {
730 if (adaptionStatus == ADAPTION_CLEAN) {
732 }
else if (adaptionStatus != ADAPTION_DIRTY) {
733 throw std::runtime_error (
"An adaption is already in progress.");
762 std::vector<adaption::Info> adaptionData;
766 if (adaptionMode == ADAPTION_DISABLED) {
771 if (adaptionStatus == ADAPTION_CLEAN) {
773 }
else if (adaptionStatus != ADAPTION_PREPARED) {
774 throw std::runtime_error (
"The prepare function has not been called.");
781 finalizeAlterations(squeezeStorage);
798 if (adaptionMode == ADAPTION_DISABLED) {
803 if (adaptionStatus == ADAPTION_CLEAN) {
805 }
else if (adaptionStatus == ADAPTION_PREPARED) {
806 throw std::runtime_error (
"It is not yet possible to abort an adaption.");
807 }
else if (adaptionStatus != ADAPTION_ALTERED) {
808 throw std::runtime_error (
"The alter function has not been called.");
833void PatchKernel::finalizeAlterations(
bool squeezeStorage)
840 if (boundingBoxDirty) {
849 if (adjacenciesDirty) {
855 if (interfacesDirty) {
860 m_interfaces.flush();
862#if BITPIT_ENABLE_MPI==1
865 if (partitioningInfoDirty) {
866 updatePartitioningInfo(
true);
871 m_alteredCells.clear();
872 m_alteredInterfaces.clear();
875 if (squeezeStorage) {
974 if (m_vertexIdGenerator) {
975 m_vertexIdGenerator->reset();
977 m_nInternalVertices = 0;
978#if BITPIT_ENABLE_MPI==1
979 m_nGhostVertices = 0;
981 m_lastInternalVertexId = Vertex::NULL_ID;
982#if BITPIT_ENABLE_MPI==1
983 m_firstGhostVertexId = Vertex::NULL_ID;
986 for (
auto &cell : m_cells) {
997 if (m_cellIdGenerator) {
998 m_cellIdGenerator->reset();
1000 m_nInternalCells = 0;
1001#if BITPIT_ENABLE_MPI==1
1004 m_lastInternalCellId = Cell::NULL_ID;
1005#if BITPIT_ENABLE_MPI==1
1006 m_firstGhostCellId = Cell::NULL_ID;
1009#if BITPIT_ENABLE_MPI==1
1010 clearGhostCellsInfo();
1011 clearGhostVerticesInfo();
1016 for (
auto &interface : m_interfaces) {
1017 interface.unsetNeigh();
1018 interface.unsetOwner();
1021 m_alteredCells.clear();
1044 m_alteredInterfaces.clear();
1058 for (
auto &cell : m_cells) {
1059 cell.resetInterfaces(!release);
1062 m_interfaces.clear(release);
1063 if (m_interfaceIdGenerator) {
1064 m_interfaceIdGenerator->reset();
1087 m_vertices.reserve(nVertices);
1110 m_cells.reserve(nCells);
1135 m_interfaces.reserve(nInterfaces);
1148 std::string oldFilename = m_vtk.getName();
1150 m_vtk.setName(filename);
1152 m_vtk.setName(oldFilename);
1164 std::string oldFilename = m_vtk.getName();
1166 m_vtk.setName(filename);
1168 m_vtk.setName(oldFilename);
1195 m_vtk.write(mode, time);
1206 long vtkCellCount = 0;
1207 if (m_vtkWriteTarget == WRITE_TARGET_CELLS_ALL) {
1209#if BITPIT_ENABLE_MPI==1
1210 }
else if (m_vtkWriteTarget == WRITE_TARGET_CELLS_INTERNAL) {
1221 vertexWriteFlag.
fill(
false);
1223 bool vtkFaceStreamNeeded =
false;
1224 for (
const Cell &cell : m_cells) {
1225 if (cell.getDimension() > 2 && !cell.hasInfo()) {
1226 vtkFaceStreamNeeded =
true;
1231#if BITPIT_ENABLE_MPI==1
1234 MPI_Allreduce(MPI_IN_PLACE, &vtkFaceStreamNeeded, 1, MPI_C_BOOL, MPI_LOR, communicator);
1238 long vtkConnectSize = 0;
1239 long vtkFaceStreamSize = 0;
1241 ConstProxyVector<long> cellVertexIds = cell.getVertexIds();
1242 const int nCellVertices = cellVertexIds.
size();
1243 for (
int k = 0; k < nCellVertices; ++k) {
1244 long vertexId = cellVertexIds[k];
1245 vertexWriteFlag.
at(vertexId) =
true;
1248 vtkConnectSize += nCellVertices;
1249 if (vtkFaceStreamNeeded) {
1250 if (cell.getDimension() <= 2 || cell.hasInfo()) {
1251 vtkFaceStreamSize += 1;
1253 vtkFaceStreamSize += cell.getFaceStreamSize();
1258 int vtkVertexCount = 0;
1259 m_vtkVertexMap.unsetKernel();
1260 m_vtkVertexMap.setStaticKernel(&m_vertices);
1263 std::size_t vertexRawId = itr.getRawIndex();
1264 if (vertexWriteFlag.
rawAt(vertexRawId)) {
1265 m_vtkVertexMap.rawAt(vertexRawId) = vtkVertexCount++;
1267 m_vtkVertexMap.rawAt(vertexRawId) = Vertex::NULL_ID;
1271 m_vtk.setDimensions(vtkCellCount, vtkVertexCount, vtkConnectSize, vtkFaceStreamSize);
1311 return m_adaptionMode;
1323 m_adaptionMode = mode;
1337 int adaptionStatus =
static_cast<int>(m_adaptionStatus);
1339#if BITPIT_ENABLE_MPI==1
1342 MPI_Allreduce(MPI_IN_PLACE, &adaptionStatus, 1, MPI_INT, MPI_MAX, communicator);
1358 m_adaptionStatus = status;
1371#if BITPIT_ENABLE_MPI==0
1382 isDirty |= !m_alteredCells.empty();
1387 assert(
isDirty || m_alteredInterfaces.empty());
1398#if BITPIT_ENABLE_MPI==1
1405 isDirty |= !m_vertices.isSynced();
1409 isDirty |= !m_cells.isSynced();
1413 isDirty |= !m_interfaces.isSynced();
1416#if BITPIT_ENABLE_MPI==1
1420 MPI_Allreduce(MPI_IN_PLACE, &
isDirty, 1, MPI_C_BOOL, MPI_LOR, communicator);
1440 initialAdaptionMode = m_adaptionMode;
1443 m_adaptionMode = initialAdaptionMode;
1482void PatchKernel::_setId(
int id)
1504 if (dimension == m_dimension) {
1509 if (m_dimension > 0) {
1514 m_dimension = dimension;
1534 return (m_dimension == 3);
1547 return static_cast<bool>(m_vertexIdGenerator);
1565 createVertexIndexGenerator(
true);
1567 m_vertexIdGenerator.reset();
1576void PatchKernel::dumpVertexAutoIndexing(std::ostream &stream)
const
1578 m_vertexIdGenerator->dump(stream);
1586void PatchKernel::restoreVertexAutoIndexing(std::istream &stream)
1588 createVertexIndexGenerator(
false);
1589 m_vertexIdGenerator->restore(stream);
1600void PatchKernel::createVertexIndexGenerator(
bool populate)
1603 if (!m_vertexIdGenerator) {
1604 m_vertexIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>());
1606 m_vertexIdGenerator->reset();
1611 VertexConstIterator beginItr = m_vertices.cbegin();
1612 VertexConstIterator endItr = m_vertices.cend();
1613 for (VertexConstIterator itr = beginItr; itr != endItr; ++itr) {
1614 m_vertexIdGenerator->setAssigned(itr.getId());
1627void PatchKernel::importVertexIndexGenerator(
const PatchKernel &source)
1629 if (source.m_vertexIdGenerator) {
1630 m_vertexIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>(*(source.m_vertexIdGenerator)));
1632 m_vertexIdGenerator.reset();
1643 return m_vertices.size();
1653 return m_nInternalVertices;
1684 return m_vertices[id];
1695 return m_vertices[id];
1705 return m_vertices[m_lastInternalVertexId];
1715 return m_vertices[m_lastInternalVertexId];
1725 return m_vertices.find(
id);
1735 return m_vertices.begin();
1745 return m_vertices.end();
1755 return m_vertices.begin();
1765 if (m_nInternalVertices > 0) {
1766 return ++m_vertices.find(m_lastInternalVertexId);
1768 return m_vertices.end();
1779 return m_vertices.find(
id);
1789 return m_vertices.cbegin();
1799 return m_vertices.cend();
1809 return m_vertices.cbegin();
1819 if (m_nInternalVertices > 0) {
1820 return ++m_vertices.find(m_lastInternalVertexId);
1822 return m_vertices.end();
1849 return addVertex(std::move(vertex),
id);
1873 id = source.getId();
1884 VertexIterator
iterator = _addInternalVertex(source.getCoords(),
id);
1892 source.setInterior(
true);
1894 Vertex &vertex = (*iterator);
1895 vertex = std::move(source);
1925 VertexIterator
iterator = _addInternalVertex(coords,
id);
1944PatchKernel::VertexIterator PatchKernel::_addInternalVertex(
const std::array<double, 3> &coords,
long id)
1947 if (m_vertexIdGenerator) {
1949 id = m_vertexIdGenerator->generate();
1951 m_vertexIdGenerator->setAssigned(
id);
1953 }
else if (
id < 0) {
1954 throw std::runtime_error(
"No valid id has been provided for the vertex.");
1958#if BITPIT_ENABLE_MPI==1
1964#if BITPIT_ENABLE_MPI==1
1965 referenceId = m_firstGhostVertexId;
1967 referenceId = Vertex::NULL_ID;
1971 VertexIterator iterator;
1972 if (referenceId == Vertex::NULL_ID) {
1973 iterator = m_vertices.emreclaim(
id,
id, coords,
true);
1975 iterator = m_vertices.emreclaimBefore(referenceId,
id,
id, coords,
true);
1977 m_nInternalVertices++;
1980 if (m_lastInternalVertexId < 0) {
1981 m_lastInternalVertexId = id;
1982 }
else if (m_vertices.rawIndex(m_lastInternalVertexId) < m_vertices.rawIndex(
id)) {
1983 m_lastInternalVertexId = id;
1989#if BITPIT_ENABLE_MPI==1
1991 setPartitioningInfoDirty(
true);
1997#if BITPIT_ENABLE_MPI==0
2014 VertexIterator iterator = m_vertices.find(
id);
2015 if (iterator == m_vertices.end()) {
2016 throw std::runtime_error(
"Unable to restore the specified vertex: the kernel doesn't contain an entry for that vertex.");
2019 _restoreInternalVertex(iterator, coords);
2031void PatchKernel::_restoreInternalVertex(
const VertexIterator &
iterator,
const std::array<double, 3> &coords)
2037 Vertex &vertex = *iterator;
2038 vertex.initialize(iterator.getId(), coords,
true);
2039 m_nInternalVertices++;
2057#if BITPIT_ENABLE_MPI==1
2058 const Vertex &vertex = m_vertices[id];
2061 _deleteInternalVertex(
id);
2063 _deleteGhostVertex(
id);
2066 _deleteInternalVertex(
id);
2077void PatchKernel::_deleteInternalVertex(
long id)
2080 const Vertex &vertex = m_vertices[id];
2084 m_vertices.erase(
id,
true);
2085 m_nInternalVertices--;
2086 if (
id == m_lastInternalVertexId) {
2091 if (m_vertexIdGenerator) {
2092 m_vertexIdGenerator->trash(
id);
2117 std::unordered_set<long> borderVertices;
2118 for (
const Cell &cell : m_cells) {
2119 int nCellFaces = cell.getFaceCount();
2120 for (
int i = 0; i < nCellFaces; ++i) {
2121 if (!cell.isFaceBorder(i)) {
2125 int nFaceVertices = cell.getFaceVertexCount(i);
2126 for (
int k = 0; k < nFaceVertices; ++k) {
2127 long faceVertexId = cell.getFaceVertexId(i, k);
2128 borderVertices.insert(faceVertexId);
2133 return borderVertices.size();
2145 std::unordered_set<long> usedVertices;
2146 for (
const Cell &cell : m_cells) {
2147 ConstProxyVector<long> cellVertexIds = cell.getVertexIds();
2148 int nCellVertices = cellVertexIds.
size();
2149 for (
int i = 0; i < nCellVertices; ++i) {
2150 usedVertices.insert(cellVertexIds[i]);
2166 VertexConstIterator beginItr = m_vertices.cbegin();
2167 VertexConstIterator endItr = m_vertices.cend();
2171 vertexUsedFlag.
fill(
false);
2172 for (
const Cell &cell : m_cells) {
2173 ConstProxyVector<long> cellVertexIds = cell.getVertexIds();
2174 int nCellVertices = cellVertexIds.
size();
2175 for (
int j = 0; j < nCellVertices; ++j) {
2176 long vertexId = cellVertexIds[j];
2177 vertexUsedFlag[vertexId] =
true;
2182 std::size_t nOrhpanVertices = 0;
2183 for (VertexConstIterator itr = beginItr; itr != endItr; ++itr) {
2184 std::size_t vertexRawIndex = itr.getRawIndex();
2185 if (!vertexUsedFlag.
rawAt(vertexRawIndex)) {
2191 std::vector<long> orhpanVertices(nOrhpanVertices);
2193 std::size_t orphanVertexIndex = 0;
2194 for (VertexConstIterator itr = beginItr; itr != endItr; ++itr) {
2195 std::size_t vertexRawIndex = itr.getRawIndex();
2196 if (!vertexUsedFlag.
rawAt(vertexRawIndex)) {
2197 orhpanVertices[orphanVertexIndex] = itr.getId();
2198 ++orphanVertexIndex;
2202 return orhpanVertices;
2229 std::vector<long> collapsedVertices;
2231 return collapsedVertices;
2235 if (nVertices == 0) {
2236 return collapsedVertices;
2245 Vertex::Less vertexLess(10 * std::numeric_limits<double>::epsilon());
2246 auto rawVertexLess = [
this, &vertexLess](
const std::size_t &i,
const std::size_t &j)
2248 return vertexLess(this->m_vertices.rawAt(i), this->m_vertices.rawAt(j));
2250 std::set<std::size_t,
decltype(rawVertexLess)> vertexTree(rawVertexLess);
2252 std::unordered_map<long, long> vertexMap;
2253 for (VertexConstIterator vertexItr = m_vertices.cbegin(); vertexItr != m_vertices.cend(); ++vertexItr) {
2254 std::size_t vertexRawId = vertexItr.getRawIndex();
2255 auto vertexTreeItr = vertexTree.find(vertexRawId);
2256 if (vertexTreeItr == vertexTree.end()) {
2257 vertexTree.insert(vertexRawId);
2259 long vertexId = vertexItr.getId();
2260 long vertexCoincidentId = m_vertices.rawFind(*vertexTreeItr).getId();
2261 vertexMap.insert({vertexId, vertexCoincidentId});
2266 if (!vertexMap.empty()) {
2272 bool keepAdjacenciesUpToDate;
2273 if (adjacenciesBuildStrategy != ADJACENCIES_NONE) {
2276 keepAdjacenciesUpToDate =
false;
2279 for (
Cell &cell : m_cells) {
2281 int nRenumberedVertices = cell.renumberVertices(vertexMap);
2287 if ((adjacenciesBuildStrategy != ADJACENCIES_NONE) && (nRenumberedVertices > 0)) {
2292 if (keepAdjacenciesUpToDate) {
2297 for (
Interface &interface : m_interfaces) {
2299 interface.renumberVertices(vertexMap);
2303 collapsedVertices.resize(vertexMap.size());
2306 for (
const auto &entry : vertexMap) {
2307 collapsedVertices[k++] = entry.first;
2311 return collapsedVertices;
2349 *coordinates = std::unique_ptr<std::array<double, 3>[]>(
new std::array<double, 3>[nVertices]);
2364 for (std::size_t i = 0; i < nVertices; ++i) {
2379#if BITPIT_ENABLE_MPI==1
2381 MPI_Allreduce(MPI_IN_PLACE, &isEmpty, 1, MPI_C_BOOL, MPI_LAND,
getCommunicator());
2395 if (m_nInternalVertices == 0) {
2396 m_lastInternalVertexId = Vertex::NULL_ID;
2400 VertexIterator lastInternalVertexItr;
2401#if BITPIT_ENABLE_MPI==1
2402 if (m_nGhostVertices == 0) {
2403 lastInternalVertexItr = --m_vertices.end();
2404 m_lastInternalVertexId = lastInternalVertexItr->getId();
2406 m_lastInternalVertexId = m_vertices.getSizeMarker(m_nInternalVertices - 1, Vertex::NULL_ID);
2409 lastInternalVertexItr = --m_vertices.end();
2410 m_lastInternalVertexId = lastInternalVertexItr->getId();
2424 return static_cast<bool>(m_cellIdGenerator);
2442 createCellIndexGenerator(
true);
2444 m_cellIdGenerator.reset();
2453void PatchKernel::dumpCellAutoIndexing(std::ostream &stream)
const
2455 m_cellIdGenerator->dump(stream);
2463void PatchKernel::restoreCellAutoIndexing(std::istream &stream)
2465 createCellIndexGenerator(
false);
2466 m_cellIdGenerator->restore(stream);
2477void PatchKernel::createCellIndexGenerator(
bool populate)
2480 if (!m_cellIdGenerator) {
2481 m_cellIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>());
2483 m_cellIdGenerator->reset();
2488 CellConstIterator beginItr = m_cells.cbegin();
2489 CellConstIterator endItr = m_cells.cend();
2490 for (CellConstIterator itr = beginItr; itr != endItr; ++itr) {
2491 m_cellIdGenerator->setAssigned(itr.getId());
2504void PatchKernel::importCellIndexGenerator(
const PatchKernel &source)
2506 if (source.m_cellIdGenerator) {
2507 m_cellIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>(*(source.m_cellIdGenerator)));
2509 m_cellIdGenerator.reset();
2520 return m_cells.size();
2530 return m_nInternalCells;
2593 return m_cells[id].getType();
2603 return m_cells[m_lastInternalCellId];
2613 return m_cells[m_lastInternalCellId];
2623 return m_cells.find(
id);
2633 return m_cells.begin();
2643 return m_cells.end();
2653 return m_cells.begin();
2673 if (m_nInternalCells > 0) {
2674 return ++m_cells.find(m_lastInternalCellId);
2676 return m_cells.end();
2697 return m_cells.find(
id);
2707 return m_cells.cbegin();
2717 return m_cells.cend();
2727 return m_cells.cbegin();
2748 if (m_nInternalCells > 0) {
2749 return ++m_cells.find(m_lastInternalCellId);
2751 return m_cells.cend();
2786 return addCell(std::move(cell),
id);
2807 id = source.getId();
2814 std::unique_ptr<long[]> dummyConnectStorage = std::unique_ptr<long[]>(
nullptr);
2816 CellIterator
iterator = _addInternalCell(ElementType::UNDEFINED, std::move(dummyConnectStorage),
id);
2824 Cell &cell = (*iterator);
2825 cell = std::move(source);
2847 std::unique_ptr<long[]> connectStorage;
2850 connectStorage = std::unique_ptr<long[]>(
new long[connectSize]);
2852 connectStorage = std::unique_ptr<long[]>(
nullptr);
2855 return addCell(type, std::move(connectStorage),
id);
2877 int connectSize = connectivity.size();
2878 std::unique_ptr<long[]> connectStorage = std::unique_ptr<long[]>(
new long[connectSize]);
2879 std::copy(connectivity.data(), connectivity.data() + connectSize, connectStorage.get());
2881 return addCell(type, std::move(connectStorage),
id);
2912 CellIterator
iterator = _addInternalCell(type, std::move(connectStorage),
id);
2933PatchKernel::CellIterator PatchKernel::_addInternalCell(
ElementType type, std::unique_ptr<
long[]> &&connectStorage,
2937 if (m_cellIdGenerator) {
2939 id = m_cellIdGenerator->generate();
2941 m_cellIdGenerator->setAssigned(
id);
2943 }
else if (
id < 0) {
2944 throw std::runtime_error(
"No valid id has been provided for the cell.");
2948#if BITPIT_ENABLE_MPI==1
2954#if BITPIT_ENABLE_MPI==1
2955 referenceId = m_firstGhostCellId;
2957 referenceId = Cell::NULL_ID;
2964 CellIterator iterator;
2965 if (referenceId == Cell::NULL_ID) {
2966 iterator = m_cells.emreclaim(
id,
id, type, std::move(connectStorage),
true, storeInterfaces, storeAdjacencies);
2968 iterator = m_cells.emreclaimBefore(referenceId,
id,
id, type, std::move(connectStorage),
true, storeInterfaces, storeAdjacencies);
2973 if (m_lastInternalCellId < 0) {
2974 m_lastInternalCellId = id;
2975 }
else if (m_cells.rawIndex(m_lastInternalCellId) < m_cells.rawIndex(
id)) {
2976 m_lastInternalCellId = id;
2980 setAddedCellAlterationFlags(
id);
2982#if BITPIT_ENABLE_MPI==1
2984 setPartitioningInfoDirty(
true);
2998void PatchKernel::setAddedCellAlterationFlags(
long id)
3000 AlterationFlags flags = FLAG_NONE;
3002 flags |= FLAG_ADJACENCIES_DIRTY;
3005 flags |= FLAG_INTERFACES_DIRTY;
3011#if BITPIT_ENABLE_MPI==0
3035 CellIterator iterator = m_cells.find(
id);
3036 if (iterator == m_cells.end()) {
3037 throw std::runtime_error(
"Unable to restore the specified cell: the kernel doesn't contain an entry for that cell.");
3040 _restoreInternalCell(iterator, type, std::move(connectStorage));
3055 std::unique_ptr<
long[]> &&connectStorage)
3064 long cellId = iterator.getId();
3065 Cell &cell = *iterator;
3066 cell.initialize(cellId, type, std::move(connectStorage),
true, storeInterfaces, storeAdjacencies);
3070 setRestoredCellAlterationFlags(cellId);
3078void PatchKernel::setRestoredCellAlterationFlags(
long id)
3080 AlterationFlags flags = FLAG_NONE;
3082 flags |= FLAG_ADJACENCIES_DIRTY;
3085 flags |= FLAG_INTERFACES_DIRTY;
3103#if BITPIT_ENABLE_MPI==1
3104 const Cell &cell = m_cells[id];
3106 if (isInternalCell) {
3107 _deleteInternalCell(
id);
3109 _deleteGhostCell(
id);
3112 _deleteInternalCell(
id);
3123void PatchKernel::_deleteInternalCell(
long id)
3126 setDeletedCellAlterationFlags(
id);
3129 m_cells.erase(
id,
true);
3131 if (
id == m_lastInternalCellId) {
3136 if (m_cellIdGenerator) {
3137 m_cellIdGenerator->trash(
id);
3148void PatchKernel::setDeletedCellAlterationFlags(
long id)
3150 const Cell &cell =
getCell(
id);
3156 const int nCellAdjacencies = cell.getAdjacencyCount();
3157 const long *cellAdjacencies = cell.getAdjacencies();
3158 for (
int k = 0; k < nCellAdjacencies; ++k) {
3159 long adjacencyId = cellAdjacencies[k];
3161 AlterationFlags flags = FLAG_DANGLING;
3163 flags |= FLAG_ADJACENCIES_DIRTY;
3166 flags |= FLAG_INTERFACES_DIRTY;
3174 const int nCellInterfaces = cell.getInterfaceCount();
3175 const long *cellInterfaces = cell.getInterfaces();
3176 for (
int k = 0; k < nCellInterfaces; ++k) {
3177 long interfaceId = cellInterfaces[k];
3205 long nBorderCells = 0;
3206 for (
const Cell &cell : m_cells) {
3207 int nCellFaces = cell.getFaceCount();
3208 for (
int i = 0; i < nCellFaces; ++i) {
3209 if (cell.isFaceBorder(i)) {
3216 return nBorderCells;
3243 std::unordered_map<long, short> vertexValence;
3244 for (
const Cell &cell : m_cells) {
3245 ConstProxyVector<long> cellVertexIds = cell.getVertexIds();
3246 int nCellVertices = cellVertexIds.
size();
3247 for (
int j = 0; j < nCellVertices; j++) {
3248 long vertexId = cellVertexIds[j];
3249 vertexValence[vertexId] += 1;
3254 std::vector<long> orphanCells;
3255 for (
const Cell &cell : m_cells) {
3256 long isIsolated =
true;
3257 ConstProxyVector<long> cellVertexIds = cell.getVertexIds();
3258 int nCellVertices = cellVertexIds.
size();
3259 for (
int j = 0; j < nCellVertices; j++) {
3260 long vertexId = cellVertexIds[j];
3261 if (vertexValence[vertexId] > 1) {
3268 orphanCells.push_back(cell.getId());
3302 auto hasher = [](
const ConstProxyVector<long> &ids)
3304 std::size_t hash = std::hash<long>{}(0);
3305 for (
long id : ids) {
3306 hash = hash + std::hash<long>{}(id);
3312 std::unordered_map<long, std::size_t > counters;
3313 auto predicate = [&counters](
const ConstProxyVector<long> &ids_A,
const ConstProxyVector<long> &ids_B)
3316 for (
long id : ids_A) {
3319 for (
long id : ids_B) {
3323 for (
const auto &entry : counters) {
3324 if (entry.second != 0) {
3336 std::vector<long> duplicateCells;
3337 std::unordered_set<ConstProxyVector<long>,
decltype(hasher),
decltype(predicate)> vertexStash(
getCellCount(), hasher, predicate);
3338 for (
const Cell &cell : m_cells) {
3339 ConstProxyVector<long> cellVertexIds = cell.getVertexIds();
3340 auto vertexStashItr = vertexStash.find(cellVertexIds);
3341 if (vertexStashItr == vertexStash.end()) {
3342 vertexStash.insert(std::move(cellVertexIds));
3344 duplicateCells.push_back(cell.getId());
3348 return duplicateCells;
3356 if (m_nInternalCells == 0) {
3357 m_lastInternalCellId = Cell::NULL_ID;
3361 CellIterator lastInternalCellItr;
3362#if BITPIT_ENABLE_MPI==1
3363 if (m_nGhostCells == 0) {
3364 lastInternalCellItr = --m_cells.end();
3365 m_lastInternalCellId = lastInternalCellItr->getId();
3367 m_lastInternalCellId = m_cells.getSizeMarker(m_nInternalCells - 1, Cell::NULL_ID);
3370 lastInternalCellItr = --m_cells.end();
3371 m_lastInternalCellId = lastInternalCellItr->getId();
3394 std::vector<long> neighs;
3432 std::vector<long> neighs;
3460 assert(codimension >= 1 && codimension <=
getDimension());
3462 if (codimension == 1) {
3466 }
else if (codimension == 2) {
3479 std::vector<long> neighs;
3505 if (m_cells.size() == 0) {
3508 nCellVertices = cellTypeInfo.nVertices;
3514 for (
int i = 0; i < nCellVertices; ++i) {
3534 if (m_cells.size() == 0) {
3537 nCellFaces = cellTypeInfo.nFaces;
3544 for (
int i = 0; i < nCellFaces; ++i) {
3558 std::vector<long> neighs;
3598 for (
int k = 0; k < nFaceAdjacencies; ++k) {
3599 long neighId = faceAdjacencies[k];
3600 if (!blackList || utils::findInOrderedVector<long>(neighId, *blackList) == blackList->end()) {
3601 utils::addToOrderedVector<long>(neighId, *neighs);
3619 std::vector<long> neighs;
3650 if (m_cells.size() == 0) {
3653 nCellEdges = cellTypeInfo.nEdges;
3660 std::unique_ptr<std::vector<long>> blackList;
3662 blackList = std::unique_ptr<std::vector<long>>(
new std::vector<long>());
3666 for (
int i = 0; i < nCellEdges; ++i) {
3682 std::vector<long> neighs;
3729 std::size_t nEdgeVertices = edgeVertices.
size();
3730 if (nEdgeVertices < 2) {
3737 const int GUESS_NEIGHS_COUNT = 3;
3739 std::vector<long> candidateIds;
3740 candidateIds.reserve(GUESS_NEIGHS_COUNT);
3744 long lastEdgeVertexId = cell.
getEdgeVertexId(edge, nEdgeVertices - 1);
3746 ConstProxyVector<long> candidateVertexIds;
3747 for (
long candidateId : candidateIds) {
3748 const Cell &candidateNeigh = m_cells.at(candidateId);
3750 std::size_t nCandidateVertices = candidateVertexIds.
size();
3752 bool isEdgeNeighbour =
false;
3753 for (std::size_t k = 0; k < nCandidateVertices; ++k) {
3754 if (candidateVertexIds[k] == lastEdgeVertexId) {
3755 isEdgeNeighbour =
true;
3760 if (isEdgeNeighbour) {
3761 utils::addToOrderedVector<long>(candidateId, *neighs);
3777 std::vector<long> neighs;
3801 if (m_cells.size() == 0) {
3804 nCellVertices = cellTypeInfo.nVertices;
3811 std::unique_ptr<std::vector<long>> blackList;
3813 blackList = std::unique_ptr<std::vector<long>>(
new std::vector<long>());
3821 for (
int i = 0; i < nCellVertices; ++i) {
3835 std::vector<long> neighs;
3894 const int GUESS_NEIGHS_COUNT = 8;
3896 std::vector<long> alreadyProcessed;
3897 alreadyProcessed.reserve(GUESS_NEIGHS_COUNT);
3899 std::vector<long> scanQueue;
3900 scanQueue.reserve(GUESS_NEIGHS_COUNT);
3901 scanQueue.push_back(
id);
3903 while (!scanQueue.empty()) {
3905 long scanCellId = scanQueue.back();
3907 scanQueue.pop_back();
3908 utils::addToOrderedVector<long>(scanCell.
getId(), alreadyProcessed);
3912 const long *scanCellConnectivity =
nullptr;
3914 scanCellInfo = &(scanCell.
getInfo());
3915 scanCellConnectivity = scanCell.
getConnect();
3921 nFaces = scanCellInfo->nFaces;
3926 for (
int i = 0; i < nFaces; ++i) {
3944 bool faceOwnsVertex =
false;
3947 const int *faceLocalConnectivity = scanCellInfo->faceConnectStorage[i].data();
3948 const int nFaceVertices = faceInfo.nVertices;
3949 for (
int k = 0; k < nFaceVertices; ++k) {
3950 long faceVertexId = scanCellConnectivity[faceLocalConnectivity[k]];
3951 if (faceVertexId == vertexId) {
3952 faceOwnsVertex =
true;
3958 int nFaceVertices = faceVertexIds.
size();
3959 for (
int k = 0; k < nFaceVertices; ++k) {
3960 long faceVertexId = faceVertexIds[k];
3961 if (faceVertexId == vertexId) {
3962 faceOwnsVertex =
true;
3968 if (!faceOwnsVertex) {
3977 for (
int k = 0; k < nFaceAdjacencies; ++k) {
3978 long faceNeighId = faceAdjacencies[k];
3981 if (utils::findInOrderedVector<long>(faceNeighId, alreadyProcessed) != alreadyProcessed.end()) {
3986 if (!blackList || utils::findInOrderedVector<long>(faceNeighId, *blackList) == blackList->end()) {
3987 utils::addToOrderedVector<long>(faceNeighId, *neighs);
3991 scanQueue.push_back(faceNeighId);
4006 std::vector<long> ring;
4025 utils::addToOrderedVector<long>(
id, *ring);
4049 for (
int i = 0; i < nFaces; ++i) {
4052 for (
int k = 0; k < nFaceAdjacencies; ++k) {
4053 long faceNeighId = faceAdjacencies[k];
4054 if (faceNeighId < 0) {
4056 }
else if (faceNeighId == neighId) {
4058 *cellAdjacencyId = k;
4065 *cellAdjacencyId = -1;
4080 list.insert(itr->getPID());
4094 std::vector<long> cells;
4097 if (itr->getPID() == pid){
4098 cells.push_back(itr.getId());
4115 std::vector<long> ring;
4141 if (cellId == bitpit::Element::NULL_ID) {
4146 assert(vertexLocalId >= 0);
4162 return static_cast<bool>(m_interfaceIdGenerator);
4183 createInterfaceIndexGenerator(
true);
4186 throw std::runtime_error(
"Auto-indexing cannot be disabled if interfaces build strategy is set to automatic.");
4189 m_interfaceIdGenerator.reset();
4198void PatchKernel::dumpInterfaceAutoIndexing(std::ostream &stream)
const
4200 m_interfaceIdGenerator->dump(stream);
4208void PatchKernel::restoreInterfaceAutoIndexing(std::istream &stream)
4210 createInterfaceIndexGenerator(
false);
4211 m_interfaceIdGenerator->restore(stream);
4222void PatchKernel::createInterfaceIndexGenerator(
bool populate)
4225 if (!m_interfaceIdGenerator) {
4226 m_interfaceIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>());
4228 m_interfaceIdGenerator->reset();
4233 InterfaceConstIterator beginItr = m_interfaces.cbegin();
4234 InterfaceConstIterator endItr = m_interfaces.cend();
4235 for (InterfaceConstIterator itr = beginItr; itr != endItr; ++itr) {
4236 m_interfaceIdGenerator->setAssigned(itr.getId());
4249void PatchKernel::importInterfaceIndexGenerator(
const PatchKernel &source)
4251 if (source.m_interfaceIdGenerator) {
4252 m_interfaceIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>(*(source.m_interfaceIdGenerator)));
4254 m_interfaceIdGenerator.reset();
4265 return m_interfaces.size();
4275 return m_interfaces;
4285 return m_interfaces;
4296 return m_interfaces[id];
4307 return m_interfaces[id];
4318 return m_interfaces[id].getType();
4328 return m_interfaces.find(
id);
4338 return m_interfaces.begin();
4348 return m_interfaces.end();
4358 return m_interfaces.find(
id);
4368 return m_interfaces.cbegin();
4378 return m_interfaces.cend();
4399 interface.
setId(
id);
4423 id = source.getId();
4431 std::unique_ptr<long[]> dummyConnectStorage = std::unique_ptr<long[]>(
nullptr);
4433 InterfaceIterator
iterator = _addInterface(ElementType::UNDEFINED, std::move(dummyConnectStorage),
id);
4443 interface = std::move(source);
4466 std::unique_ptr<long[]> connectStorage = std::unique_ptr<long[]>(
new long[connectSize]);
4468 return addInterface(type, std::move(connectStorage),
id);
4487 const std::vector<long> &connectivity,
4490 int connectSize = connectivity.size();
4491 std::unique_ptr<long[]> connectStorage = std::unique_ptr<long[]>(
new long[connectSize]);
4492 std::copy(connectivity.data(), connectivity.data() + connectSize, connectStorage.get());
4494 return addInterface(type, std::move(connectStorage),
id);
4514 std::unique_ptr<
long[]> &&connectStorage,
4525 InterfaceIterator
iterator = _addInterface(type, std::move(connectStorage),
id);
4546PatchKernel::InterfaceIterator PatchKernel::_addInterface(
ElementType type,
4547 std::unique_ptr<
long[]> &&connectStorage,
4551 if (m_interfaceIdGenerator) {
4553 id = m_interfaceIdGenerator->generate();
4555 m_interfaceIdGenerator->setAssigned(
id);
4557 }
else if (
id < 0) {
4558 throw std::runtime_error(
"No valid id has been provided for the interface.");
4565 setAddedInterfaceAlterationFlags(
id);
4578void PatchKernel::setAddedInterfaceAlterationFlags(
long id)
4596 std::unique_ptr<
long[]> &&connectStorage,
4609 throw std::runtime_error(
"Unable to restore the specified interface: the kernel doesn't contain an entry for that interface.");
4612 _restoreInterface(
iterator, type, std::move(connectStorage));
4629 std::unique_ptr<
long[]> &&connectStorage)
4635 long interfaceId =
iterator.getId();
4637 interface.initialize(interfaceId, type, std::move(connectStorage));
4640 setRestoredInterfaceAlterationFlags(interfaceId);
4648void PatchKernel::setRestoredInterfaceAlterationFlags(
long id)
4664 _deleteInterface(
id);
4674void PatchKernel::_deleteInterface(
long id)
4677 setDeletedInterfaceAlterationFlags(
id);
4680 m_interfaces.erase(
id,
true);
4683 if (m_interfaceIdGenerator) {
4684 m_interfaceIdGenerator->trash(
id);
4695void PatchKernel::setDeletedInterfaceAlterationFlags(
long id)
4721 long nBorderInterfaces = 0;
4722 for (
const Interface &interface : m_interfaces) {
4723 if (interface.getNeigh() < 0) {
4724 ++nBorderInterfaces;
4728 return nBorderInterfaces;
4741 long nOrphanInterfaces = 0;
4744 const long interfaceId = itr.getId();
4746 ++nOrphanInterfaces;
4750 return nOrphanInterfaces;
4763 std::vector<long> orphanInterfaces;
4766 const long interfaceId = itr.getId();
4768 orphanInterfaces.push_back(interfaceId);
4772 return orphanInterfaces;
4800 const Interface &
interface = getInterface(id);
4803 long ownerId = interface.
getOwner();
4804 long neighId = interface.getNeigh();
4805 if (ownerId >= 0 && neighId >= 0) {
4810 if (ownerId >= 0 && neighId < 0) {
4828 for (
const Cell &cell : m_cells) {
4829 int nCellFaces = cell.getFaceCount();
4830 for (
int i = 0; i < nCellFaces; ++i) {
4831 if (!cell.isFaceBorder(i)) {
4832 nFaces += 1. / (cell.getAdjacencyCount(i) + 1);
4839 return ((
long) round(nFaces));
4863 long nBorderFaces = 0;
4864 for (
const Cell &cell : m_cells) {
4865 int nCellFaces = cell.getFaceCount();
4866 for (
int i = 0; i < nCellFaces; ++i) {
4867 if (cell.isFaceBorder(i)) {
4873 return nBorderFaces;
4884 m_vertices.dumpKernel(stream);
4887 for (
const Vertex &vertex : m_vertices) {
4889#if BITPIT_ENABLE_MPI==1
4896 const std::array<double, 3> &coords = vertex.
getCoords();
4903#if BITPIT_ENABLE_MPI==1
4920 m_vertices.restoreKernel(stream);
4927 long nVertices = m_vertices.size();
4928 for (
long i = 0; i < nVertices; ++i) {
4932#if BITPIT_ENABLE_MPI==1
4940 std::array<double, 3> coords;
4945#if BITPIT_ENABLE_MPI==1
4953#if BITPIT_ENABLE_MPI==1
4957 long dummyFirstGhostVertexId;
4958 long dummyLastInternalVertexId;
4975 m_cells.dumpKernel(stream);
4978 for (
const Cell &cell: m_cells) {
4983#if BITPIT_ENABLE_MPI==1
4990 int dummyHaloLayer = 0;
4994 int cellConnectSize = cell.getConnectSize();
4997 const long *cellConnect = cell.getConnect();
4998 for (
int i = 0; i < cellConnectSize; ++i) {
5004#if BITPIT_ENABLE_MPI==1
5021 m_cells.restoreKernel(stream);
5028 long nCells = m_cells.size();
5029 for (
long i = 0; i < nCells; ++i) {
5039#if BITPIT_ENABLE_MPI==1
5053 int cellConnectSize;
5056 std::unique_ptr<long[]> cellConnect = std::unique_ptr<long[]>(
new long[cellConnectSize]);
5057 for (
int k = 0; k < cellConnectSize; ++k) {
5062#if BITPIT_ENABLE_MPI==1
5071#if BITPIT_ENABLE_MPI==1
5075 long dummyFirstGhostCellId;
5076 long dummyLastInternalCellId;
5101 m_interfaces.dumpKernel(stream);
5110 long neighId = interface.getNeigh();
5136 m_interfaces.restoreKernel(stream);
5143 long nInterfaces = m_interfaces.size();
5144 for (
long n = 0; n < nInterfaces; ++n) {
5152 Cell *owner = &(m_cells.at(ownerId));
5160 neigh = &(m_cells.at(neighId));
5169 InterfaceIterator interfaceIterator = buildCellInterface(owner, ownerFace, neigh, neighFace, interfaceId);
5170 interfaceIterator->setPID(pid);
5175 m_alteredInterfaces.clear();
5196 return std::vector<adaption::Info>();
5214 assert(
false &&
"The patch needs to implement _adaptionAlter");
5216 return std::vector<adaption::Info>();
5285 return adaption::MARKER_UNDEFINED;
5315 if (m_nInternalVertices > 0) {
5316 m_vertices.sortBefore(m_lastInternalVertexId,
true);
5320#if BITPIT_ENABLE_MPI==1
5322 if (m_nGhostVertices > 0) {
5323 m_vertices.sortAfter(m_firstGhostVertexId,
true);
5346 if (m_nInternalCells > 0) {
5347 m_cells.sortBefore(m_lastInternalCellId,
true);
5351#if BITPIT_ENABLE_MPI==1
5353 if (m_nGhostCells > 0) {
5354 m_cells.sortAfter(m_firstGhostCellId,
true);
5374 m_interfaces.sort();
5376 m_interfaces.sync();
5407 m_vertices.squeeze();
5447 m_interfaces.squeeze();
5449 m_interfaces.sync();
5466 if (m_alteredCells.empty()) {
5467 AlterationFlagsStorage().swap(m_alteredCells);
5470 if (m_alteredInterfaces.empty()) {
5471 AlterationFlagsStorage().swap(m_alteredInterfaces);
5523 ConstProxyVector<long> cellVertexIds = cell.
getVertexIds();
5524 const int nCellVertices = cellVertexIds.
size();
5527 ConstProxyVector<std::array<double, 3>> vertexCoordinates(ConstProxyVector<std::array<double, 3>>::INTERNAL_STORAGE, nCellVertices);
5528 ConstProxyVector<std::array<double, 3>>::storage_pointer storage = vertexCoordinates.
storedData();
5531 return vertexCoordinates;
5570 const Interface &
interface = getInterface(id);
5584 const Interface &
interface = getInterface(id);
5598 const Interface &
interface = getInterface(id);
5599 ConstProxyVector<long> interfaceVertexIds = interface.
getVertexIds();
5600 const int nInterfaceVertices = interfaceVertexIds.size();
5603 ConstProxyVector<std::array<double, 3>> vertexCoordinates(ConstProxyVector<std::array<double, 3>>::INTERNAL_STORAGE, nInterfaceVertices);
5604 ConstProxyVector<std::array<double, 3>>::storage_pointer storage = vertexCoordinates.
storedData();
5605 getVertexCoords(interfaceVertexIds.size(), interfaceVertexIds.data(), storage);
5607 return vertexCoordinates;
5618 const Interface &
interface = getInterface(id);
5633 const Interface &
interface = getInterface(id);
5658 std::array<std::array<double, 3>, 2> *intersection,
5659 std::vector<std::array<double, 3>> *polygon)
const
5661 double distanceTolerance =
getTol();
5663 const Interface &
interface = getInterface(id);
5665 switch (interfaceType)
5668 case ElementType::LINE:
5670 const std::array<double, 3> &P0 =
getVertexCoords(interface.getVertexId(0));
5671 const std::array<double, 3> &P1 =
getVertexCoords(interface.getVertexId(1));
5673 std::array<double, 3> x;
5676 if (
norm2(x - P0) < distanceTolerance)
return false;
5677 if (
norm2(x - P1) < distanceTolerance)
return false;
5679 if (!intersectionFound)
return false;
5681 (*intersection)[0] = x;
5682 (*intersection)[1] = x;
5684 polygon->push_back(P0);
5685 polygon->push_back(x);
5688 polygon->push_back(x);
5689 polygon->push_back(P1);
5693 case ElementType::TRIANGLE:
5695 const std::array<double, 3> &P0 =
getVertexCoords(interface.getVertexId(0));
5696 const std::array<double, 3> &P1 =
getVertexCoords(interface.getVertexId(1));
5697 const std::array<double, 3> &P2 =
getVertexCoords(interface.getVertexId(2));
5700 *intersection, *polygon, distanceTolerance);
5703 case ElementType::PIXEL:
5706 std::unique_ptr<std::array<double, 3>[]> coordinates;
5710 *intersection, *polygon, distanceTolerance);
5716 assert(interfaceType != ElementType::UNDEFINED);
5719 ConstProxyVector<long> vertexIds = interface.getVertexIds();
5720 int nVertices = vertexIds.
size();
5722 std::vector<std::array<double, 3>> coordinates(nVertices);
5723 for (
int i = 0; i < nVertices; ++i) {
5725 coordinates[i] =
getVertex(vertexId).getCoords();
5728 std::vector<std::array<std::array<double, 3>, 2>> intersections;
5729 std::vector< std::vector<std::array<double, 3>>> polygons;
5731 intersections, polygons, distanceTolerance);
5733 if (intersections.size() > 1) {
5734 throw std::runtime_error(
"Intersection of concave interfaces is not supported.");
5737 (*intersection) = intersections[0];
5738 (*polygon) = polygons[0];
5740 return intersectionFound;
5758 ConstProxyVector<long> elementVertexIds = element.
getVertexIds();
5759 std::size_t nCellVertices = elementVertexIds.
size();
5760 BITPIT_CREATE_WORKSPACE(vertexCoordinates, std::array<double BITPIT_COMMA 3>, nCellVertices, ReferenceElementInfo::MAX_ELEM_VERTICES);
5776 switch (elementType)
5779 case ElementType::VERTEX:
5781 const long *elementConnect = element.
getConnect();
5783 *maxPoint = *minPoint;
5787 case ElementType::PIXEL:
5789 const long *elementConnect = element.
getConnect();
5791 const std::array<double, 3> &vertexCoord_0 =
getVertexCoords(elementConnect[0]);
5792 const std::array<double, 3> &vertexCoord_3 =
getVertexCoords(elementConnect[3]);
5794 for (
int d = 0; d < 3; ++d) {
5795 (*minPoint)[d] = std::min(vertexCoord_0[d], vertexCoord_3[d]);
5796 (*maxPoint)[d] = std::max(vertexCoord_0[d], vertexCoord_3[d]);
5802 case ElementType::VOXEL:
5804 const long *elementConnect = element.
getConnect();
5806 const std::array<double, 3> &vertexCoord_0 =
getVertexCoords(elementConnect[0]);
5807 const std::array<double, 3> &vertexCoord_7 =
getVertexCoords(elementConnect[7]);
5809 for (
int d = 0; d < 3; ++d) {
5810 (*minPoint)[d] = std::min(vertexCoord_0[d], vertexCoord_7[d]);
5811 (*maxPoint)[d] = std::max(vertexCoord_0[d], vertexCoord_7[d]);
5819 ConstProxyVector<long> elementVertexIds = element.
getVertexIds();
5820 const int nElementVertices = elementVertexIds.
size();
5823 *maxPoint = *minPoint;
5824 for (
int i = 1; i < nElementVertices; ++i) {
5825 const std::array<double, 3> &vertexCoord =
getVertexCoords(elementVertexIds[i]);
5826 for (
int d = 0; d < 3; ++d) {
5827 (*minPoint)[d] = std::min(vertexCoord[d], (*minPoint)[d]);
5828 (*maxPoint)[d] = std::max(vertexCoord[d], (*maxPoint)[d]);
5873 std::vector<long> faceVertexIds_A(nFaceVertices);
5874 std::vector<long> faceVertexIds_B(nFaceVertices);
5875 for (
int k = 0; k < nFaceVertices; ++k) {
5880 std::sort(faceVertexIds_A.begin(), faceVertexIds_A.end());
5881 std::sort(faceVertexIds_B.begin(), faceVertexIds_B.end());
5883 return (faceVertexIds_A == faceVertexIds_B);
5893 return m_adjacenciesBuildStrategy;
5903 m_adjacenciesBuildStrategy = status;
5919 bool areDirty =
false;
5920 for (
const auto &entry : m_alteredCells) {
5921 AlterationFlags cellAlterationFlags = entry.second;
5928#if BITPIT_ENABLE_MPI==1
5931 MPI_Allreduce(MPI_IN_PLACE, &areDirty, 1, MPI_C_BOOL, MPI_LOR, communicator);
5965 if (strategy == ADJACENCIES_NONE) {
5966 if (currentStrategy != ADJACENCIES_NONE) {
5974 if (currentStrategy != strategy) {
5995 if (currentStrategy == ADJACENCIES_NONE) {
6001 if (!adjacenciesDirty && !forcedUpdated) {
6006 if (adjacenciesDirty) {
6074 for (
Cell &cell : m_cells) {
6075 cell.resetAdjacencies(!release);
6089 if (currentStrategy == ADJACENCIES_NONE) {
6094 for (
const auto &entry : m_alteredCells) {
6095 AlterationFlags cellAlterationFlags = entry.second;
6100 long cellId = entry.first;
6101 Cell &cell = m_cells.at(cellId);
6107 for (
int face = nCellFaces - 1; face >= 0; --face) {
6110 for (
int i = nFaceAdjacencies - 1; i >= 0; --i) {
6111 long adjacency = faceAdjacencies[i];
6140 bool multipleMatchesAllowed = (dimension < 3);
6155 std::vector<CellHalfFace::Winding> matchingWindings;
6156 matchingWindings.push_back(CellHalfFace::WINDING_REVERSE);
6157 if (multipleMatchesAllowed) {
6158 matchingWindings.push_back(CellHalfFace::WINDING_NATURAL);
6162 long nDirtyAdjacenciesCells = 0;
6163 for (
const auto &entry : m_alteredCells) {
6164 AlterationFlags cellAlterationFlags = entry.second;
6169 ++nDirtyAdjacenciesCells;
6176 std::unique_ptr<PiercedStorage<bool, long>> dirtyAdjacenciesVertices;
6177 if (multipleMatchesAllowed && (nDirtyAdjacenciesCells !=
getCellCount())) {
6179 dirtyAdjacenciesVertices->fill(
false);
6180 for (
const auto &entry : m_alteredCells) {
6181 AlterationFlags cellAlterationFlags = entry.second;
6186 long cellId = entry.first;
6187 const Cell &cell = m_cells.at(cellId);
6188 ConstProxyVector<long> cellVertexIds = cell.
getVertexIds();
6189 for (
long vertexId : cellVertexIds) {
6190 dirtyAdjacenciesVertices->at(vertexId) =
true;
6205 std::vector<Cell *> processList;
6206 processList.reserve(nDirtyAdjacenciesCells);
6208 std::size_t nMaxHalfFaces = 0;
6209 for (
Cell &cell : m_cells) {
6211 long cellId = cell.getId();
6212 int nCellFaces = cell.getFaceCount();
6216 nMaxHalfFaces += nCellFaces;
6217 processList.push_back(&cell);
6222 bool isBorderCell =
false;
6223 for (
int face = 0; face < nCellFaces; face++) {
6224 if (cell.isFaceBorder(face)) {
6225 isBorderCell =
true;
6231 nMaxHalfFaces += nCellFaces;
6232 processList.push_back(&cell);
6243 if (multipleMatchesAllowed) {
6244 ConstProxyVector<long> cellVertexIds = cell.getVertexIds();
6246 int nCelldirtyAdjacenciesVertices = 0;
6247 bool futureNeighbourCandidate =
false;
6248 for (
long vertexId : cellVertexIds) {
6249 if (dirtyAdjacenciesVertices->at(vertexId)) {
6250 ++nCelldirtyAdjacenciesVertices;
6251 if (nCelldirtyAdjacenciesVertices >= dimension) {
6252 futureNeighbourCandidate =
true;
6258 if (futureNeighbourCandidate) {
6259 nMaxHalfFaces += nCellFaces;
6260 processList.push_back(&cell);
6266 std::unordered_set<CellHalfFace, CellHalfFace::Hasher> halfFaces;
6267 halfFaces.reserve(
static_cast<std::size_t
>(0.5 * nMaxHalfFaces));
6269 std::vector<std::pair<Cell *, int>> matchingAdjacencies;
6270 for (
Cell *cell : processList) {
6271 long cellId = cell->getId();
6272 const int nCellFaces = cell->getFaceCount();
6274 for (
int face = 0; face < nCellFaces; face++) {
6276 CellHalfFace halfFace(*cell, face);
6279 auto matchingHalfFaceItr = halfFaces.end();
6280 for (CellHalfFace::Winding winding : matchingWindings) {
6285 matchingHalfFaceItr = halfFaces.find(halfFace);
6286 if (matchingHalfFaceItr != halfFaces.end()) {
6296 if (matchingHalfFaceItr == halfFaces.end()) {
6297 halfFace.
setWinding(CellHalfFace::WINDING_NATURAL);
6298 halfFaces.insert(std::move(halfFace));
6303 const CellHalfFace &matchingHalfFace = *matchingHalfFaceItr;
6305 long matchingCellId = matchingCell.
getId();
6306 long matchingFace = matchingHalfFace.
getFace();
6315 if (!areCellAdjacenciesDirty && !areMatchingCellAdjacenciesDirty) {
6325 matchingAdjacencies.clear();
6326 matchingAdjacencies.emplace_back(std::make_pair<Cell *, int>(&matchingCell, matchingFace));
6327 if (multipleMatchesAllowed) {
6329 const long *machingFaceNeighs = matchingCell.
getAdjacencies(matchingFace);
6330 for (
int k = 0; k < nMachingFaceNeighs; ++k) {
6331 long neighId = machingFaceNeighs[k];
6332 if (neighId == cellId) {
6336 Cell &neigh = m_cells.at(neighId);
6338 matchingAdjacencies.emplace_back(std::make_pair<Cell *, int>(&neigh, std::move(neighFace)));
6350 for (
const std::pair<Cell *, int> &matchingAdjacency : matchingAdjacencies) {
6351 Cell *adjacentCell = matchingAdjacency.first;
6352 long adjacentCellId = adjacentCell->
getId();
6353 int adjacentFace = matchingAdjacency.second;
6355 cell->pushAdjacency(face, adjacentCellId);
6364 if (!multipleMatchesAllowed) {
6365 halfFaces.erase(matchingHalfFaceItr);
6378 return m_interfacesBuildStrategy;
6388 if (status == INTERFACES_AUTOMATIC) {
6390 throw std::runtime_error(
"Automatic build strategy requires auto-indexing.");
6394 m_interfacesBuildStrategy = status;
6410 bool areDirty = !m_alteredInterfaces.empty();
6412 for (
const auto &entry : m_alteredCells) {
6413 AlterationFlags cellAlterationFlags = entry.second;
6421#if BITPIT_ENABLE_MPI==1
6424 MPI_Allreduce(MPI_IN_PLACE, &areDirty, 1, MPI_C_BOOL, MPI_LOR, communicator);
6459 throw std::runtime_error (
"Adjacencies are mandatory for building the interfaces.");
6466 if (strategy == INTERFACES_NONE) {
6467 if (currentStrategy != INTERFACES_NONE) {
6475 if (currentStrategy != strategy) {
6496 if (currentStrategy == INTERFACES_NONE) {
6502 if (!interfacesDirty && !forcedUpdated) {
6511 if (interfacesDirty) {
6524 m_alteredInterfaces.clear();
6553 m_alteredInterfaces.clear();
6573 for (
const auto &entry : m_alteredCells) {
6574 AlterationFlags cellAlterationFlags = entry.second;
6579 long cellId = entry.first;
6580 Cell &cell = m_cells.at(cellId);
6586 for (
int face = nCellFaces - 1; face >= 0; --face) {
6589 for (
int i = nFaceInterfaces - 1; i >= 0; --i) {
6590 long interfaceId = faceInterfaces[i];
6602 std::vector<long> danglingInterfaces;
6603 danglingInterfaces.reserve(m_alteredInterfaces.size());
6604 for (
const auto &entry : m_alteredInterfaces) {
6605 AlterationFlags interfaceAlterationFlags = entry.second;
6610 long interfaceId = entry.first;
6611 danglingInterfaces.push_back(interfaceId);
6635 for (
const auto &entry : m_alteredCells) {
6636 AlterationFlags cellAlterationFlags = entry.second;
6641 long cellId = entry.first;
6642 Cell &cell = m_cells.at(cellId);
6644 for (
int face = 0; face < nCellFaces; face++) {
6648 if (!isFaceBorder) {
6651 int updateBegin = nFaceInterfaces;
6652 if (updateBegin == updateEnd) {
6658 for (
int k = updateBegin; k < updateEnd; ++k) {
6659 long neighId = faceAdjacencies[k];
6660 Cell *neigh = &m_cells[neighId];
6664 buildCellInterface(&cell, face, neigh, neighFace);
6666 }
else if (nFaceInterfaces == 0) {
6668 buildCellInterface(&cell, face,
nullptr, -1);
6688PatchKernel::InterfaceIterator PatchKernel::buildCellInterface(
Cell *cell_1,
int face_1,
Cell *cell_2,
int face_2,
long interfaceId)
6692 assert(face_1 >= 0);
6695 assert(face_2 >= 0);
6701 long id_1 = cell_1->
getId();
6704 long id_2 = Cell::NULL_ID;
6706 id_2 = cell_2->
getId();
6718 bool cellOwnsInterface =
true;
6721 cellOwnsInterface =
false;
6734 if (cellOwnsInterface) {
6737 intrOwnerFace = face_1;
6742 intrNeighFace = face_2;
6744 intrNeighId = Cell::NULL_ID;
6745 intrNeigh =
nullptr;
6751 intrOwnerFace = face_2;
6755 intrNeighFace = face_1;
6759 ConstProxyVector<long> faceConnect = intrOwner->getFaceConnect(intrOwnerFace);
6761 int nInterfaceVertices = faceConnect.size();
6762 std::unique_ptr<long[]> interfaceConnect = std::unique_ptr<long[]>(
new long[nInterfaceVertices]);
6763 for (
int k = 0; k < nInterfaceVertices; ++k) {
6764 interfaceConnect[k] = faceConnect[k];
6768 Interface *interface;
6769 InterfaceIterator interfaceIterator;
6771 ElementType interfaceType = intrOwner->getFaceType(intrOwnerFace);
6772 if (interfaceId < 0) {
6773 interfaceIterator =
addInterface(interfaceType, std::move(interfaceConnect), interfaceId);
6774 interface = &(*interfaceIterator);
6775 interfaceId = interface->getId();
6777 interfaceIterator =
restoreInterface(interfaceType, std::move(interfaceConnect), interfaceId);
6778 interface = &(*interfaceIterator);
6782 interface->setOwner(intrOwnerId, intrOwnerFace);
6783 if (intrNeighId >= 0) {
6784 interface->setNeigh(intrNeighId, intrNeighFace);
6802 intrOwner->pushInterface(intrOwnerFace, interfaceId);
6804 intrNeigh->pushInterface(intrNeighFace, interfaceId);
6807 int ownerInterfaceIndex = intrOwner->getInterfaceCount(intrOwnerFace) - 1;
6808 long ownerPairedAdjacency = intrOwner->getAdjacency(intrOwnerFace, ownerInterfaceIndex);
6809 if (ownerPairedAdjacency != intrNeighId) {
6810 int ownerPairedAdjacencyIndex = intrOwner->findAdjacency(intrOwnerFace, intrNeighId);
6811 assert(ownerPairedAdjacencyIndex >= 0);
6812 intrOwner->setAdjacency(intrOwnerFace, ownerInterfaceIndex, intrNeighId);
6813 intrOwner->setAdjacency(intrOwnerFace, ownerPairedAdjacencyIndex, ownerPairedAdjacency);
6817 int neighInterfaceIndex = intrNeigh->getInterfaceCount(intrNeighFace) - 1;
6818 long neighPairedAdjacency = intrNeigh->getAdjacency(intrNeighFace, neighInterfaceIndex);
6819 if (neighPairedAdjacency != intrOwnerId) {
6820 int neighPairedAdjacencyIndex = intrNeigh->findAdjacency(intrNeighFace, intrOwnerId);
6821 assert(neighPairedAdjacencyIndex >= 0);
6822 intrNeigh->setAdjacency(intrNeighFace, neighInterfaceIndex, intrOwnerId);
6823 intrNeigh->setAdjacency(intrNeighFace, neighPairedAdjacencyIndex, neighPairedAdjacency);
6827 return interfaceIterator;
6849 long cellId = cell.
getId();
6852 int nCandidates = 0;
6853 BITPIT_CREATE_WORKSPACE(candidates, std::array<int BITPIT_COMMA 3>, nNeighFaces, ReferenceElementInfo::MAX_ELEM_FACES);
6854 for (
int neighFace = 0; neighFace < nNeighFaces; neighFace++) {
6857 for (
int k = 0; k < nFaceAdjacencies; ++k) {
6858 long geussId = faceAdjacencies[k];
6859 if (geussId == cellId) {
6860 (*candidates)[nCandidates] = neighFace;
6868 if (nCandidates == 1) {
6869 return (*candidates)[0];
6871 for (
int i = 0; i < nCandidates; ++i) {
6872 int candidateFace = (*candidates)[i];
6873 if (
isSameFace(cell, cellFace, neigh, candidateFace)) {
6874 return candidateFace;
6891 return testElementAlterationFlags(
id, flags, m_alteredCells);
6902 return getElementAlterationFlags(
id, m_alteredCells);
6913 resetElementAlterationFlags(
id, flags, &m_alteredCells);
6924 for (CellConstIterator itr =
cellConstBegin(); itr != endItr; ++itr) {
6937 setElementAlterationFlags(
id, flags, &m_alteredCells);
6947 unsetElementAlterationFlags(flags, &m_alteredCells);
6958 unsetElementAlterationFlags(
id, flags, &m_alteredCells);
6970 return testElementAlterationFlags(
id, flags, m_alteredInterfaces);
6981 return getElementAlterationFlags(
id, m_alteredInterfaces);
6992 resetElementAlterationFlags(
id, flags, &m_alteredInterfaces);
7016 setElementAlterationFlags(
id, flags, &m_alteredInterfaces);
7026 unsetElementAlterationFlags(flags, &m_alteredInterfaces);
7037 unsetElementAlterationFlags(
id, flags, &m_alteredInterfaces);
7048bool PatchKernel::testElementAlterationFlags(
long id, AlterationFlags flags,
const AlterationFlagsStorage &flagsStorage)
const
7050 auto storedFlagsItr = flagsStorage.find(
id);
7051 if (storedFlagsItr != flagsStorage.end()) {
7067 return ((availableFlags & requestedFlags) == requestedFlags);
7077PatchKernel::AlterationFlags PatchKernel::getElementAlterationFlags(
long id,
const AlterationFlagsStorage &flagsStorage)
const
7079 auto storedFlagsItr = flagsStorage.find(
id);
7080 if (storedFlagsItr != flagsStorage.end()) {
7081 return storedFlagsItr->second;
7094void PatchKernel::resetElementAlterationFlags(
long id, AlterationFlags flags, AlterationFlagsStorage *flagsStorage)
const
7096 if (flags == FLAG_NONE) {
7097 flagsStorage->erase(
id);
7099 (*flagsStorage)[id] = flags;
7110void PatchKernel::setElementAlterationFlags(
long id, AlterationFlags flags, AlterationFlagsStorage *flagsStorage)
const
7112 if (flags == FLAG_NONE) {
7116 auto storedFlagsItr = flagsStorage->find(
id);
7117 if (storedFlagsItr != flagsStorage->end()) {
7118 storedFlagsItr->second |= flags;
7120 flagsStorage->insert({id, flags});
7130void PatchKernel::unsetElementAlterationFlags(AlterationFlags flags, AlterationFlagsStorage *flagsStorage)
const
7132 if (flags == FLAG_NONE) {
7136 for (
auto storedFlagsItr = flagsStorage->begin(); storedFlagsItr != flagsStorage->end();) {
7137 storedFlagsItr->second &= ~flags;
7138 if (storedFlagsItr->second == FLAG_NONE) {
7139 storedFlagsItr = flagsStorage->erase(storedFlagsItr);
7153void PatchKernel::unsetElementAlterationFlags(
long id, AlterationFlags flags, AlterationFlagsStorage *flagsStorage)
const
7155 if (flags == FLAG_NONE) {
7159 auto storedFlagsItr = flagsStorage->find(
id);
7160 if (storedFlagsItr == flagsStorage->end()) {
7164 storedFlagsItr->second &= ~flags;
7165 if (storedFlagsItr->second == FLAG_NONE) {
7166 flagsStorage->erase(storedFlagsItr);
7177 for (
int k = 0; k < 3; ++k) {
7178 m_boxMinPoint[k] = std::numeric_limits<double>::max();
7179 m_boxMinCounter[k] = 0;
7181 m_boxMaxPoint[k] = - std::numeric_limits<double>::max();
7182 m_boxMaxCounter[k] = 0;
7198 m_boxMinPoint = minPoint;
7199 m_boxMaxPoint = maxPoint;
7225 minPoint = m_boxMinPoint;
7226 maxPoint = m_boxMaxPoint;
7228#if BITPIT_ENABLE_MPI==1
7231 MPI_Allreduce(MPI_IN_PLACE, minPoint.data(), 3, MPI_DOUBLE, MPI_MIN, communicator);
7232 MPI_Allreduce(MPI_IN_PLACE, maxPoint.data(), 3, MPI_DOUBLE, MPI_MAX, communicator);
7261 m_boxFrozen = frozen;
7274#if BITPIT_ENABLE_MPI==1
7277 MPI_Allreduce(
const_cast<bool *
>(&m_boxDirty), &
isDirty, 1, MPI_C_BOOL, MPI_LOR, communicator);
7320 for (
const auto &vertex : m_vertices) {
7339 for (
size_t k = 0; k < point.size(); ++k) {
7340 double value = point[k];
7344 ++m_boxMaxCounter[k];
7345 }
else if (value > m_boxMaxPoint[k]) {
7346 m_boxMaxPoint[k] = value;
7347 m_boxMaxCounter[k] = 1;
7352 ++m_boxMinCounter[k];
7353 }
else if (value < m_boxMinPoint[k]) {
7354 m_boxMinPoint[k] = value;
7355 m_boxMinCounter[k] = 1;
7374 double tolerance =
getTol();
7375 for (
size_t k = 0; k < point.size(); ++k) {
7376 double value = point[k];
7380 --m_boxMaxCounter[k];
7381 if (m_boxMaxCounter[k] == 0) {
7385 }
else if (value > m_boxMaxPoint[k]) {
7386 assert(
false &&
"Bounding box is in inconsistent state.");
7393 --m_boxMinCounter[k];
7394 if (m_boxMinCounter[k] == 0) {
7398 }
else if (value < m_boxMinPoint[k]) {
7399 assert(
false &&
"Bounding box is in inconsistent state.");
7415 ConstProxyVector<long> elementVertexIds = element.
getVertexIds();
7416 const int nElementVertices = elementVertexIds.
size();
7419 ConstProxyVector<std::array<double, 3>> vertexCoordinates(ConstProxyVector<std::array<double, 3>>::INTERNAL_STORAGE, nElementVertices);
7420 ConstProxyVector<std::array<double, 3>>::storage_pointer storage = vertexCoordinates.
storedData();
7423 return vertexCoordinates;
7434 ConstProxyVector<long> elementVertexIds = element.
getVertexIds();
7448 ConstProxyVector<long> elementVertexIds = element.
getVertexIds();
7476 double dx = std::max(1.0e-12, m_boxMaxPoint[0] - m_boxMinPoint[0]) / ((double) nBins);
7477 double dy = std::max(1.0e-12, m_boxMaxPoint[1] - m_boxMinPoint[1]) / ((double) nBins);
7478 double dz = std::max(1.0e-12, m_boxMaxPoint[2] - m_boxMinPoint[2]) / ((double) nBins);
7481 std::unordered_map<long, std::vector<long>> bins;
7482 for (
const Vertex &vertex : vertices) {
7483 const std::array<double, 3> &coordinates = vertex.
getCoords();
7485 int i = std::min(nBins - 1L, (
long) ((coordinates[0] - m_boxMinPoint[0]) / dx));
7486 int j = std::min(nBins - 1L, (
long) ((coordinates[1] - m_boxMinPoint[1]) / dy));
7487 int k = std::min(nBins - 1L, (
long) ((coordinates[2] - m_boxMinPoint[2]) / dz));
7489 long binId = nBins * nBins * k + nBins * j + i;
7490 bins[binId].emplace_back(vertex.
getId());
7504 for (
auto &vertex : m_vertices) {
7510 m_boxMinPoint += translation;
7511 m_boxMaxPoint += translation;
7538 for (
auto &vertex : m_vertices) {
7539 vertex.
rotate(n0, n1, angle);
7545 std::array<std::array<double, 3>, 3> originalBox = {{m_boxMinPoint, m_boxMaxPoint}};
7554 for (
int i = 0; i < 2; ++i) {
7555 double xCorner = originalBox[i][0];
7556 for (
int j = 0; j < 2; ++j) {
7557 double yCorner = originalBox[j][1];
7558 for (
int k = 0; k < 2; ++k) {
7559 double zCorner = originalBox[k][2];
7561 std::array<double, 3> corner = {{xCorner, yCorner, zCorner}};
7583 double n1y,
double n1z,
double angle)
7585 rotate({{n0x, n0y, n0z}}, {{n1x, n1y, n1z}}, angle);
7597 scale(scaling, m_boxMinPoint);
7609 for (
auto &vertex : m_vertices) {
7610 vertex.
scale(scaling, center);
7615 for (
int k = 0; k < 3; ++k) {
7616 m_boxMinPoint[k] = center[k] + scaling[k] * (m_boxMinPoint[k] - center[k]);
7617 m_boxMaxPoint[k] = center[k] + scaling[k] * (m_boxMaxPoint[k] - center[k]);
7631 scale({{scaling, scaling, scaling}}, m_boxMinPoint);
7642 scale({{scaling, scaling, scaling}}, center);
7654 scale({{sx, sy, sz}}, m_boxMinPoint);
7669 scale({{sx, sy, sz}}, center);
7682 m_toleranceCustom =
true;
7693 m_tolerance = tolerance;
7713 m_toleranceCustom =
false;
7727 const double DEFAULT_TOLERANCE = 1e-14;
7729 m_tolerance = DEFAULT_TOLERANCE;
7740 return m_toleranceCustom;
7763 std::unordered_map<long, long> vertexMap;
7764 for (
const Cell &cell : m_cells) {
7765 int nCellFaces = cell.getFaceCount();
7766 for (
int i = 0; i < nCellFaces; ++i) {
7767 if (!cell.isFaceBorder(i)) {
7773 ConstProxyVector<long> faceConnect = cell.getFaceConnect(i);
7774 int nFaceVertices = faceConnect.
size();
7776 std::unique_ptr<long[]> faceEnvelopeConnect = std::unique_ptr<long[]>(
new long[nFaceVertices]);
7777 for (
int j = 0; j < nFaceVertices; ++j) {
7778 long vertexId = faceConnect[j];
7782 if (vertexMap.count(vertexId) == 0) {
7784 VertexIterator envelopeVertex = envelope.
addVertex(vertex);
7785 vertexMap[vertexId] = envelopeVertex->
getId();
7789 faceEnvelopeConnect[j] = vertexMap.
at(vertexId);
7794 envelope.
addCell(faceType, std::move(faceEnvelopeConnect));
7808 std::string indent = std::string(padding,
' ');
7813 out << indent<<
"Vertices --------------------------------" << std::endl;
7822 out << indent<<
"Faces -----------------------------------" << std::endl;
7823 out << indent<<
" # faces " <<
countFaces() << std::endl;
7829 out << indent<<
"Cells -----------------------------------" << std::endl;
7830 out << indent<<
" # cells " <<
getCellCount() << std::endl;
7845 std::string indent = std::string(padding,
' ');
7846 for (
const Vertex &vertex : m_vertices) {
7847 out << indent <<
"vertex: " << std::endl;
7848 vertex.
display(out, padding + 2);
7861 std::string indent = std::string(padding,
' ');
7862 for (
const Cell &cell : m_cells) {
7863 out << indent <<
"cell: " << std::endl;
7864 cell.display(out, padding + 2);
7877 std::string indent = std::string(padding,
' ');
7878 for (
const Interface &interface : m_interfaces) {
7879 out << indent <<
"interface: " << std::endl;
7880 interface.display(out, padding + 2);
7911 return m_vtkWriteTarget;
7921 m_vtkWriteTarget = writeTarget;
7931 if (m_vtkWriteTarget == WRITE_TARGET_CELLS_ALL) {
7933#if BITPIT_ENABLE_MPI==1
7934 }
else if (m_vtkWriteTarget == WRITE_TARGET_CELLS_INTERNAL) {
7955 std::vector<std::string> streamedGeomFields;
7963 streamedGeomFields.push_back(field.
getName());
7966 for (
const std::string &name : streamedGeomFields) {
7967 const VTKField &field = *(m_vtk.findGeomData(name));
7968 VTKField updatedField(field);
7969 updatedField.setStreamer(*updated);
7971 m_vtk.setGeomData(std::move(updatedField));
7974 std::vector<std::string> streamedDataFields;
7975 streamedDataFields.reserve(m_vtk.getDataCount());
7976 for (
auto itr = m_vtk.getDataBegin(); itr != m_vtk.getDataEnd(); ++itr) {
7977 const VTKField &field = *itr;
7978 if (&field.getStreamer() != original) {
7982 streamedDataFields.push_back(field.getName());
7985 for (
const std::string &name : streamedDataFields) {
7986 const VTKField &field = *(m_vtk.findData(name));
7987 VTKField updatedField(field);
7988 updatedField.setStreamer(*updated);
7990 m_vtk.removeData(field.getName());
7991 m_vtk.addData(std::move(updatedField));
8007 if (name ==
"Points") {
8010 std::size_t vertexRawId = itr.getRawIndex();
8011 long vertexVTKId = m_vtkVertexMap.rawAt(vertexRawId);
8012 if (vertexVTKId != Vertex::NULL_ID) {
8013 const Vertex &vertex = m_vertices.rawAt(vertexRawId);
8017 }
else if (name ==
"offsets") {
8020 offset += cell.getVertexCount();
8023 }
else if (name ==
"types") {
8026 switch (cell.getType()) {
8028 case ElementType::VERTEX:
8029 VTKType = VTKElementType::VERTEX;
8032 case ElementType::LINE:
8033 VTKType = VTKElementType::LINE;
8036 case ElementType::TRIANGLE:
8037 VTKType = VTKElementType::TRIANGLE;
8040 case ElementType::PIXEL:
8041 VTKType = VTKElementType::PIXEL;
8044 case ElementType::QUAD:
8045 VTKType = VTKElementType::QUAD;
8048 case ElementType::POLYGON:
8049 VTKType = VTKElementType::POLYGON;
8052 case ElementType::TETRA:
8053 VTKType = VTKElementType::TETRA;
8056 case ElementType::VOXEL:
8057 VTKType = VTKElementType::VOXEL;
8060 case ElementType::HEXAHEDRON:
8061 VTKType = VTKElementType::HEXAHEDRON;
8064 case ElementType::WEDGE:
8065 VTKType = VTKElementType::WEDGE;
8068 case ElementType::PYRAMID:
8069 VTKType = VTKElementType::PYRAMID;
8072 case ElementType::POLYHEDRON:
8073 VTKType = VTKElementType::POLYHEDRON;
8077 VTKType = VTKElementType::UNDEFINED;
8084 }
else if (name ==
"connectivity") {
8086 ConstProxyVector<long> cellVertexIds = cell.getVertexIds();
8087 const int nCellVertices = cellVertexIds.
size();
8088 for (
int k = 0; k < nCellVertices; ++k) {
8089 long vertexId = cellVertexIds[k];
8090 long vtkVertexId = m_vtkVertexMap.
at(vertexId);
8094 }
else if (name ==
"faces") {
8096 if (cell.getDimension() <= 2 || cell.hasInfo()) {
8099 std::vector<long> faceStream = cell.getFaceStream();
8101 int faceStreamSize = faceStream.size();
8102 for (
int k = 0; k < faceStreamSize; ++k) {
8107 }
else if (name ==
"faceoffsets") {
8110 if (cell.getDimension() <= 2 || cell.hasInfo()) {
8113 offset += cell.getFaceStreamSize();
8118 }
else if (name ==
"cellIndex") {
8122 }
else if (name ==
"PID") {
8126 }
else if (name ==
"vertexIndex") {
8129 std::size_t vertexRawId = itr.getRawIndex();
8130 long vertexVTKId = m_vtkVertexMap.rawAt(vertexRawId);
8131 if (vertexVTKId != Vertex::NULL_ID) {
8132 long vertexId = itr.getId();
8136#if BITPIT_ENABLE_MPI==1
8137 }
else if (name ==
"cellGlobalIndex") {
8138 PatchNumberingInfo numberingInfo(
this);
8142 }
else if (name ==
"cellRank") {
8146 }
else if (name ==
"cellHaloLayer") {
8150 }
else if (name ==
"vertexRank") {
8153 std::size_t vertexRawId = itr.getRawIndex();
8154 long vertexVTKId = m_vtkVertexMap.rawAt(vertexRawId);
8155 if (vertexVTKId != Vertex::NULL_ID) {
8174 for(
Cell &cell : m_cells) {
8175 cell.renumberVertices(map);
8180 interface.renumberVertices(map);
8185 createVertexIndexGenerator(
true);
8200 for (
auto &cell: m_cells) {
8201 long *adjacencies = cell.getAdjacencies();
8202 int nCellAdjacencies = cell.getAdjacencyCount();
8203 for (
int i = 0; i < nCellAdjacencies; ++i) {
8204 long &neighId = adjacencies[i];
8205 neighId = map[neighId];
8210 for (
Interface &interface: m_interfaces) {
8211 long ownerId = interface.getOwner();
8212 int ownerFace = interface.getOwnerFace();
8213 interface.setOwner(map.at(ownerId), ownerFace);
8215 long neighId = interface.getNeigh();
8217 int neighFace = interface.getNeighFace();
8218 interface.setNeigh(map.at(neighId), neighFace);
8223 if (m_lastInternalCellId >= 0) {
8224 m_lastInternalCellId = map.at(m_lastInternalCellId);
8227#if BITPIT_ENABLE_MPI==1
8228 if (m_firstGhostCellId >= 0) {
8229 m_firstGhostCellId = map.at(m_firstGhostCellId);
8235 createCellIndexGenerator(
true);
8238#if BITPIT_ENABLE_MPI==1
8241 updatePartitioningInfo(
true);
8257 for (
Cell &cell: m_cells) {
8258 long *interfaces = cell.getInterfaces();
8259 int nCellInterfaces = cell.getInterfaceCount();
8260 for (
int i = 0; i < nCellInterfaces; ++i) {
8261 long &interfaceId = interfaces[i];
8262 interfaceId = map.at(interfaceId);
8268 createInterfaceIndexGenerator(
true);
8294 const int KERNEL_DUMP_VERSION = 12;
8296 return (KERNEL_DUMP_VERSION + _getDumpVersion());
8315 return constPatch->
dump(stream);
8333 assert(!dirty &&
"Dumping a patch that is not up-to-date is not supported.");
8345#if BITPIT_ENABLE_MPI==1
8356#if BITPIT_ENABLE_MPI==1
8378 if (m_toleranceCustom) {
8385 if (hasVertexAutoIndexing) {
8386 dumpVertexAutoIndexing(stream);
8391 if (hasInterfaceAutoIndexing) {
8392 dumpInterfaceAutoIndexing(stream);
8397 if (hasCellAutoIndexing) {
8398 dumpCellAutoIndexing(stream);
8421 throw std::runtime_error (
"The version of the file does not match the required version");
8439 m_vtk.setName(name);
8442#if BITPIT_ENABLE_MPI==1
8454#if BITPIT_ENABLE_MPI==1
8477#if BITPIT_ENABLE_MPI==1
8480 updatePartitioningInfo(
true);
8485 int hasCustomTolerance;
8487 if (hasCustomTolerance) {
8496 bool hasVertexAutoIndexing;
8498 if (hasVertexAutoIndexing) {
8499 restoreVertexAutoIndexing(stream);
8504 bool hasInterfaceAutoIndexing;
8506 if (hasInterfaceAutoIndexing) {
8507 restoreInterfaceAutoIndexing(stream);
8512 bool hasCellAutoIndexing;
8514 if (hasCellAutoIndexing) {
8515 restoreCellAutoIndexing(stream);
8527void PatchKernel::mergeAdaptionInfo(std::vector<adaption::Info> &&source, std::vector<adaption::Info> &destination)
8529 if (source.empty()) {
8531 }
else if (destination.empty()) {
8532 destination.swap(source);
8536 throw std::runtime_error (
"Unable to merge the adaption info.");
The Cell class defines the cells.
bool isFaceBorder(int face) const
bool pushAdjacency(int face, long adjacency)
void deleteInterface(int face, int i)
int getInterfaceCount() const
const long * getAdjacencies() const
const long * getInterfaces() const
void deleteAdjacency(int face, int i)
int getAdjacencyCount() const
void setWinding(Winding winding)
The Element class provides an interface for defining elements.
ConstProxyVector< long > getFaceVertexIds(int face) const
static int getDimension(ElementType type)
ElementType getType() const
long getFaceVertexId(int face, int vertex) const
int findVertex(long vertexId) const
const ReferenceElementInfo & getInfo() const
ElementType getFaceType(int face) const
ConstProxyVector< int > getEdgeLocalConnect(int edge) const
long getEdgeVertexId(int edge, int vertex) const
static ConstProxyVector< long > getVertexIds(ElementType type, const long *connectivity)
int getFaceVertexCount(int face) const
const long * getConnect() const
long getVertexId(int vertex) const
static void renumberFaceStream(const PiercedStorage< long, long > &map, std::vector< long > *faceStream)
std::array< double, 3 > evalCentroid(const std::array< double, 3 > *coordinates) const
int getVertexCount() const
The Interface class defines the interfaces among cells.
The PatchKernel class provides an interface for defining patches.
void initializeAdjacencies(AdjacenciesBuildStrategy strategy=ADJACENCIES_AUTOMATIC)
VertexIterator vertexEnd()
void unsetCellAlterationFlags(AlterationFlags flags)
CellConstIterator cellConstBegin() const
Vertex & getLastInternalVertex()
CellIterator getCellIterator(long id)
void dumpInterfaces(std::ostream &stream) const
CellIterator internalCellBegin()
InterfacesBuildStrategy getInterfacesBuildStrategy() const
CellConstIterator internalConstBegin() const
virtual bool _enableCellBalancing(long id, bool enabled)
CellConstIterator internalCellConstEnd() const
CellIterator internalBegin()
AdjacenciesBuildStrategy getAdjacenciesBuildStrategy() const
virtual bool _markCellForRefinement(long id)
std::vector< long > getInternalCellsByPID(int pid)
void displayVertices(std::ostream &out, unsigned int padding=0) const
int getVertexOwner(long id) const
InterfaceIterator restoreInterface(ElementType type, std::unique_ptr< long[]> &&connectStorage, long id)
std::unordered_map< id_t, id_t > consecutiveItemRenumbering(PiercedVector< item_t, id_t > &container, long offset)
virtual void _findCellEdgeNeighs(long id, int edge, const std::vector< long > *blackList, std::vector< long > *neighs) const
void markCellForRefinement(long id)
std::vector< long > findVertexOneRing(long vertexId) const
virtual std::array< double, 3 > evalInterfaceCentroid(long id) const
void setCellAutoIndexing(bool enabled)
virtual long getInterfaceCount() const
std::vector< adaption::Info > update(bool trackAdaption=true, bool squeezeStorage=false)
bool intersectInterfacePlane(long id, std::array< double, 3 > P, std::array< double, 3 > nP, std::array< std::array< double, 3 >, 2 > *intersection, std::vector< std::array< double, 3 > > *polygon) const
InterfaceIterator interfaceBegin()
PiercedVector< Cell > & getCells()
std::vector< long > findOrphanInterfaces() const
bool testAlterationFlags(AlterationFlags availableFlags, AlterationFlags requestedFlags) const
VertexConstIterator vertexConstEnd() const
void dumpVertices(std::ostream &stream) const
virtual void _writeFinalize()
InterfaceIterator interfaceEnd()
void destroyAdjacencies()
void pruneStaleAdjacencies()
Interface & getInterface(long id)
PatchKernel(PatchKernel &&other)
void updateFirstGhostCellId()
virtual void _resetInterfaces(bool release)
VertexIterator restoreVertex(const std::array< double, 3 > &coords, int owner, long id)
AdaptionMode getAdaptionMode() const
CellIterator restoreCell(ElementType type, std::unique_ptr< long[]> &&connectStorage, int owner, int haloLayer, long id)
void setExpert(bool expert)
long countBorderInterfaces() const
InterfaceIterator addInterface(const Interface &source, long id=Element::NULL_ID)
void dumpCells(std::ostream &stream) const
void setBoundingBoxDirty(bool dirty)
CellConstIterator internalCellConstBegin() const
bool isVertexAutoIndexingEnabled() const
virtual void _writePrepare()
VertexIterator vertexBegin()
InterfaceConstIterator interfaceConstEnd() const
InterfaceConstIterator interfaceConstBegin() const
std::vector< long > collapseCoincidentVertices()
void consecutiveRenumberInterfaces(long offset=0)
bool isCellAutoIndexingEnabled() const
VertexConstIterator vertexConstBegin() const
WriteTarget getVTKWriteTarget() const
virtual long getVertexCount() const
bool deleteCoincidentVertices()
long countOrphanInterfaces() const
virtual void evalCellBoundingBox(long id, std::array< double, 3 > *minPoint, std::array< double, 3 > *maxPoint) const
void restoreCells(std::istream &stream)
virtual void _findCellFaceNeighs(long id, int face, const std::vector< long > *blackList, std::vector< long > *neighs) const
void addPointToBoundingBox(const std::array< double, 3 > &point)
std::vector< long > findDuplicateCells() const
virtual ElementType getInterfaceType(long id) const
VertexIterator addVertex(const Vertex &source, long id=Vertex::NULL_ID)
bool empty(bool global=true) const
std::vector< long > findCellNeighs(long id) const
bool deleteVertex(long id)
void getBoundingBox(std::array< double, 3 > &minPoint, std::array< double, 3 > &maxPoint) const
std::vector< adaption::Info > adaptionPrepare(bool trackAdaption=true)
adaption::Marker getCellAdaptionMarker(long id)
VTKUnstructuredGrid & getVTK()
std::unordered_map< long, std::vector< long > > binGroupVertices(const PiercedVector< Vertex > &vertices, int nBins)
void setBoundingBoxFrozen(bool frozen)
virtual bool isSameFace(const Cell &cell_A, int face_A, const Cell &cell_B, int face_B) const
const CellConstRange getVTKCellWriteRange() const
virtual bool _resetCellAdaptionMarker(long id)
void consecutiveRenumberCells(long offset=0)
virtual void simulateCellUpdate(const long id, adaption::Marker marker, std::vector< Cell > *virtualCells, PiercedVector< Vertex, long > *virtualVertices) const
void setVertexAutoIndexing(bool enabled)
VertexIterator getVertexIterator(long id)
VertexConstIterator getVertexConstIterator(long id) const
PiercedVector< Vertex > & getVertices()
virtual bool _markCellForCoarsening(long id)
std::vector< long > findCellFaceNeighs(long id) const
virtual void _setTol(double tolerance)
bool deleteVertices(const IdStorage &ids)
long locatePoint(double x, double y, double z) const
Cell & getLastInternalCell()
InterfaceConstIterator getInterfaceConstIterator(long id) const
void flushData(std::fstream &stream, const std::string &name, VTKFormat format) override
virtual adaption::Marker _getCellAdaptionMarker(long id)
CellIterator addCell(const Cell &source, long id=Element::NULL_ID)
void evalElementBoundingBox(const Element &element, std::array< double, 3 > *minPoint, std::array< double, 3 > *maxPoint) const
void resetCellAlterationFlags(long id, AlterationFlags flags=FLAG_NONE)
void updateInterfaces(bool forcedUpdated=false)
void displayTopologyStats(std::ostream &out, unsigned int padding=0) const
virtual void rotate(const std::array< double, 3 > &n0, const std::array< double, 3 > &n1, double angle)
ConstProxyVector< std::array< double BITPIT_COMMA 3 > > getElementVertexCoordinates(const Element &element) const
long countBorderCells() const
void setTol(double tolerance)
CellConstIterator cellConstEnd() const
AlterationFlags getCellAlterationFlags(long id) const
void scale(const std::array< double, 3 > &scaling)
virtual void setDimension(int dimension)
void markCellForCoarsening(long id)
void restoreVertices(std::istream &stream)
virtual void translate(const std::array< double, 3 > &translation)
VertexConstIterator internalVertexConstEnd() const
bool arePartitioningInfoDirty(bool global=true) const
void setInterfaceAutoIndexing(bool enabled)
void setAdaptionStatus(AdaptionStatus status)
bool isInterfaceAutoIndexingEnabled() const
PatchKernel & operator=(PatchKernel &&other)
void setAdjacenciesBuildStrategy(AdjacenciesBuildStrategy status)
void updateLastInternalVertexId()
VertexIterator internalVertexEnd()
bool reserveInterfaces(size_t nInterfaces)
long countDuplicateCells() const
bool areInterfacesDirty(bool global=false) const
bool deleteOrphanInterfaces()
void setInterfacesBuildStrategy(InterfacesBuildStrategy status)
const MPI_Comm & getCommunicator() const
void updateBoundingBox(bool forcedUpdated=false)
void restore(std::istream &stream, bool reregister=false)
virtual void resetVertices()
virtual int findAdjoinNeighFace(const Cell &cell, int cellFace, const Cell &neigh) const
virtual void resetInterfaces()
long countFreeVertices() const
void updateFirstGhostVertexId()
long countFreeCells() const
virtual void _updateAdjacencies()
void initializeInterfaces(InterfacesBuildStrategy strategy=INTERFACES_AUTOMATIC)
CellIterator internalEnd()
void enableCellBalancing(long id, bool enabled)
virtual void _resetAdjacencies(bool release)
void setVTKWriteTarget(WriteTarget targetCells)
bool isPartitioned() const
void displayCells(std::ostream &out, unsigned int padding=0) const
int getDumpVersion() const
bool testInterfaceAlterationFlags(long id, AlterationFlags flags) const
Vertex & getVertex(long id)
std::set< int > getInternalCellPIDs()
long countOrphanVertices() const
void restoreInterfaces(std::istream &stream)
virtual long getCellCount() const
void unsetInterfaceAlterationFlags(AlterationFlags flags)
virtual void _adaptionCleanup()
bool isBoundingBoxFrozen() const
void removePointFromBoundingBox(const std::array< double, 3 > &point)
void resetCellAdaptionMarker(long id)
std::vector< long > findCellVertexNeighs(long id, bool complete=true) const
void setAdaptionMode(AdaptionMode mode)
bool deleteOrphanVertices()
int getCellHaloLayer(long id) const
bool deleteInterface(long id)
virtual void _findCellNeighs(long id, const std::vector< long > *blackList, std::vector< long > *neighs) const
const std::array< double, 3 > & getVertexCoords(long id) const
virtual long _getCellNativeIndex(long id) const
long countOrphanCells() const
bool dump(std::ostream &stream)
void write(VTKWriteMode mode=VTKWriteMode::DEFAULT)
virtual void _updateInterfaces()
virtual void evalInterfaceBoundingBox(long id, std::array< double, 3 > *minPoint, std::array< double, 3 > *maxPoint) const
void updateAdjacencies(bool forcedUpdated=false)
ConstProxyVector< std::array< double BITPIT_COMMA 3 > > getInterfaceVertexCoordinates(long id) const
bool areAdjacenciesDirty(bool global=false) const
virtual void settleAdaptionMarkers()
VertexConstIterator internalVertexConstBegin() const
long countBorderVertices() const
InterfaceIterator getInterfaceIterator(long id)
AdaptionStatus getAdaptionStatus(bool global=false) const
long getInternalCount() const
bool isDirty(bool global=false) const
std::vector< long > findCellEdgeNeighs(long id, bool complete=true) const
VertexIterator internalVertexBegin()
long countFreeInterfaces() const
bool isTolCustomized() const
CellConstIterator internalConstEnd() const
void consecutiveRenumberVertices(long offset=0)
void extractEnvelope(PatchKernel &envelope) const
long getInternalCellCount() const
std::vector< long > findOrphanCells() const
void displayInterfaces(std::ostream &out, unsigned int padding=0) const
bool isInterfaceOrphan(long id) const
std::vector< adaption::Info > adaption(bool trackAdaption=true, bool squeezeStorage=false)
virtual std::vector< adaption::Info > _adaptionPrepare(bool trackAdaption)
PiercedVector< Interface > & getInterfaces()
virtual ElementType getCellType(long id) const
void setInterfaceAlterationFlags(AlterationFlags flags)
bool testCellAlterationFlags(long id, AlterationFlags flags) const
long getInternalVertexCount() const
long countBorderFaces() const
bool findFaceNeighCell(long cellId, long neighId, int *cellFace, int *cellAdjacencyId) const
void consecutiveRenumber(long offsetVertices, long offsetCells, long offsetInterfaces)
virtual std::vector< adaption::Info > _adaptionAlter(bool trackAdaption)
std::array< double, 3 > evalElementCentroid(const Element &element) const
virtual std::array< double, 3 > evalCellCentroid(long id) const
std::vector< long > findOrphanVertices()
bool reserveCells(size_t nCells)
AlterationFlags getInterfaceAlterationFlags(long id) const
bool isBoundingBoxDirty(bool global=false) const
void resetInterfaceAlterationFlags(long id, AlterationFlags flags=FLAG_NONE)
void updateLastInternalCellId()
void setCellAlterationFlags(AlterationFlags flags)
bool reserveVertices(size_t nVertices)
void setBoundingBox(const std::array< double, 3 > &minPoint, const std::array< double, 3 > &maxPoint)
long countFreeFaces() const
std::vector< long > findCellVertexOneRing(long id, int vertex) const
CellIterator internalCellEnd()
bool isAdaptionSupported() const
CellConstIterator getCellConstIterator(long id) const
ConstProxyVector< std::array< double BITPIT_COMMA 3 > > getCellVertexCoordinates(long id) const
virtual void resetCells()
int getCellOwner(long id) const
void pruneStaleInterfaces()
std::vector< adaption::Info > adaptionAlter(bool trackAdaption=true, bool squeezeStorage=false)
virtual void _findCellVertexNeighs(long id, int vertex, const std::vector< long > *blackList, std::vector< long > *neighs) const
bool isThreeDimensional() const
bool deleteInterfaces(const IdStorage &ids)
long getCellGlobalId(long id) const
id_t getId(const id_t &fallback=-1) const noexcept
Metafunction for generating a pierced storage.
__PS_REFERENCE__ at(id_t id, std::size_t k=0)
__PS_REFERENCE__ rawAt(std::size_t pos, std::size_t offset=0)
void fill(const value_t &value)
iterator find(const id_t &id) noexcept
Metafunction for generating a pierced vector.
PiercedVectorStorage< value_t, id_t >::iterator iterator
__PXV_POINTER__ data() noexcept
__PXV_STORAGE_POINTER__ storedData() noexcept
__PXV_REFERENCE__ at(std::size_t n)
QualifiedCell & getCell() const
The Reference2DElementInfo class allows to define information about reference two-dimensional element...
virtual int getCCWOrderedVertex(int n) const
The ReferenceElementInfo class allows to define information about reference elements.
static bool hasInfo(ElementType type)
static BITPIT_PUBLIC_API const ReferenceElementInfo & getInfo(ElementType type)
The base class to be used to derive VTK streamers form.
void flushValue(std::fstream &, VTKFormat, const T &value) const
VTKField handles geometry and data field information for the VTK format.
const std::string & getName() const
const VTKBaseStreamer & getStreamer() const
VTK input output for Unstructured Meshes.
std::vector< VTKField >::const_iterator getGeomDataBegin() const
std::vector< VTKField >::const_iterator getGeomDataEnd() const
std::size_t getGeomDataCount() const
The Vertex class defines the vertexs.
void translate(const std::array< double, 3 > &translation)
void display(std::ostream &out, unsigned short int indent) const
void scale(const std::array< double, 3 > &scaling, const std::array< double, 3 > ¢er)
void rotate(const std::array< double, 3 > &n0, const std::array< double, 3 > &n1, double angle)
std::array< double, 3 > & getCoords()
bool intersectPlaneTriangle(array3D const &P0, array3D const &P1, array3D const &P2, array3D const &Pp, array3D const &nP, std::array< array3D, 2 > &intersection, std::array< int, 2 > &edges_of_intersection, const double distanceTolerance=DEFAULT_COPLANARITY_TOLERANCE)
bool intersectPlanePixel(array3D const &Pp, array3D const &nP, array3D const *V, std::array< array3D, 2 > &intersection, std::array< int, 2 > &edges_of_intersection, const double distanceTolerance=DEFAULT_COPLANARITY_TOLERANCE)
bool intersectSegmentPlane(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
array3D rotatePoint(const array3D &P, const array3D &n0, const array3D &n1, double angle)
bool intersectPlanePolygon(array3D const &P, array3D const &nP, std::size_t nV, array3D const *V, std::vector< std::array< array3D, 2 > > &Qs, std::vector< std::array< int, 2 > > &edges_of_Qs, const double distanceTolerance=DEFAULT_COPLANARITY_TOLERANCE)
T dotProduct(const std::array< T, d > &x, const std::array< T, d > &y)
double norm2(const std::array< T, d > &x)
void write(std::ostream &stream, const std::vector< bool > &container)
void read(std::istream &stream, std::vector< bool > &container)
#define BITPIT_UNUSED(variable)
#define BITPIT_CREATE_WORKSPACE(workspace, item_type, size, stack_size)
Logger & cout(log::Level defaultSeverity, log::Visibility defaultVisibility)