Skip to content

Commit d63a6c7

Browse files
committed
patchkernel: add tracking of interfaces during adaptation/partitioning
1 parent feecfb2 commit d63a6c7

File tree

7 files changed

+207
-61
lines changed

7 files changed

+207
-61
lines changed

src/patchkernel/patch_kernel.cpp

Lines changed: 135 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ std::vector<adaption::Info> PatchKernel::update(bool trackAdaption, bool squeeze
635635
}
636636

637637
// Finalize alterations
638-
finalizeAlterations(squeezeStorage);
638+
mergeAdaptionInfo(finalizeAlterations(trackAdaption, squeezeStorage), adaptionData);
639639

640640
// Adaption
641641
bool adaptionDirty = (getAdaptionStatus(true) == ADAPTION_DIRTY);
@@ -768,7 +768,9 @@ std::vector<adaption::Info> PatchKernel::adaptionPrepare(bool trackAdaption)
768768
- new ghost cells that have been created;
769769
- new ghost vertices that have been created;
770770
- ghost cells that have been deleted;
771-
- ghost vertices that have been deleted.
771+
- ghost vertices that have been deleted;
772+
- new interfaces that have been created;
773+
- interfaces that have been deleted.
772774
773775
\param trackAdaption if set to true the function will return the changes
774776
done to the patch during the adaption
@@ -796,10 +798,10 @@ std::vector<adaption::Info> PatchKernel::adaptionAlter(bool trackAdaption, bool
796798
}
797799

798800
// Adapt the patch
799-
adaptionData = _adaptionAlter(trackAdaption);
801+
mergeAdaptionInfo(_adaptionAlter(trackAdaption), adaptionData);
800802

801803
// Finalize patch alterations
802-
finalizeAlterations(squeezeStorage);
804+
mergeAdaptionInfo(finalizeAlterations(trackAdaption, squeezeStorage), adaptionData);
803805

804806
// Update the status
805807
setAdaptionStatus(ADAPTION_ALTERED);
@@ -848,11 +850,15 @@ void PatchKernel::settleAdaptionMarkers()
848850
/*!
849851
Finalize patch alterations.
850852
853+
\param trackAdaption if set to true the function will return the changes
854+
that will be performed in the alter step
851855
\param squeezeStorage if set to true patch data structures will be
852856
squeezed
853857
*/
854-
void PatchKernel::finalizeAlterations(bool squeezeStorage)
858+
std::vector<adaption::Info> PatchKernel::finalizeAlterations(bool trackAdaption, bool squeezeStorage)
855859
{
860+
std::vector<adaption::Info> adaptionData;
861+
856862
// Flush vertex data structures
857863
m_vertices.flush();
858864

@@ -874,7 +880,7 @@ void PatchKernel::finalizeAlterations(bool squeezeStorage)
874880
// Update interfaces
875881
bool interfacesDirty = areInterfacesDirty();
876882
if (interfacesDirty) {
877-
updateInterfaces();
883+
mergeAdaptionInfo(updateInterfaces(false, trackAdaption), adaptionData);
878884
}
879885

880886
// Flush interfaces data structures
@@ -901,6 +907,8 @@ void PatchKernel::finalizeAlterations(bool squeezeStorage)
901907
m_cells.sync();
902908
m_interfaces.sync();
903909
m_vertices.sync();
910+
911+
return adaptionData;
904912
}
905913

906914
/*!
@@ -1047,43 +1055,79 @@ void PatchKernel::resetCells()
10471055
10481056
This function doesn't change the build strategy, it only resets the
10491057
existing interface.
1058+
1059+
\param trackAdaption if set to true the changes to the patch will be
1060+
tracked
10501061
*/
1051-
void PatchKernel::resetInterfaces()
1062+
std::vector<adaption::Info> PatchKernel::resetInterfaces(bool trackAdaption)
10521063
{
1064+
std::vector<adaption::Info> adaptionData;
1065+
10531066
// Early return if no interfaces have been built
10541067
if (getInterfacesBuildStrategy() == INTERFACES_NONE) {
1055-
return;
1068+
return adaptionData;
10561069
}
10571070

10581071
// Reset the interfaces
1059-
_resetInterfaces(false);
1072+
adaptionData = _resetInterfaces(trackAdaption, false);
10601073

10611074
// Mark cell interfaces as dirty
10621075
setCellAlterationFlags(FLAG_INTERFACES_DIRTY);
10631076

10641077
// Clear list of altered interfaces
10651078
m_alteredInterfaces.clear();
1079+
1080+
return adaptionData;
10661081
}
10671082

