Skip to content

Commit

Permalink
patchkernel: add tracking of interfaces during adaptation/partitioning
Browse files Browse the repository at this point in the history
  • Loading branch information
andrea-iob committed Aug 1, 2023
1 parent 26f4aee commit b8fb3af
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 60 deletions.
167 changes: 135 additions & 32 deletions src/patchkernel/patch_kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ std::vector<adaption::Info> PatchKernel::update(bool trackAdaption, bool squeeze
}

// Finalize alterations
finalizeAlterations(squeezeStorage);
mergeAdaptionInfo(finalizeAlterations(trackAdaption, squeezeStorage), adaptionData);

// Spawn
bool spawnNeeed = (getSpawnStatus() == SPAWN_NEEDED);
Expand Down Expand Up @@ -796,7 +796,9 @@ std::vector<adaption::Info> PatchKernel::adaptionPrepare(bool trackAdaption)
- new ghost cells that have been created;
- new ghost vertices that have been created;
- ghost cells that have been deleted;
- ghost vertices that have been deleted.
- ghost vertices that have been deleted;
- new interfaces that have been created;
- interfaces that have been deleted.
\param trackAdaption if set to true the function will return the changes
done to the patch during the adaption
Expand All @@ -819,10 +821,10 @@ std::vector<adaption::Info> PatchKernel::adaptionAlter(bool trackAdaption, bool
}

// Adapt the patch
adaptionData = _adaptionAlter(trackAdaption);
mergeAdaptionInfo(_adaptionAlter(trackAdaption), adaptionData);

// Finalize patch alterations
finalizeAlterations(squeezeStorage);
mergeAdaptionInfo(finalizeAlterations(trackAdaption, squeezeStorage), adaptionData);

// Update the status
setAdaptionStatus(ADAPTION_ALTERED);
Expand Down Expand Up @@ -865,11 +867,15 @@ void PatchKernel::settleAdaptionMarkers()
/*!
Finalize patch alterations.
\param trackAdaption if set to true the function will return the changes
that will be performed in the alter step
\param squeezeStorage if set to true patch data structures will be
squeezed
*/
void PatchKernel::finalizeAlterations(bool squeezeStorage)
std::vector<adaption::Info> PatchKernel::finalizeAlterations(bool trackAdaption, bool squeezeStorage)
{
std::vector<adaption::Info> adaptionData;

// Flush vertex data structures
m_vertices.flush();

Expand All @@ -891,7 +897,7 @@ void PatchKernel::finalizeAlterations(bool squeezeStorage)
// Update interfaces
bool interfacesDirty = areInterfacesDirty();
if (interfacesDirty) {
updateInterfaces();
mergeAdaptionInfo(updateInterfaces(false, trackAdaption), adaptionData);
}

// Flush interfaces data structures
Expand All @@ -918,6 +924,8 @@ void PatchKernel::finalizeAlterations(bool squeezeStorage)
m_cells.sync();
m_interfaces.sync();
m_vertices.sync();

return adaptionData;
}

/*!
Expand Down Expand Up @@ -1064,43 +1072,79 @@ void PatchKernel::resetCells()
This function doesn't change the build strategy, it only resets the
existing interface.
\param trackAdaption if set to true the changes to the patch will be
tracked
*/
void PatchKernel::resetInterfaces()
std::vector<adaption::Info> PatchKernel::resetInterfaces(bool trackAdaption)
{
std::vector<adaption::Info> adaptionData;

// Early return if no interfaces have been built
if (getInterfacesBuildStrategy() == INTERFACES_NONE) {
return;
return adaptionData;
}

// Reset the interfaces
_resetInterfaces(false);
adaptionData = _resetInterfaces(trackAdaption, false);

// Mark cell interfaces as dirty
setCellAlterationFlags(FLAG_INTERFACES_DIRTY);

// Clear list of altered interfaces
m_alteredInterfaces.clear();

return adaptionData;
}

