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);
147 setDimension(dimension);
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> updateInfo;
633 if (!squeezeStorage && !
isDirty(
true)) {
638 finalizeAlterations(squeezeStorage);
643 mergeAdaptionInfo(
adaption(trackAdaption, squeezeStorage), updateInfo);
666 throw std::runtime_error (
"This function has not been implemented for the specified patch.");
681 std::vector<adaption::Info> adaptionInfo;
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> adaptionInfo;
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> adaptionInfo;
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();
1061 for (
auto &cell : m_cells) {
1062 cell.resetInterfaces(!release);
1065 m_interfaces.clear(release);
1066 if (m_interfaceIdGenerator) {
1067 m_interfaceIdGenerator->reset();
1090 m_vertices.reserve(nVertices);
1113 m_cells.reserve(nCells);
1138 m_interfaces.reserve(nInterfaces);
1151 std::string oldFilename = m_vtk.
getName();
1167 std::string oldFilename = m_vtk.
getName();
1198 m_vtk.
write(mode, time);
1209 long vtkCellCount = 0;
1210 if (m_vtkWriteTarget == WRITE_TARGET_CELLS_ALL) {
1212#if BITPIT_ENABLE_MPI==1
1213 }
else if (m_vtkWriteTarget == WRITE_TARGET_CELLS_INTERNAL) {
1224 vertexWriteFlag.
fill(
false);
1226 bool vtkFaceStreamNeeded =
false;
1227 for (
const Cell &cell : m_cells) {
1228 if (cell.getDimension() > 2 && !cell.hasInfo()) {
1229 vtkFaceStreamNeeded =
true;
1234#if BITPIT_ENABLE_MPI==1
1237 MPI_Allreduce(MPI_IN_PLACE, &vtkFaceStreamNeeded, 1, MPI_C_BOOL, MPI_LOR, communicator);
1241 long vtkConnectSize = 0;
1242 long vtkFaceStreamSize = 0;
1245 const int nCellVertices = cellVertexIds.
size();
1246 for (
int k = 0; k < nCellVertices; ++k) {
1247 long vertexId = cellVertexIds[k];
1248 vertexWriteFlag.
at(vertexId) =
true;
1251 vtkConnectSize += nCellVertices;
1252 if (vtkFaceStreamNeeded) {
1253 if (cell.getDimension() <= 2 || cell.hasInfo()) {
1254 vtkFaceStreamSize += 1;
1256 vtkFaceStreamSize += cell.getFaceStreamSize();
1261 int vtkVertexCount = 0;
1266 std::size_t vertexRawId = itr.getRawIndex();
1267 if (vertexWriteFlag.
rawAt(vertexRawId)) {
1268 m_vtkVertexMap.
rawAt(vertexRawId) = vtkVertexCount++;
1270 m_vtkVertexMap.
rawAt(vertexRawId) = Vertex::NULL_ID;
1274 m_vtk.
setDimensions(vtkCellCount, vtkVertexCount, vtkConnectSize, vtkFaceStreamSize);
1314 return m_adaptionMode;
1326 m_adaptionMode = mode;
1340 int adaptionStatus =
static_cast<int>(m_adaptionStatus);
1342#if BITPIT_ENABLE_MPI==1
1345 MPI_Allreduce(MPI_IN_PLACE, &adaptionStatus, 1, MPI_INT, MPI_MAX, communicator);
1361 m_adaptionStatus = status;
1374#if BITPIT_ENABLE_MPI==0
1385 isDirty |= !m_alteredCells.empty();
1390 assert(
isDirty || m_alteredInterfaces.empty());
1401#if BITPIT_ENABLE_MPI==1
1408 isDirty |= !m_vertices.isSynced();
1412 isDirty |= !m_cells.isSynced();
1416 isDirty |= !m_interfaces.isSynced();
1419#if BITPIT_ENABLE_MPI==1
1423 MPI_Allreduce(MPI_IN_PLACE, &
isDirty, 1, MPI_C_BOOL, MPI_LOR, communicator);
1443 initialAdaptionMode = m_adaptionMode;
1446 m_adaptionMode = initialAdaptionMode;
1485void PatchKernel::_setId(
int id)
1507 if (dimension == m_dimension) {
1512 if (m_dimension > 0) {
1517 m_dimension = dimension;
1537 return (m_dimension == 3);
1550 return static_cast<bool>(m_vertexIdGenerator);
1568 createVertexIndexGenerator(
true);
1570 m_vertexIdGenerator.reset();
1579void PatchKernel::dumpVertexAutoIndexing(std::ostream &stream)
const
1581 m_vertexIdGenerator->dump(stream);
1589void PatchKernel::restoreVertexAutoIndexing(std::istream &stream)
1591 createVertexIndexGenerator(
false);
1592 m_vertexIdGenerator->restore(stream);
1603void PatchKernel::createVertexIndexGenerator(
bool populate)
1606 if (!m_vertexIdGenerator) {
1607 m_vertexIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>());
1609 m_vertexIdGenerator->reset();
1614 VertexConstIterator beginItr = m_vertices.cbegin();
1615 VertexConstIterator endItr = m_vertices.cend();
1616 for (VertexConstIterator itr = beginItr; itr != endItr; ++itr) {
1617 m_vertexIdGenerator->setAssigned(itr.getId());
1630void PatchKernel::importVertexIndexGenerator(
const PatchKernel &source)
1632 if (source.m_vertexIdGenerator) {
1633 m_vertexIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>(*(source.m_vertexIdGenerator)));
1635 m_vertexIdGenerator.reset();
1646 return m_vertices.size();
1656 return m_nInternalVertices;
1687 return m_vertices[id];
1698 return m_vertices[id];
1708 return m_vertices[m_lastInternalVertexId];
1718 return m_vertices[m_lastInternalVertexId];
1728 return m_vertices.find(
id);
1738 return m_vertices.begin();
1748 return m_vertices.end();
1758 return m_vertices.begin();
1768 if (m_nInternalVertices > 0) {
1769 return ++m_vertices.find(m_lastInternalVertexId);
1771 return m_vertices.end();
1782 return m_vertices.find(
id);
1792 return m_vertices.cbegin();
1802 return m_vertices.cend();
1812 return m_vertices.cbegin();
1822 if (m_nInternalVertices > 0) {
1823 return ++m_vertices.find(m_lastInternalVertexId);
1825 return m_vertices.end();
1852 return addVertex(std::move(vertex),
id);
1876 id = source.
getId();
1887 VertexIterator iterator = _addInternalVertex(source.getCoords(),
id);
1894 source.setId(iterator->getId());
1895 source.setInterior(
true);
1897 Vertex &vertex = (*iterator);
1898 vertex = std::move(source);
1947PatchKernel::VertexIterator PatchKernel::_addInternalVertex(
const std::array<double, 3> &coords,
long id)
1950 if (m_vertexIdGenerator) {
1952 id = m_vertexIdGenerator->generate();
1954 m_vertexIdGenerator->setAssigned(
id);
1956 }
else if (
id < 0) {
1957 throw std::runtime_error(
"No valid id has been provided for the vertex.");
1961#if BITPIT_ENABLE_MPI==1
1967#if BITPIT_ENABLE_MPI==1
1968 referenceId = m_firstGhostVertexId;
1970 referenceId = Vertex::NULL_ID;
1974 VertexIterator iterator;
1975 if (referenceId == Vertex::NULL_ID) {
1976 iterator = m_vertices.emreclaim(
id,
id, coords,
true);
1978 iterator = m_vertices.emreclaimBefore(referenceId,
id,
id, coords,
true);
1980 m_nInternalVertices++;
1983 if (m_lastInternalVertexId < 0) {
1984 m_lastInternalVertexId = id;
1985 }
else if (m_vertices.rawIndex(m_lastInternalVertexId) < m_vertices.rawIndex(
id)) {
1986 m_lastInternalVertexId = id;
1992#if BITPIT_ENABLE_MPI==1
1994 setPartitioningInfoDirty(
true);
2000#if BITPIT_ENABLE_MPI==0
2017 VertexIterator iterator = m_vertices.find(
id);
2018 if (iterator == m_vertices.end()) {
2019 throw std::runtime_error(
"Unable to restore the specified vertex: the kernel doesn't contain an entry for that vertex.");
2022 _restoreInternalVertex(iterator, coords);
2034void PatchKernel::_restoreInternalVertex(
const VertexIterator &iterator,
const std::array<double, 3> &coords)
2040 Vertex &vertex = *iterator;
2041 vertex.initialize(iterator.getId(), coords,
true);
2042 m_nInternalVertices++;
2060#if BITPIT_ENABLE_MPI==1
2061 const Vertex &vertex = m_vertices[id];
2064 _deleteInternalVertex(
id);
2066 _deleteGhostVertex(
id);
2069 _deleteInternalVertex(
id);
2080void PatchKernel::_deleteInternalVertex(
long id)
2083 const Vertex &vertex = m_vertices[id];
2087 m_vertices.erase(
id,
true);
2088 m_nInternalVertices--;
2089 if (
id == m_lastInternalVertexId) {
2094 if (m_vertexIdGenerator) {
2095 m_vertexIdGenerator->trash(
id);
2120 std::unordered_set<long> borderVertices;
2121 for (
const Cell &cell : m_cells) {
2122 int nCellFaces = cell.getFaceCount();
2123 for (
int i = 0; i < nCellFaces; ++i) {
2124 if (!cell.isFaceBorder(i)) {
2128 int nFaceVertices = cell.getFaceVertexCount(i);
2129 for (
int k = 0; k < nFaceVertices; ++k) {
2130 long faceVertexId = cell.getFaceVertexId(i, k);
2131 borderVertices.insert(faceVertexId);
2136 return borderVertices.size();
2148 std::unordered_set<long> usedVertices;
2149 for (
const Cell &cell : m_cells) {
2151 int nCellVertices = cellVertexIds.
size();
2152 for (
int i = 0; i < nCellVertices; ++i) {
2153 usedVertices.insert(cellVertexIds[i]);
2174 vertexUsedFlag.
fill(
false);
2175 for (
const Cell &cell : m_cells) {
2177 int nCellVertices = cellVertexIds.
size();
2178 for (
int j = 0; j < nCellVertices; ++j) {
2179 long vertexId = cellVertexIds[j];
2180 vertexUsedFlag[vertexId] =
true;
2185 std::size_t nOrhpanVertices = 0;
2187 std::size_t vertexRawIndex = itr.getRawIndex();
2188 if (!vertexUsedFlag.
rawAt(vertexRawIndex)) {
2194 std::vector<long> orhpanVertices(nOrhpanVertices);
2196 std::size_t orphanVertexIndex = 0;
2198 std::size_t vertexRawIndex = itr.getRawIndex();
2199 if (!vertexUsedFlag.
rawAt(vertexRawIndex)) {
2200 orhpanVertices[orphanVertexIndex] = itr.getId();
2201 ++orphanVertexIndex;
2205 return orhpanVertices;
2232 std::vector<long> collapsedVertices;
2234 return collapsedVertices;
2238 if (nVertices == 0) {
2239 return collapsedVertices;
2248 Vertex::Less vertexLess(10 * std::numeric_limits<double>::epsilon());
2249 auto rawVertexLess = [
this, &vertexLess](
const std::size_t &i,
const std::size_t &j)
2251 return vertexLess(this->m_vertices.rawAt(i), this->m_vertices.rawAt(j));
2253 std::set<std::size_t,
decltype(rawVertexLess)> vertexTree(rawVertexLess);
2255 std::unordered_map<long, long> vertexMap;
2256 for (
VertexConstIterator vertexItr = m_vertices.cbegin(); vertexItr != m_vertices.cend(); ++vertexItr) {
2257 std::size_t vertexRawId = vertexItr.getRawIndex();
2258 auto vertexTreeItr = vertexTree.find(vertexRawId);
2259 if (vertexTreeItr == vertexTree.end()) {
2260 vertexTree.insert(vertexRawId);
2262 long vertexId = vertexItr.getId();
2263 long vertexCoincidentId = m_vertices.rawFind(*vertexTreeItr).getId();
2264 vertexMap.insert({vertexId, vertexCoincidentId});
2269 if (!vertexMap.empty()) {
2275 bool keepAdjacenciesUpToDate;
2276 if (adjacenciesBuildStrategy != ADJACENCIES_NONE) {
2279 keepAdjacenciesUpToDate =
false;
2282 for (
Cell &cell : m_cells) {
2284 int nRenumberedVertices = cell.renumberVertices(vertexMap);
2290 if ((adjacenciesBuildStrategy != ADJACENCIES_NONE) && (nRenumberedVertices > 0)) {
2295 if (keepAdjacenciesUpToDate) {
2300 for (
Interface &interface : m_interfaces) {
2302 interface.renumberVertices(vertexMap);
2306 collapsedVertices.resize(vertexMap.size());
2309 for (
const auto &entry : vertexMap) {
2310 collapsedVertices[k++] = entry.first;
2314 return collapsedVertices;
2352 *coordinates = std::unique_ptr<std::array<double, 3>[]>(
new std::array<double, 3>[nVertices]);
2367 for (std::size_t i = 0; i < nVertices; ++i) {
2382#if BITPIT_ENABLE_MPI==1
2384 MPI_Allreduce(MPI_IN_PLACE, &isEmpty, 1, MPI_C_BOOL, MPI_LAND,
getCommunicator());
2398 if (m_nInternalVertices == 0) {
2399 m_lastInternalVertexId = Vertex::NULL_ID;
2404#if BITPIT_ENABLE_MPI==1
2405 if (m_nGhostVertices == 0) {
2406 lastInternalVertexItr = --m_vertices.end();
2407 m_lastInternalVertexId = lastInternalVertexItr->
getId();
2409 m_lastInternalVertexId = m_vertices.getSizeMarker(m_nInternalVertices - 1, Vertex::NULL_ID);
2412 lastInternalVertexItr = --m_vertices.end();
2413 m_lastInternalVertexId = lastInternalVertexItr->
getId();
2427 return static_cast<bool>(m_cellIdGenerator);
2445 createCellIndexGenerator(
true);
2447 m_cellIdGenerator.reset();
2456void PatchKernel::dumpCellAutoIndexing(std::ostream &stream)
const
2458 m_cellIdGenerator->dump(stream);
2466void PatchKernel::restoreCellAutoIndexing(std::istream &stream)
2468 createCellIndexGenerator(
false);
2469 m_cellIdGenerator->restore(stream);
2480void PatchKernel::createCellIndexGenerator(
bool populate)
2483 if (!m_cellIdGenerator) {
2484 m_cellIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>());
2486 m_cellIdGenerator->reset();
2491 CellConstIterator beginItr = m_cells.cbegin();
2492 CellConstIterator endItr = m_cells.cend();
2493 for (CellConstIterator itr = beginItr; itr != endItr; ++itr) {
2494 m_cellIdGenerator->setAssigned(itr.getId());
2507void PatchKernel::importCellIndexGenerator(
const PatchKernel &source)
2509 if (source.m_cellIdGenerator) {
2510 m_cellIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>(*(source.m_cellIdGenerator)));
2512 m_cellIdGenerator.reset();
2523 return m_cells.size();
2533 return m_nInternalCells;
2596 return m_cells[id].getType();
2606 return m_cells[m_lastInternalCellId];
2616 return m_cells[m_lastInternalCellId];
2626 return m_cells.find(
id);
2636 return m_cells.begin();
2646 return m_cells.end();
2656 return m_cells.begin();
2676 if (m_nInternalCells > 0) {
2677 return ++m_cells.find(m_lastInternalCellId);
2679 return m_cells.end();
2700 return m_cells.find(
id);
2710 return m_cells.cbegin();
2720 return m_cells.cend();
2730 return m_cells.cbegin();
2751 if (m_nInternalCells > 0) {
2752 return ++m_cells.find(m_lastInternalCellId);
2754 return m_cells.cend();
2789 return addCell(std::move(cell),
id);
2810 id = source.
getId();
2817 std::unique_ptr<long[]> dummyConnectStorage = std::unique_ptr<long[]>(
nullptr);
2819 CellIterator iterator = _addInternalCell(ElementType::UNDEFINED, std::move(dummyConnectStorage),
id);
2825 source.setId(iterator->getId());
2827 Cell &cell = (*iterator);
2828 cell = std::move(source);
2850 std::unique_ptr<long[]> connectStorage;
2853 connectStorage = std::unique_ptr<long[]>(
new long[connectSize]);
2855 connectStorage = std::unique_ptr<long[]>(
nullptr);
2858 return addCell(type, std::move(connectStorage),
id);
2880 int connectSize = connectivity.size();
2881 std::unique_ptr<long[]> connectStorage = std::unique_ptr<long[]>(
new long[connectSize]);
2882 std::copy(connectivity.data(), connectivity.data() + connectSize, connectStorage.get());
2884 return addCell(type, std::move(connectStorage),
id);
2915 CellIterator iterator = _addInternalCell(type, std::move(connectStorage),
id);
2936PatchKernel::CellIterator PatchKernel::_addInternalCell(
ElementType type, std::unique_ptr<
long[]> &&connectStorage,
2940 if (m_cellIdGenerator) {
2942 id = m_cellIdGenerator->generate();
2944 m_cellIdGenerator->setAssigned(
id);
2946 }
else if (
id < 0) {
2947 throw std::runtime_error(
"No valid id has been provided for the cell.");
2951#if BITPIT_ENABLE_MPI==1
2957#if BITPIT_ENABLE_MPI==1
2958 referenceId = m_firstGhostCellId;
2960 referenceId = Cell::NULL_ID;
2967 CellIterator iterator;
2968 if (referenceId == Cell::NULL_ID) {
2969 iterator = m_cells.emreclaim(
id,
id, type, std::move(connectStorage),
true, storeInterfaces, storeAdjacencies);
2971 iterator = m_cells.emreclaimBefore(referenceId,
id,
id, type, std::move(connectStorage),
true, storeInterfaces, storeAdjacencies);
2976 if (m_lastInternalCellId < 0) {
2977 m_lastInternalCellId = id;
2978 }
else if (m_cells.rawIndex(m_lastInternalCellId) < m_cells.rawIndex(
id)) {
2979 m_lastInternalCellId = id;
2983 setAddedCellAlterationFlags(
id);
2985#if BITPIT_ENABLE_MPI==1
2987 setPartitioningInfoDirty(
true);
3001void PatchKernel::setAddedCellAlterationFlags(
long id)
3003 AlterationFlags flags = FLAG_NONE;
3005 flags |= FLAG_ADJACENCIES_DIRTY;
3008 flags |= FLAG_INTERFACES_DIRTY;
3014#if BITPIT_ENABLE_MPI==0
3038 CellIterator iterator = m_cells.find(
id);
3039 if (iterator == m_cells.end()) {
3040 throw std::runtime_error(
"Unable to restore the specified cell: the kernel doesn't contain an entry for that cell.");
3043 _restoreInternalCell(iterator, type, std::move(connectStorage));
3057void PatchKernel::_restoreInternalCell(
const CellIterator &iterator,
ElementType type,
3058 std::unique_ptr<
long[]> &&connectStorage)
3067 long cellId = iterator.getId();
3068 Cell &cell = *iterator;
3069 cell.initialize(cellId, type, std::move(connectStorage),
true, storeInterfaces, storeAdjacencies);
3073 setRestoredCellAlterationFlags(cellId);
3081void PatchKernel::setRestoredCellAlterationFlags(
long id)
3083 AlterationFlags flags = FLAG_NONE;
3085 flags |= FLAG_ADJACENCIES_DIRTY;
3088 flags |= FLAG_INTERFACES_DIRTY;
3106#if BITPIT_ENABLE_MPI==1
3107 const Cell &cell = m_cells[id];
3109 if (isInternalCell) {
3110 _deleteInternalCell(
id);
3112 _deleteGhostCell(
id);
3115 _deleteInternalCell(
id);
3126void PatchKernel::_deleteInternalCell(
long id)
3129 setDeletedCellAlterationFlags(
id);
3132 m_cells.erase(
id,
true);
3134 if (
id == m_lastInternalCellId) {
3139 if (m_cellIdGenerator) {
3140 m_cellIdGenerator->trash(
id);
3151void PatchKernel::setDeletedCellAlterationFlags(
long id)
3153 const Cell &cell =
getCell(
id);
3159 const int nCellAdjacencies = cell.getAdjacencyCount();
3160 const long *cellAdjacencies = cell.getAdjacencies();
3161 for (
int k = 0; k < nCellAdjacencies; ++k) {
3162 long adjacencyId = cellAdjacencies[k];
3164 AlterationFlags flags = FLAG_DANGLING;
3166 flags |= FLAG_ADJACENCIES_DIRTY;
3169 flags |= FLAG_INTERFACES_DIRTY;
3177 const int nCellInterfaces = cell.getInterfaceCount();
3178 const long *cellInterfaces = cell.getInterfaces();
3179 for (
int k = 0; k < nCellInterfaces; ++k) {
3180 long interfaceId = cellInterfaces[k];
3208 long nBorderCells = 0;
3209 for (
const Cell &cell : m_cells) {
3210 int nCellFaces = cell.getFaceCount();
3211 for (
int i = 0; i < nCellFaces; ++i) {
3212 if (cell.isFaceBorder(i)) {
3219 return nBorderCells;
3246 std::unordered_map<long, short> vertexValence;
3247 for (
const Cell &cell : m_cells) {
3249 int nCellVertices = cellVertexIds.
size();
3250 for (
int j = 0; j < nCellVertices; j++) {
3251 long vertexId = cellVertexIds[j];
3252 vertexValence[vertexId] += 1;
3257 std::vector<long> orphanCells;
3258 for (
const Cell &cell : m_cells) {
3259 long isIsolated =
true;
3261 int nCellVertices = cellVertexIds.
size();
3262 for (
int j = 0; j < nCellVertices; j++) {
3263 long vertexId = cellVertexIds[j];
3264 if (vertexValence[vertexId] > 1) {
3271 orphanCells.push_back(cell.getId());
3307 std::size_t hash = std::hash<long>{}(0);
3308 for (
long id : ids) {
3309 hash = hash + std::hash<long>{}(id);
3315 std::unordered_map<long, std::size_t > counters;
3319 for (
long id : ids_A) {
3322 for (
long id : ids_B) {
3326 for (
const auto &entry : counters) {
3327 if (entry.second != 0) {
3339 std::vector<long> duplicateCells;
3340 std::unordered_set<ConstProxyVector<long>,
decltype(hasher),
decltype(predicate)> vertexStash(
getCellCount(), hasher, predicate);
3341 for (
const Cell &cell : m_cells) {
3343 auto vertexStashItr = vertexStash.find(cellVertexIds);
3344 if (vertexStashItr == vertexStash.end()) {
3345 vertexStash.insert(std::move(cellVertexIds));
3347 duplicateCells.push_back(cell.getId());
3351 return duplicateCells;
3359 if (m_nInternalCells == 0) {
3360 m_lastInternalCellId = Cell::NULL_ID;
3365#if BITPIT_ENABLE_MPI==1
3366 if (m_nGhostCells == 0) {
3367 lastInternalCellItr = --m_cells.end();
3368 m_lastInternalCellId = lastInternalCellItr->
getId();
3370 m_lastInternalCellId = m_cells.getSizeMarker(m_nInternalCells - 1, Cell::NULL_ID);
3373 lastInternalCellItr = --m_cells.end();
3374 m_lastInternalCellId = lastInternalCellItr->
getId();
3397 std::vector<long> neighs;
3435 std::vector<long> neighs;
3463 assert(codimension >= 1 && codimension <=
getDimension());
3465 if (codimension == 1) {
3469 }
else if (codimension == 2) {
3482 std::vector<long> neighs;
3508 if (m_cells.size() == 0) {
3511 nCellVertices = cellTypeInfo.nVertices;
3517 for (
int i = 0; i < nCellVertices; ++i) {
3537 if (m_cells.size() == 0) {
3540 nCellFaces = cellTypeInfo.nFaces;
3547 for (
int i = 0; i < nCellFaces; ++i) {
3561 std::vector<long> neighs;
3601 for (
int k = 0; k < nFaceAdjacencies; ++k) {
3602 long neighId = faceAdjacencies[k];
3603 if (!blackList || utils::findInOrderedVector<long>(neighId, *blackList) == blackList->end()) {
3604 utils::addToOrderedVector<long>(neighId, *neighs);
3622 std::vector<long> neighs;
3653 if (m_cells.size() == 0) {
3656 nCellEdges = cellTypeInfo.nEdges;
3663 std::unique_ptr<std::vector<long>> blackList;
3665 blackList = std::unique_ptr<std::vector<long>>(
new std::vector<long>());
3669 for (
int i = 0; i < nCellEdges; ++i) {
3685 std::vector<long> neighs;
3732 std::size_t nEdgeVertices = edgeVertices.
size();
3733 if (nEdgeVertices < 2) {
3740 const int GUESS_NEIGHS_COUNT = 3;
3742 std::vector<long> candidateIds;
3743 candidateIds.reserve(GUESS_NEIGHS_COUNT);
3747 long lastEdgeVertexId = cell.
getEdgeVertexId(edge, nEdgeVertices - 1);
3750 for (
long candidateId : candidateIds) {
3751 const Cell &candidateNeigh = m_cells.at(candidateId);
3753 std::size_t nCandidateVertices = candidateVertexIds.
size();
3755 bool isEdgeNeighbour =
false;
3756 for (std::size_t k = 0; k < nCandidateVertices; ++k) {
3757 if (candidateVertexIds[k] == lastEdgeVertexId) {
3758 isEdgeNeighbour =
true;
3763 if (isEdgeNeighbour) {
3764 utils::addToOrderedVector<long>(candidateId, *neighs);
3780 std::vector<long> neighs;
3804 if (m_cells.size() == 0) {
3807 nCellVertices = cellTypeInfo.nVertices;
3814 std::unique_ptr<std::vector<long>> blackList;
3816 blackList = std::unique_ptr<std::vector<long>>(
new std::vector<long>());
3824 for (
int i = 0; i < nCellVertices; ++i) {
3838 std::vector<long> neighs;
3897 const int GUESS_NEIGHS_COUNT = 8;
3899 std::vector<long> alreadyProcessed;
3900 alreadyProcessed.reserve(GUESS_NEIGHS_COUNT);
3902 std::vector<long> scanQueue;
3903 scanQueue.reserve(GUESS_NEIGHS_COUNT);
3904 scanQueue.push_back(
id);
3906 while (!scanQueue.empty()) {
3908 long scanCellId = scanQueue.back();
3910 scanQueue.pop_back();
3911 utils::addToOrderedVector<long>(scanCell.
getId(), alreadyProcessed);
3915 const long *scanCellConnectivity =
nullptr;
3917 scanCellInfo = &(scanCell.
getInfo());
3918 scanCellConnectivity = scanCell.
getConnect();
3924 nFaces = scanCellInfo->nFaces;
3929 for (
int i = 0; i < nFaces; ++i) {
3947 bool faceOwnsVertex =
false;
3950 const int *faceLocalConnectivity = scanCellInfo->faceConnectStorage[i].data();
3951 const int nFaceVertices = faceInfo.nVertices;
3952 for (
int k = 0; k < nFaceVertices; ++k) {
3953 long faceVertexId = scanCellConnectivity[faceLocalConnectivity[k]];
3954 if (faceVertexId == vertexId) {
3955 faceOwnsVertex =
true;
3961 int nFaceVertices = faceVertexIds.
size();
3962 for (
int k = 0; k < nFaceVertices; ++k) {
3963 long faceVertexId = faceVertexIds[k];
3964 if (faceVertexId == vertexId) {
3965 faceOwnsVertex =
true;
3971 if (!faceOwnsVertex) {
3980 for (
int k = 0; k < nFaceAdjacencies; ++k) {
3981 long faceNeighId = faceAdjacencies[k];
3984 if (utils::findInOrderedVector<long>(faceNeighId, alreadyProcessed) != alreadyProcessed.end()) {
3989 if (!blackList || utils::findInOrderedVector<long>(faceNeighId, *blackList) == blackList->end()) {
3990 utils::addToOrderedVector<long>(faceNeighId, *neighs);
3994 scanQueue.push_back(faceNeighId);
4009 std::vector<long> ring;
4028 utils::addToOrderedVector<long>(
id, *ring);
4052 for (
int i = 0; i < nFaces; ++i) {
4055 for (
int k = 0; k < nFaceAdjacencies; ++k) {
4056 long faceNeighId = faceAdjacencies[k];
4057 if (faceNeighId < 0) {
4059 }
else if (faceNeighId == neighId) {
4061 *cellAdjacencyId = k;
4068 *cellAdjacencyId = -1;
4083 list.insert(itr->getPID());
4097 std::vector<long> cells;
4100 if (itr->getPID() == pid){
4101 cells.push_back(itr.getId());
4118 std::vector<long> ring;
4144 if (cellId == bitpit::Element::NULL_ID) {
4149 assert(vertexLocalId >= 0);
4165 return static_cast<bool>(m_interfaceIdGenerator);
4186 createInterfaceIndexGenerator(
true);
4189 throw std::runtime_error(
"Auto-indexing cannot be disabled if interfaces build strategy is set to automatic.");
4192 m_interfaceIdGenerator.reset();
4201void PatchKernel::dumpInterfaceAutoIndexing(std::ostream &stream)
const
4203 m_interfaceIdGenerator->dump(stream);
4211void PatchKernel::restoreInterfaceAutoIndexing(std::istream &stream)
4213 createInterfaceIndexGenerator(
false);
4214 m_interfaceIdGenerator->restore(stream);
4225void PatchKernel::createInterfaceIndexGenerator(
bool populate)
4228 if (!m_interfaceIdGenerator) {
4229 m_interfaceIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>());
4231 m_interfaceIdGenerator->reset();
4236 InterfaceConstIterator beginItr = m_interfaces.cbegin();
4237 InterfaceConstIterator endItr = m_interfaces.cend();
4238 for (InterfaceConstIterator itr = beginItr; itr != endItr; ++itr) {
4239 m_interfaceIdGenerator->setAssigned(itr.getId());
4252void PatchKernel::importInterfaceIndexGenerator(
const PatchKernel &source)
4254 if (source.m_interfaceIdGenerator) {
4255 m_interfaceIdGenerator = std::unique_ptr<IndexGenerator<long>>(
new IndexGenerator<long>(*(source.m_interfaceIdGenerator)));
4257 m_interfaceIdGenerator.reset();
4268 return m_interfaces.size();
4278 return m_interfaces;
4288 return m_interfaces;
4299 return m_interfaces[id];
4310 return m_interfaces[id];
4321 return m_interfaces[id].getType();
4331 return m_interfaces.find(
id);
4341 return m_interfaces.begin();
4351 return m_interfaces.end();
4361 return m_interfaces.find(
id);
4371 return m_interfaces.cbegin();
4381 return m_interfaces.cend();
4402 interface.
setId(
id);
4426 id = source.
getId();
4434 std::unique_ptr<long[]> dummyConnectStorage = std::unique_ptr<long[]>(
nullptr);
4436 InterfaceIterator iterator = _addInterface(ElementType::UNDEFINED, std::move(dummyConnectStorage),
id);
4443 source.setId(iterator->getId());
4446 interface = std::move(source);
4469 std::unique_ptr<long[]> connectStorage = std::unique_ptr<long[]>(
new long[connectSize]);
4471 return addInterface(type, std::move(connectStorage),
id);
4490 const std::vector<long> &connectivity,
4493 int connectSize = connectivity.size();
4494 std::unique_ptr<long[]> connectStorage = std::unique_ptr<long[]>(
new long[connectSize]);
4495 std::copy(connectivity.data(), connectivity.data() + connectSize, connectStorage.get());
4497 return addInterface(type, std::move(connectStorage),
id);
4517 std::unique_ptr<
long[]> &&connectStorage,
4528 InterfaceIterator iterator = _addInterface(type, std::move(connectStorage),
id);
4549PatchKernel::InterfaceIterator PatchKernel::_addInterface(
ElementType type,
4550 std::unique_ptr<
long[]> &&connectStorage,
4554 if (m_interfaceIdGenerator) {
4556 id = m_interfaceIdGenerator->generate();
4558 m_interfaceIdGenerator->setAssigned(
id);
4560 }
else if (
id < 0) {
4561 throw std::runtime_error(
"No valid id has been provided for the interface.");
4568 setAddedInterfaceAlterationFlags(
id);
4581void PatchKernel::setAddedInterfaceAlterationFlags(
long id)
4599 std::unique_ptr<
long[]> &&connectStorage,
4611 if (iterator == m_interfaces.end()) {
4612 throw std::runtime_error(
"Unable to restore the specified interface: the kernel doesn't contain an entry for that interface.");
4615 _restoreInterface(iterator, type, std::move(connectStorage));
4631void PatchKernel::_restoreInterface(
const InterfaceIterator &iterator,
ElementType type,
4632 std::unique_ptr<
long[]> &&connectStorage)
4638 long interfaceId = iterator.getId();
4640 interface.
initialize(interfaceId, type, std::move(connectStorage));
4643 setRestoredInterfaceAlterationFlags(interfaceId);
4651void PatchKernel::setRestoredInterfaceAlterationFlags(
long id)
4667 _deleteInterface(
id);
4677void PatchKernel::_deleteInterface(
long id)
4680 setDeletedInterfaceAlterationFlags(
id);
4683 m_interfaces.erase(
id,
true);
4686 if (m_interfaceIdGenerator) {
4687 m_interfaceIdGenerator->trash(
id);
4698void PatchKernel::setDeletedInterfaceAlterationFlags(
long id)
4724 long nBorderInterfaces = 0;
4725 for (
const Interface &interface : m_interfaces) {
4726 if (interface.getNeigh() < 0) {
4727 ++nBorderInterfaces;
4731 return nBorderInterfaces;
4744 long nOrphanInterfaces = 0;
4747 const long interfaceId = itr.getId();
4749 ++nOrphanInterfaces;
4753 return nOrphanInterfaces;
4766 std::vector<long> orphanInterfaces;
4769 const long interfaceId = itr.getId();
4771 orphanInterfaces.push_back(interfaceId);
4775 return orphanInterfaces;
4803 const Interface &
interface = getInterface(id);
4806 long ownerId = interface.
getOwner();
4807 long neighId = interface.getNeigh();
4808 if (ownerId >= 0 && neighId >= 0) {
4813 if (ownerId >= 0 && neighId < 0) {
4814 const Cell &owner = getCell(ownerId);
4831 for (
const Cell &cell : m_cells) {
4832 int nCellFaces = cell.getFaceCount();
4833 for (
int i = 0; i < nCellFaces; ++i) {
4834 if (!cell.isFaceBorder(i)) {
4835 nFaces += 1. / (cell.getAdjacencyCount(i) + 1);
4842 return ((
long) round(nFaces));
4866 long nBorderFaces = 0;
4867 for (
const Cell &cell : m_cells) {
4868 int nCellFaces = cell.getFaceCount();
4869 for (
int i = 0; i < nCellFaces; ++i) {
4870 if (cell.isFaceBorder(i)) {
4876 return nBorderFaces;
4887 m_vertices.dumpKernel(stream);
4890 for (
const Vertex &vertex : m_vertices) {
4892#if BITPIT_ENABLE_MPI==1
4899 const std::array<double, 3> &coords = vertex.
getCoords();
4906#if BITPIT_ENABLE_MPI==1
4923 m_vertices.restoreKernel(stream);
4930 long nVertices = m_vertices.size();
4931 for (
long i = 0; i < nVertices; ++i) {
4935#if BITPIT_ENABLE_MPI==1
4943 std::array<double, 3> coords;
4948#if BITPIT_ENABLE_MPI==1
4956#if BITPIT_ENABLE_MPI==1
4960 long dummyFirstGhostVertexId;
4961 long dummyLastInternalVertexId;
4978 m_cells.dumpKernel(stream);
4981 for (
const Cell &cell: m_cells) {
4986#if BITPIT_ENABLE_MPI==1
4993 int dummyHaloLayer = 0;
4997 int cellConnectSize = cell.getConnectSize();
5000 const long *cellConnect = cell.getConnect();
5001 for (
int i = 0; i < cellConnectSize; ++i) {
5007#if BITPIT_ENABLE_MPI==1
5024 m_cells.restoreKernel(stream);
5031 long nCells = m_cells.size();
5032 for (
long i = 0; i < nCells; ++i) {
5042#if BITPIT_ENABLE_MPI==1
5056 int cellConnectSize;
5059 std::unique_ptr<long[]> cellConnect = std::unique_ptr<long[]>(
new long[cellConnectSize]);
5060 for (
int k = 0; k < cellConnectSize; ++k) {
5065#if BITPIT_ENABLE_MPI==1
5066 iterator =
restoreCell(type, std::move(cellConnect), owner, haloLayer,
id);
5068 iterator =
restoreCell(type, std::move(cellConnect),
id);
5070 iterator->setPID(PID);
5074#if BITPIT_ENABLE_MPI==1
5078 long dummyFirstGhostCellId;
5079 long dummyLastInternalCellId;
5104 m_interfaces.dumpKernel(stream);
5113 long neighId = interface.getNeigh();
5139 m_interfaces.restoreKernel(stream);
5146 long nInterfaces = m_interfaces.size();
5147 for (
long n = 0; n < nInterfaces; ++n) {
5155 Cell *owner = &(m_cells.at(ownerId));
5163 neigh = &(m_cells.at(neighId));
5172 InterfaceIterator interfaceIterator = buildCellInterface(owner, ownerFace, neigh, neighFace, interfaceId);
5173 interfaceIterator->setPID(pid);
5178 m_alteredInterfaces.clear();
5199 return std::vector<adaption::Info>();
5217 assert(
false &&
"The patch needs to implement _adaptionAlter");
5219 return std::vector<adaption::Info>();
5288 return adaption::MARKER_UNDEFINED;
5318 if (m_nInternalVertices > 0) {
5319 m_vertices.sortBefore(m_lastInternalVertexId,
true);
5323#if BITPIT_ENABLE_MPI==1
5325 if (m_nGhostVertices > 0) {
5326 m_vertices.sortAfter(m_firstGhostVertexId,
true);
5349 if (m_nInternalCells > 0) {
5350 m_cells.sortBefore(m_lastInternalCellId,
true);
5354#if BITPIT_ENABLE_MPI==1
5356 if (m_nGhostCells > 0) {
5357 m_cells.sortAfter(m_firstGhostCellId,
true);
5377 m_interfaces.sort();
5379 m_interfaces.sync();
5410 m_vertices.squeeze();
5450 m_interfaces.squeeze();
5452 m_interfaces.sync();
5469 if (m_alteredCells.empty()) {
5470 AlterationFlagsStorage().swap(m_alteredCells);
5473 if (m_alteredInterfaces.empty()) {
5474 AlterationFlagsStorage().swap(m_alteredInterfaces);
5527 const int nCellVertices = cellVertexIds.
size();
5534 return vertexCoordinates;
5573 const Interface &
interface = getInterface(id);
5575 return evalElementCentroid(interface);
5587 const Interface &
interface = getInterface(id);
5589 evalElementBoundingBox(interface, minPoint, maxPoint);
5601 const Interface &
interface = getInterface(id);
5603 const int nInterfaceVertices = interfaceVertexIds.
size();
5608 getVertexCoords(interfaceVertexIds.size(), interfaceVertexIds.data(), storage);
5610 return vertexCoordinates;
5621 const Interface &
interface = getInterface(id);
5623 getElementVertexCoordinates(interface, coordinates);
5636 const Interface &
interface = getInterface(id);
5638 getElementVertexCoordinates(interface, coordinates);
5653 std::size_t nCellVertices = elementVertexIds.
size();
5654 BITPIT_CREATE_WORKSPACE(vertexCoordinates, std::array<double BITPIT_COMMA 3>, nCellVertices, ReferenceElementInfo::MAX_ELEM_VERTICES);
5670 switch (elementType)
5673 case ElementType::VERTEX:
5675 const long *elementConnect = element.
getConnect();
5677 *maxPoint = *minPoint;
5681 case ElementType::PIXEL:
5683 const long *elementConnect = element.
getConnect();
5685 const std::array<double, 3> &vertexCoord_0 =
getVertexCoords(elementConnect[0]);
5686 const std::array<double, 3> &vertexCoord_3 =
getVertexCoords(elementConnect[3]);
5688 for (
int d = 0; d < 3; ++d) {
5689 (*minPoint)[d] = std::min(vertexCoord_0[d], vertexCoord_3[d]);
5690 (*maxPoint)[d] = std::max(vertexCoord_0[d], vertexCoord_3[d]);
5696 case ElementType::VOXEL:
5698 const long *elementConnect = element.
getConnect();
5700 const std::array<double, 3> &vertexCoord_0 =
getVertexCoords(elementConnect[0]);
5701 const std::array<double, 3> &vertexCoord_7 =
getVertexCoords(elementConnect[7]);
5703 for (
int d = 0; d < 3; ++d) {
5704 (*minPoint)[d] = std::min(vertexCoord_0[d], vertexCoord_7[d]);
5705 (*maxPoint)[d] = std::max(vertexCoord_0[d], vertexCoord_7[d]);
5714 const int nElementVertices = elementVertexIds.
size();
5717 *maxPoint = *minPoint;
5718 for (
int i = 1; i < nElementVertices; ++i) {
5719 const std::array<double, 3> &vertexCoord =
getVertexCoords(elementVertexIds[i]);
5720 for (
int d = 0; d < 3; ++d) {
5721 (*minPoint)[d] = std::min(vertexCoord[d], (*minPoint)[d]);
5722 (*maxPoint)[d] = std::max(vertexCoord[d], (*maxPoint)[d]);
5767 std::vector<long> faceVertexIds_A(nFaceVertices);
5768 std::vector<long> faceVertexIds_B(nFaceVertices);
5769 for (
int k = 0; k < nFaceVertices; ++k) {
5774 std::sort(faceVertexIds_A.begin(), faceVertexIds_A.end());
5775 std::sort(faceVertexIds_B.begin(), faceVertexIds_B.end());
5777 return (faceVertexIds_A == faceVertexIds_B);
5787 return m_adjacenciesBuildStrategy;
5797 m_adjacenciesBuildStrategy = status;
5813 bool areDirty =
false;
5814 for (
const auto &entry : m_alteredCells) {
5815 AlterationFlags cellAlterationFlags = entry.second;
5822#if BITPIT_ENABLE_MPI==1
5825 MPI_Allreduce(MPI_IN_PLACE, &areDirty, 1, MPI_C_BOOL, MPI_LOR, communicator);
5859 if (strategy == ADJACENCIES_NONE) {
5860 if (currentStrategy != ADJACENCIES_NONE) {
5868 if (currentStrategy != strategy) {
5889 if (currentStrategy == ADJACENCIES_NONE) {
5895 if (!adjacenciesDirty && !forcedUpdated) {
5900 if (adjacenciesDirty) {
5968 for (
Cell &cell : m_cells) {
5969 cell.resetAdjacencies(!release);
5983 if (currentStrategy == ADJACENCIES_NONE) {
5988 for (
const auto &entry : m_alteredCells) {
5989 AlterationFlags cellAlterationFlags = entry.second;
5994 long cellId = entry.first;
5995 Cell &cell = m_cells.at(cellId);
6001 for (
int face = nCellFaces - 1; face >= 0; --face) {
6004 for (
int i = nFaceAdjacencies - 1; i >= 0; --i) {
6005 long adjacency = faceAdjacencies[i];
6034 bool multipleMatchesAllowed = (dimension < 3);
6049 std::vector<CellHalfFace::Winding> matchingWindings;
6050 matchingWindings.push_back(CellHalfFace::WINDING_REVERSE);
6051 if (multipleMatchesAllowed) {
6052 matchingWindings.push_back(CellHalfFace::WINDING_NATURAL);
6056 long nDirtyAdjacenciesCells = 0;
6057 for (
const auto &entry : m_alteredCells) {
6058 AlterationFlags cellAlterationFlags = entry.second;
6063 ++nDirtyAdjacenciesCells;
6070 std::unique_ptr<PiercedStorage<bool, long>> dirtyAdjacenciesVertices;
6071 if (multipleMatchesAllowed && (nDirtyAdjacenciesCells !=
getCellCount())) {
6073 dirtyAdjacenciesVertices->fill(
false);
6074 for (
const auto &entry : m_alteredCells) {
6075 AlterationFlags cellAlterationFlags = entry.second;
6080 long cellId = entry.first;
6081 const Cell &cell = m_cells.at(cellId);
6083 for (
long vertexId : cellVertexIds) {
6084 dirtyAdjacenciesVertices->at(vertexId) =
true;
6099 std::vector<Cell *> processList;
6100 processList.reserve(nDirtyAdjacenciesCells);
6102 std::size_t nMaxHalfFaces = 0;
6103 for (
Cell &cell : m_cells) {
6105 long cellId = cell.getId();
6106 int nCellFaces = cell.getFaceCount();
6110 nMaxHalfFaces += nCellFaces;
6111 processList.push_back(&cell);
6116 bool isBorderCell =
false;
6117 for (
int face = 0; face < nCellFaces; face++) {
6118 if (cell.isFaceBorder(face)) {
6119 isBorderCell =
true;
6125 nMaxHalfFaces += nCellFaces;
6126 processList.push_back(&cell);
6137 if (multipleMatchesAllowed) {
6140 int nCelldirtyAdjacenciesVertices = 0;
6141 bool futureNeighbourCandidate =
false;
6142 for (
long vertexId : cellVertexIds) {
6143 if (dirtyAdjacenciesVertices->at(vertexId)) {
6144 ++nCelldirtyAdjacenciesVertices;
6145 if (nCelldirtyAdjacenciesVertices >= dimension) {
6146 futureNeighbourCandidate =
true;
6152 if (futureNeighbourCandidate) {
6153 nMaxHalfFaces += nCellFaces;
6154 processList.push_back(&cell);
6160 std::unordered_set<CellHalfFace, CellHalfFace::Hasher> halfFaces;
6161 halfFaces.reserve(
static_cast<std::size_t
>(0.5 * nMaxHalfFaces));
6163 std::vector<std::pair<Cell *, int>> matchingAdjacencies;
6164 for (
Cell *cell : processList) {
6165 long cellId = cell->getId();
6166 const int nCellFaces = cell->getFaceCount();
6168 for (
int face = 0; face < nCellFaces; face++) {
6173 auto matchingHalfFaceItr = halfFaces.end();
6174 for (CellHalfFace::Winding winding : matchingWindings) {
6179 matchingHalfFaceItr = halfFaces.find(halfFace);
6180 if (matchingHalfFaceItr != halfFaces.end()) {
6190 if (matchingHalfFaceItr == halfFaces.end()) {
6191 halfFace.
setWinding(CellHalfFace::WINDING_NATURAL);
6192 halfFaces.insert(std::move(halfFace));
6197 const CellHalfFace &matchingHalfFace = *matchingHalfFaceItr;
6199 long matchingCellId = matchingCell.
getId();
6200 long matchingFace = matchingHalfFace.
getFace();
6209 if (!areCellAdjacenciesDirty && !areMatchingCellAdjacenciesDirty) {
6219 matchingAdjacencies.clear();
6220 matchingAdjacencies.emplace_back(std::make_pair<Cell *, int>(&matchingCell, matchingFace));
6221 if (multipleMatchesAllowed) {
6223 const long *machingFaceNeighs = matchingCell.
getAdjacencies(matchingFace);
6224 for (
int k = 0; k < nMachingFaceNeighs; ++k) {
6225 long neighId = machingFaceNeighs[k];
6226 if (neighId == cellId) {
6230 Cell &neigh = m_cells.at(neighId);
6232 matchingAdjacencies.emplace_back(std::make_pair<Cell *, int>(&neigh, std::move(neighFace)));
6244 for (
const std::pair<Cell *, int> &matchingAdjacency : matchingAdjacencies) {
6245 Cell *adjacentCell = matchingAdjacency.first;
6246 long adjacentCellId = adjacentCell->
getId();
6247 int adjacentFace = matchingAdjacency.second;
6249 cell->pushAdjacency(face, adjacentCellId);
6258 if (!multipleMatchesAllowed) {
6259 halfFaces.erase(matchingHalfFaceItr);
6272 return m_interfacesBuildStrategy;
6282 if (status == INTERFACES_AUTOMATIC) {
6284 throw std::runtime_error(
"Automatic build strategy requires auto-indexing.");
6288 m_interfacesBuildStrategy = status;
6304 bool areDirty = !m_alteredInterfaces.empty();
6306 for (
const auto &entry : m_alteredCells) {
6307 AlterationFlags cellAlterationFlags = entry.second;
6315#if BITPIT_ENABLE_MPI==1
6318 MPI_Allreduce(MPI_IN_PLACE, &areDirty, 1, MPI_C_BOOL, MPI_LOR, communicator);
6353 throw std::runtime_error (
"Adjacencies are mandatory for building the interfaces.");
6360 if (strategy == INTERFACES_NONE) {
6361 if (currentStrategy != INTERFACES_NONE) {
6369 if (currentStrategy != strategy) {
6390 if (currentStrategy == INTERFACES_NONE) {
6396 if (!interfacesDirty && !forcedUpdated) {
6405 if (interfacesDirty) {
6418 m_alteredInterfaces.clear();
6447 m_alteredInterfaces.clear();
6467 for (
const auto &entry : m_alteredCells) {
6468 AlterationFlags cellAlterationFlags = entry.second;
6473 long cellId = entry.first;
6474 Cell &cell = m_cells.at(cellId);
6480 for (
int face = nCellFaces - 1; face >= 0; --face) {
6483 for (
int i = nFaceInterfaces - 1; i >= 0; --i) {
6484 long interfaceId = faceInterfaces[i];
6496 std::vector<long> danglingInterfaces;
6497 danglingInterfaces.reserve(m_alteredInterfaces.size());
6498 for (
const auto &entry : m_alteredInterfaces) {
6499 AlterationFlags interfaceAlterationFlags = entry.second;
6504 long interfaceId = entry.first;
6505 danglingInterfaces.push_back(interfaceId);
6530 for (
const auto &entry : m_alteredCells) {
6531 AlterationFlags cellAlterationFlags = entry.second;
6536 long cellId = entry.first;
6537 Cell &cell = m_cells.at(cellId);
6539 for (
int face = 0; face < nCellFaces; face++) {
6543 if (!isFaceBorder) {
6546 int updateBegin = nFaceInterfaces;
6547 if (updateBegin == updateEnd) {
6553 for (
int k = updateBegin; k < updateEnd; ++k) {
6554 long neighId = faceAdjacencies[k];
6555 Cell *neigh = &m_cells[neighId];
6559 buildCellInterface(&cell, face, neigh, neighFace);
6561 }
else if (nFaceInterfaces == 0) {
6563 buildCellInterface(&cell, face,
nullptr, -1);
6583PatchKernel::InterfaceIterator PatchKernel::buildCellInterface(
Cell *cell_1,
int face_1,
Cell *cell_2,
int face_2,
long interfaceId)
6587 assert(face_1 >= 0);
6590 assert(face_2 >= 0);
6596 long id_1 = cell_1->
getId();
6599 long id_2 = Cell::NULL_ID;
6601 id_2 = cell_2->
getId();
6613 bool cellOwnsInterface =
true;
6616 cellOwnsInterface =
false;
6619 cellOwnsInterface = CellFuzzyPositionLess(*
this)(id_1, id_2);
6629 if (cellOwnsInterface) {
6632 intrOwnerFace = face_1;
6637 intrNeighFace = face_2;
6639 intrNeighId = Cell::NULL_ID;
6640 intrNeigh =
nullptr;
6646 intrOwnerFace = face_2;
6650 intrNeighFace = face_1;
6654 ConstProxyVector<long> faceConnect = intrOwner->
getFaceConnect(intrOwnerFace);
6656 int nInterfaceVertices = faceConnect.size();
6657 std::unique_ptr<long[]> interfaceConnect = std::unique_ptr<long[]>(
new long[nInterfaceVertices]);
6658 for (
int k = 0; k < nInterfaceVertices; ++k) {
6659 interfaceConnect[k] = faceConnect[k];
6663 Interface *interface;
6664 InterfaceIterator interfaceIterator;
6666 ElementType interfaceType = intrOwner->getFaceType(intrOwnerFace);
6667 if (interfaceId < 0) {
6668 interfaceIterator =
addInterface(interfaceType, std::move(interfaceConnect), interfaceId);
6669 interface = &(*interfaceIterator);
6670 interfaceId = interface->getId();
6672 interfaceIterator =
restoreInterface(interfaceType, std::move(interfaceConnect), interfaceId);
6673 interface = &(*interfaceIterator);
6677 interface->setOwner(intrOwnerId, intrOwnerFace);
6678 if (intrNeighId >= 0) {
6679 interface->setNeigh(intrNeighId, intrNeighFace);
6697 intrOwner->pushInterface(intrOwnerFace, interfaceId);
6699 intrNeigh->pushInterface(intrNeighFace, interfaceId);
6702 int ownerInterfaceIndex = intrOwner->getInterfaceCount(intrOwnerFace) - 1;
6703 long ownerPairedAdjacency = intrOwner->getAdjacency(intrOwnerFace, ownerInterfaceIndex);
6704 if (ownerPairedAdjacency != intrNeighId) {
6705 int ownerPairedAdjacencyIndex = intrOwner->findAdjacency(intrOwnerFace, intrNeighId);
6706 assert(ownerPairedAdjacencyIndex >= 0);
6707 intrOwner->setAdjacency(intrOwnerFace, ownerInterfaceIndex, intrNeighId);
6708 intrOwner->setAdjacency(intrOwnerFace, ownerPairedAdjacencyIndex, ownerPairedAdjacency);
6712 int neighInterfaceIndex = intrNeigh->getInterfaceCount(intrNeighFace) - 1;
6713 long neighPairedAdjacency = intrNeigh->getAdjacency(intrNeighFace, neighInterfaceIndex);
6714 if (neighPairedAdjacency != intrOwnerId) {
6715 int neighPairedAdjacencyIndex = intrNeigh->findAdjacency(intrNeighFace, intrOwnerId);
6716 assert(neighPairedAdjacencyIndex >= 0);
6717 intrNeigh->setAdjacency(intrNeighFace, neighInterfaceIndex, intrOwnerId);
6718 intrNeigh->setAdjacency(intrNeighFace, neighPairedAdjacencyIndex, neighPairedAdjacency);
6722 return interfaceIterator;
6744 long cellId = cell.
getId();
6747 int nCandidates = 0;
6748 BITPIT_CREATE_WORKSPACE(candidates, std::array<int BITPIT_COMMA 3>, nNeighFaces, ReferenceElementInfo::MAX_ELEM_FACES);
6749 for (
int neighFace = 0; neighFace < nNeighFaces; neighFace++) {
6752 for (
int k = 0; k < nFaceAdjacencies; ++k) {
6753 long geussId = faceAdjacencies[k];
6754 if (geussId == cellId) {
6755 (*candidates)[nCandidates] = neighFace;
6763 if (nCandidates == 1) {
6764 return (*candidates)[0];
6766 for (
int i = 0; i < nCandidates; ++i) {
6767 int candidateFace = (*candidates)[i];
6768 if (
isSameFace(cell, cellFace, neigh, candidateFace)) {
6769 return candidateFace;
6786 return testElementAlterationFlags(
id, flags, m_alteredCells);
6797 return getElementAlterationFlags(
id, m_alteredCells);
6808 resetElementAlterationFlags(
id, flags, &m_alteredCells);
6832 setElementAlterationFlags(
id, flags, &m_alteredCells);
6842 unsetElementAlterationFlags(flags, &m_alteredCells);
6853 unsetElementAlterationFlags(
id, flags, &m_alteredCells);
6865 return testElementAlterationFlags(
id, flags, m_alteredInterfaces);
6876 return getElementAlterationFlags(
id, m_alteredInterfaces);
6887 resetElementAlterationFlags(
id, flags, &m_alteredInterfaces);
6911 setElementAlterationFlags(
id, flags, &m_alteredInterfaces);
6921 unsetElementAlterationFlags(flags, &m_alteredInterfaces);
6932 unsetElementAlterationFlags(
id, flags, &m_alteredInterfaces);
6943bool PatchKernel::testElementAlterationFlags(
long id, AlterationFlags flags,
const AlterationFlagsStorage &flagsStorage)
const
6945 auto storedFlagsItr = flagsStorage.find(
id);
6946 if (storedFlagsItr != flagsStorage.end()) {
6962 return ((availableFlags & requestedFlags) == requestedFlags);
6972PatchKernel::AlterationFlags PatchKernel::getElementAlterationFlags(
long id,
const AlterationFlagsStorage &flagsStorage)
const
6974 auto storedFlagsItr = flagsStorage.find(
id);
6975 if (storedFlagsItr != flagsStorage.end()) {
6976 return storedFlagsItr->second;
6989void PatchKernel::resetElementAlterationFlags(
long id, AlterationFlags flags, AlterationFlagsStorage *flagsStorage)
const
6991 if (flags == FLAG_NONE) {
6992 flagsStorage->erase(
id);
6994 (*flagsStorage)[id] = flags;
7005void PatchKernel::setElementAlterationFlags(
long id, AlterationFlags flags, AlterationFlagsStorage *flagsStorage)
const
7007 if (flags == FLAG_NONE) {
7011 auto storedFlagsItr = flagsStorage->find(
id);
7012 if (storedFlagsItr != flagsStorage->end()) {
7013 storedFlagsItr->second |= flags;
7015 flagsStorage->insert({id, flags});
7025void PatchKernel::unsetElementAlterationFlags(AlterationFlags flags, AlterationFlagsStorage *flagsStorage)
const
7027 if (flags == FLAG_NONE) {
7031 for (
auto storedFlagsItr = flagsStorage->begin(); storedFlagsItr != flagsStorage->end();) {
7032 storedFlagsItr->second &= ~flags;
7033 if (storedFlagsItr->second == FLAG_NONE) {
7034 storedFlagsItr = flagsStorage->erase(storedFlagsItr);
7048void PatchKernel::unsetElementAlterationFlags(
long id, AlterationFlags flags, AlterationFlagsStorage *flagsStorage)
const
7050 if (flags == FLAG_NONE) {
7054 auto storedFlagsItr = flagsStorage->find(
id);
7055 if (storedFlagsItr == flagsStorage->end()) {
7059 storedFlagsItr->second &= ~flags;
7060 if (storedFlagsItr->second == FLAG_NONE) {
7061 flagsStorage->erase(storedFlagsItr);
7072 for (
int k = 0; k < 3; ++k) {
7073 m_boxMinPoint[k] = std::numeric_limits<double>::max();
7074 m_boxMinCounter[k] = 0;
7076 m_boxMaxPoint[k] = - std::numeric_limits<double>::max();
7077 m_boxMaxCounter[k] = 0;
7093 m_boxMinPoint = minPoint;
7094 m_boxMaxPoint = maxPoint;
7120 minPoint = m_boxMinPoint;
7121 maxPoint = m_boxMaxPoint;
7123#if BITPIT_ENABLE_MPI==1
7126 MPI_Allreduce(MPI_IN_PLACE, minPoint.data(), 3, MPI_DOUBLE, MPI_MIN, communicator);
7127 MPI_Allreduce(MPI_IN_PLACE, maxPoint.data(), 3, MPI_DOUBLE, MPI_MAX, communicator);
7156 m_boxFrozen = frozen;
7169#if BITPIT_ENABLE_MPI==1
7172 MPI_Allreduce(
const_cast<bool *
>(&m_boxDirty), &
isDirty, 1, MPI_C_BOOL, MPI_LOR, communicator);
7215 for (
const auto &vertex : m_vertices) {
7234 for (
size_t k = 0; k < point.size(); ++k) {
7235 double value = point[k];
7239 ++m_boxMaxCounter[k];
7240 }
else if (value > m_boxMaxPoint[k]) {
7241 m_boxMaxPoint[k] = value;
7242 m_boxMaxCounter[k] = 1;
7247 ++m_boxMinCounter[k];
7248 }
else if (value < m_boxMinPoint[k]) {
7249 m_boxMinPoint[k] = value;
7250 m_boxMinCounter[k] = 1;
7269 double tolerance =
getTol();
7270 for (
size_t k = 0; k < point.size(); ++k) {
7271 double value = point[k];
7275 --m_boxMaxCounter[k];
7276 if (m_boxMaxCounter[k] == 0) {
7280 }
else if (value > m_boxMaxPoint[k]) {
7281 assert(
false &&
"Bounding box is in inconsistent state.");
7288 --m_boxMinCounter[k];
7289 if (m_boxMinCounter[k] == 0) {
7293 }
else if (value < m_boxMinPoint[k]) {
7294 assert(
false &&
"Bounding box is in inconsistent state.");
7311 const int nElementVertices = elementVertexIds.
size();
7318 return vertexCoordinates;
7371 double dx = std::max(1.0e-12, m_boxMaxPoint[0] - m_boxMinPoint[0]) / ((double) nBins);
7372 double dy = std::max(1.0e-12, m_boxMaxPoint[1] - m_boxMinPoint[1]) / ((double) nBins);
7373 double dz = std::max(1.0e-12, m_boxMaxPoint[2] - m_boxMinPoint[2]) / ((double) nBins);
7376 std::unordered_map<long, std::vector<long>> bins;
7377 for (
const Vertex &vertex : vertices) {
7378 const std::array<double, 3> &coordinates = vertex.
getCoords();
7380 int i = std::min(nBins - 1L, (
long) ((coordinates[0] - m_boxMinPoint[0]) / dx));
7381 int j = std::min(nBins - 1L, (
long) ((coordinates[1] - m_boxMinPoint[1]) / dy));
7382 int k = std::min(nBins - 1L, (
long) ((coordinates[2] - m_boxMinPoint[2]) / dz));
7384 long binId = nBins * nBins * k + nBins * j + i;
7385 bins[binId].emplace_back(vertex.
getId());
7399 for (
auto &vertex : m_vertices) {
7405 m_boxMinPoint += translation;
7406 m_boxMaxPoint += translation;
7433 for (
auto &vertex : m_vertices) {
7434 vertex.
rotate(n0, n1, angle);
7440 std::array<std::array<double, 3>, 3> originalBox = {{m_boxMinPoint, m_boxMaxPoint}};
7449 for (
int i = 0; i < 2; ++i) {
7450 double xCorner = originalBox[i][0];
7451 for (
int j = 0; j < 2; ++j) {
7452 double yCorner = originalBox[j][1];
7453 for (
int k = 0; k < 2; ++k) {
7454 double zCorner = originalBox[k][2];
7456 std::array<double, 3> corner = {{xCorner, yCorner, zCorner}};
7478 double n1y,
double n1z,
double angle)
7480 rotate({{n0x, n0y, n0z}}, {{n1x, n1y, n1z}}, angle);
7492 scale(scaling, m_boxMinPoint);
7504 for (
auto &vertex : m_vertices) {
7505 vertex.
scale(scaling, center);
7510 for (
int k = 0; k < 3; ++k) {
7511 m_boxMinPoint[k] = center[k] + scaling[k] * (m_boxMinPoint[k] - center[k]);
7512 m_boxMaxPoint[k] = center[k] + scaling[k] * (m_boxMaxPoint[k] - center[k]);
7526 scale({{scaling, scaling, scaling}}, m_boxMinPoint);
7537 scale({{scaling, scaling, scaling}}, center);
7549 scale({{sx, sy, sz}}, m_boxMinPoint);
7564 scale({{sx, sy, sz}}, center);
7577 m_toleranceCustom =
true;
7588 m_tolerance = tolerance;
7608 m_toleranceCustom =
false;
7622 const double DEFAULT_TOLERANCE = 1e-14;
7624 m_tolerance = DEFAULT_TOLERANCE;
7635 return m_toleranceCustom;
7658 std::unordered_map<long, long> vertexMap;
7659 for (
const Cell &cell : m_cells) {
7660 int nCellFaces = cell.getFaceCount();
7661 for (
int i = 0; i < nCellFaces; ++i) {
7662 if (!cell.isFaceBorder(i)) {
7669 int nFaceVertices = faceConnect.
size();
7671 std::unique_ptr<long[]> faceEnvelopeConnect = std::unique_ptr<long[]>(
new long[nFaceVertices]);
7672 for (
int j = 0; j < nFaceVertices; ++j) {
7673 long vertexId = faceConnect[j];
7677 if (vertexMap.count(vertexId) == 0) {
7680 vertexMap[vertexId] = envelopeVertex->
getId();
7684 faceEnvelopeConnect[j] = vertexMap.at(vertexId);
7689 envelope.
addCell(faceType, std::move(faceEnvelopeConnect));
7703 std::string indent = std::string(padding,
' ');
7708 out << indent<<
"Vertices --------------------------------" << std::endl;
7717 out << indent<<
"Faces -----------------------------------" << std::endl;
7718 out << indent<<
" # faces " <<
countFaces() << std::endl;
7724 out << indent<<
"Cells -----------------------------------" << std::endl;
7725 out << indent<<
" # cells " <<
getCellCount() << std::endl;
7740 std::string indent = std::string(padding,
' ');
7741 for (
const Vertex &vertex : m_vertices) {
7742 out << indent <<
"vertex: " << std::endl;
7743 vertex.
display(out, padding + 2);
7756 std::string indent = std::string(padding,
' ');
7757 for (
const Cell &cell : m_cells) {
7758 out << indent <<
"cell: " << std::endl;
7759 cell.display(out, padding + 2);
7772 std::string indent = std::string(padding,
' ');
7773 for (
const Interface &interface : m_interfaces) {
7774 out << indent <<
"interface: " << std::endl;
7775 interface.display(out, padding + 2);
7806 return m_vtkWriteTarget;
7816 m_vtkWriteTarget = writeTarget;
7826 if (m_vtkWriteTarget == WRITE_TARGET_CELLS_ALL) {
7828#if BITPIT_ENABLE_MPI==1
7829 }
else if (m_vtkWriteTarget == WRITE_TARGET_CELLS_INTERNAL) {
7850 std::vector<std::string> streamedGeomFields;
7858 streamedGeomFields.push_back(field.
getName());
7861 for (
const std::string &name : streamedGeomFields) {
7863 VTKField updatedField(field);
7864 updatedField.setStreamer(*updated);
7869 std::vector<std::string> streamedDataFields;
7872 const VTKField &field = *itr;
7873 if (&field.getStreamer() != original) {
7877 streamedDataFields.push_back(field.getName());
7880 for (
const std::string &name : streamedDataFields) {
7881 const VTKField &field = *(m_vtk.
findData(name));
7882 VTKField updatedField(field);
7883 updatedField.setStreamer(*updated);
7886 m_vtk.
addData(std::move(updatedField));
7902 if (name ==
"Points") {
7905 std::size_t vertexRawId = itr.getRawIndex();
7906 long vertexVTKId = m_vtkVertexMap.
rawAt(vertexRawId);
7907 if (vertexVTKId != Vertex::NULL_ID) {
7908 const Vertex &vertex = m_vertices.rawAt(vertexRawId);
7912 }
else if (name ==
"offsets") {
7915 offset += cell.getVertexCount();
7918 }
else if (name ==
"types") {
7921 switch (cell.getType()) {
7923 case ElementType::VERTEX:
7924 VTKType = VTKElementType::VERTEX;
7927 case ElementType::LINE:
7928 VTKType = VTKElementType::LINE;
7931 case ElementType::TRIANGLE:
7932 VTKType = VTKElementType::TRIANGLE;
7935 case ElementType::PIXEL:
7936 VTKType = VTKElementType::PIXEL;
7939 case ElementType::QUAD:
7940 VTKType = VTKElementType::QUAD;
7943 case ElementType::POLYGON:
7944 VTKType = VTKElementType::POLYGON;
7947 case ElementType::TETRA:
7948 VTKType = VTKElementType::TETRA;
7951 case ElementType::VOXEL:
7952 VTKType = VTKElementType::VOXEL;
7955 case ElementType::HEXAHEDRON:
7956 VTKType = VTKElementType::HEXAHEDRON;
7959 case ElementType::WEDGE:
7960 VTKType = VTKElementType::WEDGE;
7963 case ElementType::PYRAMID:
7964 VTKType = VTKElementType::PYRAMID;
7967 case ElementType::POLYHEDRON:
7968 VTKType = VTKElementType::POLYHEDRON;
7972 VTKType = VTKElementType::UNDEFINED;
7979 }
else if (name ==
"connectivity") {
7982 const int nCellVertices = cellVertexIds.
size();
7983 for (
int k = 0; k < nCellVertices; ++k) {
7984 long vertexId = cellVertexIds[k];
7985 long vtkVertexId = m_vtkVertexMap.
at(vertexId);
7989 }
else if (name ==
"faces") {
7991 if (cell.getDimension() <= 2 || cell.hasInfo()) {
7994 std::vector<long> faceStream = cell.getFaceStream();
7996 int faceStreamSize = faceStream.size();
7997 for (
int k = 0; k < faceStreamSize; ++k) {
8002 }
else if (name ==
"faceoffsets") {
8005 if (cell.getDimension() <= 2 || cell.hasInfo()) {
8008 offset += cell.getFaceStreamSize();
8013 }
else if (name ==
"cellIndex") {
8017 }
else if (name ==
"PID") {
8021 }
else if (name ==
"vertexIndex") {
8024 std::size_t vertexRawId = itr.getRawIndex();
8025 long vertexVTKId = m_vtkVertexMap.
rawAt(vertexRawId);
8026 if (vertexVTKId != Vertex::NULL_ID) {
8027 long vertexId = itr.getId();
8031#if BITPIT_ENABLE_MPI==1
8032 }
else if (name ==
"cellGlobalIndex") {
8037 }
else if (name ==
"cellRank") {
8041 }
else if (name ==
"cellHaloLayer") {
8045 }
else if (name ==
"vertexRank") {
8048 std::size_t vertexRawId = itr.getRawIndex();
8049 long vertexVTKId = m_vtkVertexMap.
rawAt(vertexRawId);
8050 if (vertexVTKId != Vertex::NULL_ID) {
8069 for(
Cell &cell : m_cells) {
8070 cell.renumberVertices(map);
8075 interface.renumberVertices(map);
8080 createVertexIndexGenerator(
true);
8095 for (
auto &cell: m_cells) {
8096 long *adjacencies = cell.getAdjacencies();
8097 int nCellAdjacencies = cell.getAdjacencyCount();
8098 for (
int i = 0; i < nCellAdjacencies; ++i) {
8099 long &neighId = adjacencies[i];
8100 neighId = map[neighId];
8105 for (
Interface &interface: m_interfaces) {
8106 long ownerId = interface.getOwner();
8107 int ownerFace = interface.getOwnerFace();
8108 interface.setOwner(map.at(ownerId), ownerFace);
8110 long neighId = interface.getNeigh();
8112 int neighFace = interface.getNeighFace();
8113 interface.setNeigh(map.at(neighId), neighFace);
8118 if (m_lastInternalCellId >= 0) {
8119 m_lastInternalCellId = map.at(m_lastInternalCellId);
8122#if BITPIT_ENABLE_MPI==1
8123 if (m_firstGhostCellId >= 0) {
8124 m_firstGhostCellId = map.at(m_firstGhostCellId);
8130 createCellIndexGenerator(
true);
8133#if BITPIT_ENABLE_MPI==1
8136 updatePartitioningInfo(
true);
8152 for (
Cell &cell: m_cells) {
8153 long *interfaces = cell.getInterfaces();
8154 int nCellInterfaces = cell.getInterfaceCount();
8155 for (
int i = 0; i < nCellInterfaces; ++i) {
8156 long &interfaceId = interfaces[i];
8157 interfaceId = map.at(interfaceId);
8163 createInterfaceIndexGenerator(
true);
8189 const int KERNEL_DUMP_VERSION = 12;
8191 return (KERNEL_DUMP_VERSION + _getDumpVersion());
8210 return constPatch->
dump(stream);
8228 assert(!dirty &&
"Dumping a patch that is not up-to-date is not supported.");
8240#if BITPIT_ENABLE_MPI==1
8251#if BITPIT_ENABLE_MPI==1
8273 if (m_toleranceCustom) {
8280 if (hasVertexAutoIndexing) {
8281 dumpVertexAutoIndexing(stream);
8286 if (hasInterfaceAutoIndexing) {
8287 dumpInterfaceAutoIndexing(stream);
8292 if (hasCellAutoIndexing) {
8293 dumpCellAutoIndexing(stream);
8316 throw std::runtime_error (
"The version of the file does not match the required version");
8337#if BITPIT_ENABLE_MPI==1
8349#if BITPIT_ENABLE_MPI==1
8372#if BITPIT_ENABLE_MPI==1
8375 updatePartitioningInfo(
true);
8380 int hasCustomTolerance;
8382 if (hasCustomTolerance) {
8391 bool hasVertexAutoIndexing;
8393 if (hasVertexAutoIndexing) {
8394 restoreVertexAutoIndexing(stream);
8399 bool hasInterfaceAutoIndexing;
8401 if (hasInterfaceAutoIndexing) {
8402 restoreInterfaceAutoIndexing(stream);
8407 bool hasCellAutoIndexing;
8409 if (hasCellAutoIndexing) {
8410 restoreCellAutoIndexing(stream);
8422void PatchKernel::mergeAdaptionInfo(std::vector<adaption::Info> &&source, std::vector<adaption::Info> &destination)
8424 if (source.empty()) {
8426 }
else if (destination.empty()) {
8427 destination.swap(source);
8431 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
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
ConstProxyVector< long > getFaceConnect(int face) 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.
void initialize(long id, ElementType type)
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)
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)
Numbering information about the patch.
long getCellGlobalId(long id) const
id_t getId(const id_t &fallback=-1) const noexcept
Iterator for the class PiercedStorage.
The PiercedStorageRange allow to iterate using range-based loops over a PiercedStorage.
void setStaticKernel(const PiercedKernel< id_t > *kernel)
void unsetKernel(bool release=true)
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)
Metafunction for generating a pierced vector.
PiercedVectorStorage< value_t, id_t >::iterator iterator
Metafunction for generating a list of elements that can be either stored in an external vectror or,...
__PXV_POINTER__ data() noexcept
__PXV_STORAGE_POINTER__ storedData() noexcept
The QualifiedCellHalfFace class defines cell half-faces.
QualifiedCell & getCell() 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.
void setDimensions(uint64_t, uint64_t, uint64_t nconn=0, uint64_t nfacestream=0)
void setGeomData(VTKUnstructuredField, std::vector< T > &)
const VTKField * findGeomData(const std::string &name) const
std::size_t getDataCount() const
VTKField & addData(VTKField &&field)
const VTKField * findData(const std::string &name) const
std::vector< VTKField >::const_iterator getDataEnd() const
void removeData(const std::string &)
std::string getName() const
void setName(const std::string &)
std::vector< VTKField >::const_iterator getDataBegin() const
std::vector< VTKField >::const_iterator getGeomDataBegin() const
std::vector< VTKField >::const_iterator getGeomDataEnd() const
std::size_t getGeomDataCount() const
void write(VTKWriteMode writeMode, double time)
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()
array3D rotatePoint(const array3D &P, const array3D &n0, const array3D &n1, double angle)
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)