10681083
/*!
10691084
Internal function to reset the interfaces of the patch.
10701085
10711086
This function doesn't change the alteration flags.
10721087
1088+
\param trackAdaption if set to true the changes to the patch will be
1089+
tracked
10731090
\param release if it's true the memory hold by the interfaces will be
10741091
released, otherwise the interfaces will be reset but their memory will
10751092
not be released
10761093
*/
1077-
void PatchKernel::_resetInterfaces(bool release)
1094+
std::vector<adaption::Info> PatchKernel::_resetInterfaces(bool trackAdaption, bool release)
10781095
{
1096+
// Reset cell interfaces
10791097
for (auto &cell : m_cells) {
10801098
cell.resetInterfaces(!release);
10811099
}
10821100

1101+
// Track deleted interfaces
1102+
adaption::InfoCollection adaptionData;
1103+
if (trackAdaption) {
1104+
// Identify interior interfaces
1105+
std::unordered_set<long> internalInterfaces;
1106+
for (CellConstIterator cellItr = internalCellBegin(); cellItr != internalCellEnd(); ++cellItr) {
1107+
const Cell &cell = *cellItr;
1108+
const int nCellInterfaces = cell.getInterfaceCount();
1109+
const long *cellInterfaces = cell.getInterfaces();
1110+
for (int k = 0; k < nCellInterfaces; ++k) {
1111+
long interfaceId = cellInterfaces[k];
1112+
internalInterfaces.insert(interfaceId);
1113+
}
1114+
}
1115+
1116+
// Track interfaces that will be deleted
1117+
//
1118+
// Only interfaces on interior cells will be tracked.
1119+
std::size_t adaptionInfoId = adaptionData.insert(adaption::TYPE_DELETION, adaption::ENTITY_INTERFACE);
1120+
adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
1121+
adaptionInfo.previous = std::vector<long>(internalInterfaces.begin(), internalInterfaces.end());
1122+
}
1123+
1124+
// Delete interfaces
10831125
m_interfaces.clear(release);
10841126
if (m_interfaceIdGenerator) {
10851127
m_interfaceIdGenerator->reset();
10861128
}
1129+
1130+
return adaptionData.dump();
10871131
}
10881132

10891133
/*!
@@ -6449,9 +6493,12 @@ void PatchKernel::buildInterfaces()
64496493
adjacencies are not yet initialized an exception is thrown.
64506494
64516495
\param strategy is the build strategy that will be used
6496+
\param trackAdaption if set to true the changes to the patch will be tracked
64526497
*/
6453-
void PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy)
6498+
std::vector<adaption::Info> PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy, bool trackAdaption)
64546499
{
6500+
std::vector<adaption::Info> adaptionData;
6501+
64556502
// Interfaces need adjacencies
64566503
if (getAdjacenciesBuildStrategy() == ADJACENCIES_NONE) {
64576504
throw std::runtime_error ("Adjacencies are mandatory for building the interfaces.");
@@ -6463,10 +6510,10 @@ void PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy)
64636510
// Early return if we don't need interfaces
64646511
if (strategy == INTERFACES_NONE) {
64656512
if (currentStrategy != INTERFACES_NONE) {
6466-
destroyInterfaces();
6513+
mergeAdaptionInfo(destroyInterfaces(trackAdaption), adaptionData);
64676514
}
64686515

6469-
return;
6516+
return adaptionData;
64706517
}
64716518

64726519
// Update the build strategy
@@ -6475,30 +6522,35 @@ void PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy)
64756522
}
64766523

64776524
// Reset interfaces
6478-
resetInterfaces();
6525+
mergeAdaptionInfo(resetInterfaces(trackAdaption), adaptionData);
64796526

64806527
// Update the interfaces
6481-
updateInterfaces();
6528+
mergeAdaptionInfo(updateInterfaces(false, trackAdaption), adaptionData);
6529+
6530+
return adaptionData;
64826531
}
64836532