/*!
Internal function to reset the interfaces of the patch.
This function doesn't change the alteration flags.
\param trackAdaption if set to true the changes to the patch will be
tracked
\param release if it's true the memory hold by the interfaces will be
released, otherwise the interfaces will be reset but their memory will
not be released
*/
void PatchKernel::_resetInterfaces(bool release)
std::vector<adaption::Info> PatchKernel::_resetInterfaces(bool trackAdaption, bool release)
{
// Reset cell interfaces
for (auto &cell : m_cells) {
cell.resetInterfaces(!release);
}

// Track deleted interfaces
adaption::InfoCollection adaptionData;
if (trackAdaption) {
// Identify interior interfaces
std::unordered_set<long> internalInterfaces;
for (CellConstIterator cellItr = internalCellBegin(); cellItr != internalCellEnd(); ++cellItr) {
const Cell &cell = *cellItr;
const int nCellInterfaces = cell.getInterfaceCount();
const long *cellInterfaces = cell.getInterfaces();
for (int k = 0; k < nCellInterfaces; ++k) {
long interfaceId = cellInterfaces[k];
internalInterfaces.insert(interfaceId);
}
}

// Track interfaces that will be deleted
//
// Only interfaces on interior cells will be tracked.
std::size_t adaptionInfoId = adaptionData.insert(adaption::TYPE_DELETION, adaption::ENTITY_INTERFACE);
adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
adaptionInfo.previous = std::vector<long>(internalInterfaces.begin(), internalInterfaces.end());
}

// Delete interfaces
m_interfaces.clear(release);
if (m_interfaceIdGenerator) {
m_interfaceIdGenerator->reset();
}

return adaptionData.dump();
}

/*!
Expand Down Expand Up @@ -6377,9 +6421,12 @@ void PatchKernel::buildInterfaces()
adjacencies are not yet initialized an exception is thrown.
\param strategy is the build strategy that will be used
\param trackAdaption if set to true the changes to the patch will be tracked
*/
void PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy)
std::vector<adaption::Info> PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy, bool trackAdaption)
{
std::vector<adaption::Info> adaptionData;

// Interfaces need adjacencies
if (getAdjacenciesBuildStrategy() == ADJACENCIES_NONE) {
throw std::runtime_error ("Adjacencies are mandatory for building the interfaces.");
Expand All @@ -6391,10 +6438,10 @@ void PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy)
// Early return if we don't need interfaces
if (strategy == INTERFACES_NONE) {
if (currentStrategy != INTERFACES_NONE) {
destroyInterfaces();
mergeAdaptionInfo(destroyInterfaces(trackAdaption), adaptionData);
}

return;
return adaptionData;
}

// Update the build strategy
Expand All @@ -6403,30 +6450,35 @@ void PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy)
}

// Reset interfaces
resetInterfaces();
mergeAdaptionInfo(resetInterfaces(trackAdaption), adaptionData);

// Update the interfaces
updateInterfaces();
mergeAdaptionInfo(updateInterfaces(false, trackAdaption), adaptionData);

return adaptionData;
}

/*!
Update the interfaces of the patch.
\param forcedUpdated if set to true, bounding box information will be
updated also if they are not marked as dirty
\param trackAdaption if set to true the changes to the patch will be tracked
*/
void PatchKernel::updateInterfaces(bool forcedUpdated)
std::vector<adaption::Info> PatchKernel::updateInterfaces(bool forcedUpdated, bool trackAdaption)
{
std::vector<adaption::Info> adaptionData;

// Early return if interfaces are not built
InterfacesBuildStrategy currentStrategy = getInterfacesBuildStrategy();
if (currentStrategy == INTERFACES_NONE) {
return;
return adaptionData;
}

// Check if the interfaces are dirty
bool interfacesDirty = areInterfacesDirty();
if (!interfacesDirty && !forcedUpdated) {
return;
return adaptionData;
}

// Interfaces need up-to-date adjacencies
Expand All @@ -6440,10 +6492,10 @@ void PatchKernel::updateInterfaces(bool forcedUpdated)
setExpert(true);

// Prune stale interfaces
pruneStaleInterfaces();
mergeAdaptionInfo(pruneStaleInterfaces(trackAdaption), adaptionData);

// Update interfaces
_updateInterfaces();
mergeAdaptionInfo(_updateInterfaces(trackAdaption), adaptionData);

// Interfaces are now updated
unsetCellAlterationFlags(FLAG_INTERFACES_DIRTY);
Expand All @@ -6452,25 +6504,32 @@ void PatchKernel::updateInterfaces(bool forcedUpdated)
// Set original advanced editing status
setExpert(originalExpertStatus);
} else {
initializeInterfaces(currentStrategy);
mergeAdaptionInfo(initializeInterfaces(currentStrategy, trackAdaption), adaptionData);
}

return adaptionData;
}