64846533
/*!
64856534
Update the interfaces of the patch.
64866535
64876536
\param forcedUpdated if set to true, bounding box information will be
64886537
updated also if they are not marked as dirty
6538+
\param trackAdaption if set to true the changes to the patch will be tracked
64896539
*/
6490-
void PatchKernel::updateInterfaces(bool forcedUpdated)
6540+
std::vector<adaption::Info> PatchKernel::updateInterfaces(bool forcedUpdated, bool trackAdaption)
64916541
{
6542+
std::vector<adaption::Info> adaptionData;
6543+
64926544
// Early return if interfaces are not built
64936545
InterfacesBuildStrategy currentStrategy = getInterfacesBuildStrategy();
64946546
if (currentStrategy == INTERFACES_NONE) {
6495-
return;
6547+
return adaptionData;
64966548
}
64976549

64986550
// Check if the interfaces are dirty
64996551
bool interfacesDirty = areInterfacesDirty();
65006552
if (!interfacesDirty && !forcedUpdated) {
6501-
return;
6553+
return adaptionData;
65026554
}
65036555

65046556
// Interfaces need up-to-date adjacencies
@@ -6512,10 +6564,10 @@ void PatchKernel::updateInterfaces(bool forcedUpdated)
65126564
setAdaptionMode(ADAPTION_MANUAL);
65136565

65146566
// Prune stale interfaces
6515-
pruneStaleInterfaces();
6567+
mergeAdaptionInfo(pruneStaleInterfaces(trackAdaption), adaptionData);
65166568

65176569
// Update interfaces
6518-
_updateInterfaces();
6570+
mergeAdaptionInfo(_updateInterfaces(trackAdaption), adaptionData);
65196571

65206572
// Interfaces are now updated
65216573
unsetCellAlterationFlags(FLAG_INTERFACES_DIRTY);
@@ -6524,25 +6576,32 @@ void PatchKernel::updateInterfaces(bool forcedUpdated)
65246576
// Restore previous adaption mode
65256577
setAdaptionMode(previousAdaptionMode);
65266578
} else {
6527-
initializeInterfaces(currentStrategy);
6579+
mergeAdaptionInfo(initializeInterfaces(currentStrategy, trackAdaption), adaptionData);
65286580
}
6581+
6582+
return adaptionData;
65296583
}
65306584

65316585
/*!
65326586
Destroy the interfaces.
65336587
65346588
After deleting the interfaces, this function changes the build strategy
65356589
to "None".
6590+
6591+
\param trackAdaption if set to true the changes to the patch will be
6592+
tracked
65366593
*/
6537-
void PatchKernel::destroyInterfaces()
6594+
std::vector<adaption::Info> PatchKernel::destroyInterfaces(bool trackAdaption)
65386595
{
6596+
std::vector<adaption::Info> adaptionData;
6597+
65396598
// Early return if no interfaces have been built
65406599
if (getInterfacesBuildStrategy() == INTERFACES_NONE) {
6541-
return;
6600+
return adaptionData;
65426601
}
65436602

6544-
// Destroy the interfaces
6545-
_resetInterfaces(true);
6603+
// Reset the interfaces
6604+
adaptionData = _resetInterfaces(trackAdaption, true);
65466605

65476606
// Clear list of cells with dirty interfaces
65486607
unsetCellAlterationFlags(FLAG_INTERFACES_DIRTY);
@@ -6552,19 +6611,26 @@ void PatchKernel::destroyInterfaces()
65526611

65536612
// Set interface build strategy
65546613
setInterfacesBuildStrategy(INTERFACES_NONE);
6614+
6615+
return adaptionData;
65556616
}
65566617