/*!
Destroy the interfaces.
After deleting the interfaces, this function changes the build strategy
to "None".
\param trackAdaption if set to true the changes to the patch will be
tracked
*/
void PatchKernel::destroyInterfaces()
std::vector<adaption::Info> PatchKernel::destroyInterfaces(bool trackAdaption)
{
std::vector<adaption::Info> adaptionData;

// Early return if no interfaces have been built
if (getInterfacesBuildStrategy() == INTERFACES_NONE) {
return;
return adaptionData;
}

// Destroy the interfaces
_resetInterfaces(true);
// Reset the interfaces
adaptionData = _resetInterfaces(trackAdaption, true);

// Clear list of cells with dirty interfaces
unsetCellAlterationFlags(FLAG_INTERFACES_DIRTY);
Expand All @@ -6480,19 +6539,26 @@ void PatchKernel::destroyInterfaces()

// Set interface build strategy
setInterfacesBuildStrategy(INTERFACES_NONE);

return adaptionData;
}

/*!
Prune stale interfaces.
The list of cells to process and the list of stale interfaces are filled
during cell deletion.
\param trackAdaption if set to true the changes to the patch will be tracked
\result If the adaption is tracked, returns a vector of adaption::Info
with all the changes done to the patch during the adaption, otherwise an
empty vector will be returned.
*/
void PatchKernel::pruneStaleInterfaces()
std::vector<adaption::Info> PatchKernel::pruneStaleInterfaces(bool trackAdaption)
{
// Early return if no interfaces have been built
if (getInterfacesBuildStrategy() == INTERFACES_NONE) {
return;
return std::vector<adaption::Info>();
}

// Remove dangling interfaces from cells
Expand Down Expand Up @@ -6537,15 +6603,27 @@ void PatchKernel::pruneStaleInterfaces()
danglingInterfaces.push_back(interfaceId);
}
deleteInterfaces(danglingInterfaces);

// Track changes
adaption::InfoCollection adaptionData;
if (trackAdaption) {
std::size_t adaptionInfoId = adaptionData.insert(adaption::TYPE_DELETION, adaption::ENTITY_INTERFACE);
adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
adaptionInfo.previous = std::move(danglingInterfaces);
}

return adaptionData.dump();
}

/*!
Internal function to update the interfaces of the patch.
The function will process the cells whose interfaces have been marked as
dirty.
\param trackAdaption if set to true the changes to the patch will be tracked
*/
void PatchKernel::_updateInterfaces()
std::vector<adaption::Info> PatchKernel::_updateInterfaces(bool trackAdaption)
{
// Update interfaces
//
Expand All @@ -6558,6 +6636,7 @@ void PatchKernel::_updateInterfaces()
//
// On border faces of internal cells we need to build an interface, also
// if there are no adjacencies.
std::vector<long> createdInterfaces;
for (const auto &entry : m_alteredCells) {
AlterationFlags cellAlterationFlags = entry.second;
if (!testAlterationFlags(cellAlterationFlags, FLAG_INTERFACES_DIRTY)) {
Expand Down Expand Up @@ -6587,14 +6666,35 @@ void PatchKernel::_updateInterfaces()

int neighFace = findAdjoinNeighFace(cell, face, *neigh);

buildCellInterface(&cell, face, neigh, neighFace);
// Build the interface
InterfaceIterator interfaceIterator = buildCellInterface(&cell, face, neigh, neighFace);

// Track changes
if (trackAdaption) {
createdInterfaces.push_back(interfaceIterator.getId());
}
}
} else if (nFaceInterfaces == 0) {
// Internal borderes need an interface
buildCellInterface(&cell, face, nullptr, -1);
InterfaceIterator interfaceIterator = buildCellInterface(&cell, face, nullptr, -1);

// Track changes
if (trackAdaption) {
createdInterfaces.push_back(interfaceIterator.getId());
}
}
}
}

// Track changes
adaption::InfoCollection adaptionData;
if (trackAdaption) {
std::size_t adaptionInfoId = adaptionData.insert(adaption::TYPE_CREATION, adaption::ENTITY_INTERFACE);
adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
adaptionInfo.current = std::move(createdInterfaces);
}

return adaptionData.dump();
}

/*!
Expand Down Expand Up @@ -8445,12 +8545,15 @@ void PatchKernel::mergeAdaptionInfo(std::vector<adaption::Info> &&source, std::v
{
if (source.empty()) {
return;
} else if (destination.empty()) {
}

if (destination.empty()) {
destination.swap(source);
return;
}

throw std::runtime_error ("Unable to merge the adaption info.");
destination.insert(destination.end(), std::make_move_iterator(source.begin()), std::make_move_iterator(source.end()));
source.clear();
}

}
Loading

0 comments on commit b8fb3af

Please sign in to comment.