65576618
/*!
65586619
Prune stale interfaces.
65596620
65606621
The list of cells to process and the list of stale interfaces are filled
65616622
during cell deletion.
6623+
6624+
\param trackAdaption if set to true the changes to the patch will be tracked
6625+
\result If the adaption is tracked, returns a vector of adaption::Info
6626+
with all the changes done to the patch during the adaption, otherwise an
6627+
empty vector will be returned.
65626628
*/
6563-
void PatchKernel::pruneStaleInterfaces()
6629+
std::vector<adaption::Info> PatchKernel::pruneStaleInterfaces(bool trackAdaption)
65646630
{
65656631
// Early return if no interfaces have been built
65666632
if (getInterfacesBuildStrategy() == INTERFACES_NONE) {
6567-
return;
6633+
return std::vector<adaption::Info>();
65686634
}
65696635

65706636
// Remove dangling interfaces from cells
@@ -6609,15 +6675,27 @@ void PatchKernel::pruneStaleInterfaces()
66096675
danglingInterfaces.push_back(interfaceId);
66106676
}
66116677
deleteInterfaces(danglingInterfaces);
6678+
6679+
// Track changes
6680+
adaption::InfoCollection adaptionData;
6681+
if (trackAdaption) {
6682+
std::size_t adaptionInfoId = adaptionData.insert(adaption::TYPE_DELETION, adaption::ENTITY_INTERFACE);
6683+
adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
6684+
adaptionInfo.previous = std::move(danglingInterfaces);
6685+
}
6686+
6687+
return adaptionData.dump();
66126688
}
66136689

66146690
/*!
66156691
Internal function to update the interfaces of the patch.
66166692
66176693
The function will process the cells whose interfaces have been marked as
66186694
dirty.
6695+
6696+
\param trackAdaption if set to true the changes to the patch will be tracked
66196697
*/
6620-
void PatchKernel::_updateInterfaces()
6698+
std::vector<adaption::Info> PatchKernel::_updateInterfaces(bool trackAdaption)
66216699
{
66226700
// Update interfaces
66236701
//
@@ -6630,6 +6708,7 @@ void PatchKernel::_updateInterfaces()
66306708
//
66316709
// On border faces of internal cells we need to build an interface, also
66326710
// if there are no adjacencies.
6711+
std::vector<long> createdInterfaces;
66336712
for (const auto &entry : m_alteredCells) {
66346713
AlterationFlags cellAlterationFlags = entry.second;
66356714
if (!testAlterationFlags(cellAlterationFlags, FLAG_INTERFACES_DIRTY)) {
@@ -6659,14 +6738,35 @@ void PatchKernel::_updateInterfaces()
66596738

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

6662-
buildCellInterface(&cell, face, neigh, neighFace);
6741+
// Build the interface
6742+
InterfaceIterator interfaceIterator = buildCellInterface(&cell, face, neigh, neighFace);
6743+
6744+
// Track changes
6745+
if (trackAdaption) {
6746+
createdInterfaces.push_back(interfaceIterator.getId());
6747+
}
66636748
}
66646749
} else if (nFaceInterfaces == 0) {
66656750
// Internal borderes need an interface
6666-
buildCellInterface(&cell, face, nullptr, -1);
6751+
InterfaceIterator interfaceIterator = buildCellInterface(&cell, face, nullptr, -1);
6752+
6753+
// Track changes
6754+
if (trackAdaption) {
6755+
createdInterfaces.push_back(interfaceIterator.getId());
6756+
}
66676757
}
66686758
}
66696759
}
6760+
6761+
// Track changes
6762+
adaption::InfoCollection adaptionData;
6763+
if (trackAdaption) {
6764+
std::size_t adaptionInfoId = adaptionData.insert(adaption::TYPE_CREATION, adaption::ENTITY_INTERFACE);
6765+
adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
6766+
adaptionInfo.current = std::move(createdInterfaces);
6767+
}
6768+
6769+
return adaptionData.dump();
66706770
}
66716771

66726772
/*!
@@ -8526,12 +8626,15 @@ void PatchKernel::mergeAdaptionInfo(std::vector<adaption::Info> &&source, std::v
85268626
{
85278627
if (source.empty()) {
85288628
return;
8529-
} else if (destination.empty()) {
8629+
}
8630+
8631+
if (destination.empty()) {
85308632
destination.swap(source);
85318633
return;
85328634
}
85338635

8534-
throw std::runtime_error ("Unable to merge the adaption info.");
8636+
destination.insert(destination.end(), std::make_move_iterator(source.begin()), std::make_move_iterator(source.end()));
8637+
source.clear();
85358638
}
85368639

85378640
}

0 commit comments

Comments
 (0)