@@ -630,7 +630,7 @@ std::vector<adaption::Info> PatchKernel::update(bool trackAdaption, bool squeeze
630630	}
631631
632632	//  Finalize alterations
633- 	finalizeAlterations (squeezeStorage);
633+ 	mergeAdaptionInfo ( finalizeAlterations (trackAdaption,  squeezeStorage), adaptionData );
634634
635635	//  Spawn
636636	bool  spawnNeeed = (getSpawnStatus () == SPAWN_NEEDED);
@@ -796,7 +796,9 @@ std::vector<adaption::Info> PatchKernel::adaptionPrepare(bool trackAdaption)
796796	 - new ghost cells that have been created; 
797797	 - new ghost vertices that have been created; 
798798	 - ghost cells that have been deleted; 
799- 	 - ghost vertices that have been deleted. 
799+ 	 - ghost vertices that have been deleted; 
800+ 	 - new interfaces that have been created; 
801+ 	 - interfaces that have been deleted. 
800802
801803	\param trackAdaption if set to true the function will return the changes 
802804	done to the patch during the adaption 
@@ -819,10 +821,10 @@ std::vector<adaption::Info> PatchKernel::adaptionAlter(bool trackAdaption, bool
819821	}
820822
821823	//  Adapt the patch
822- 	adaptionData =  _adaptionAlter (trackAdaption);
824+ 	mergeAdaptionInfo ( _adaptionAlter (trackAdaption), adaptionData );
823825
824826	//  Finalize patch alterations
825- 	finalizeAlterations (squeezeStorage);
827+ 	mergeAdaptionInfo ( finalizeAlterations (trackAdaption,  squeezeStorage), adaptionData );
826828
827829	//  Update the status
828830	setAdaptionStatus (ADAPTION_ALTERED);
@@ -865,11 +867,15 @@ void PatchKernel::settleAdaptionMarkers()
865867/* !
866868	Finalize patch alterations. 
867869
870+ 	\param trackAdaption if set to true the function will return the changes 
871+ 	that will be performed in the alter step 
868872	\param squeezeStorage if set to true patch data structures will be 
869873	squeezed 
870874*/ 
871- void  PatchKernel::finalizeAlterations (bool  squeezeStorage)
875+ std::vector<adaption::Info>  PatchKernel::finalizeAlterations (bool  trackAdaption,  bool  squeezeStorage)
872876{
877+ 	std::vector<adaption::Info> adaptionData;
878+ 
873879	//  Flush vertex data structures
874880	m_vertices.flush ();
875881
@@ -891,7 +897,7 @@ void PatchKernel::finalizeAlterations(bool squeezeStorage)
891897	//  Update interfaces
892898	bool  interfacesDirty = areInterfacesDirty ();
893899	if  (interfacesDirty) {
894- 		updateInterfaces ();
900+ 		mergeAdaptionInfo ( updateInterfaces (false , trackAdaption), adaptionData );
895901	}
896902
897903	//  Flush interfaces data structures
@@ -918,6 +924,8 @@ void PatchKernel::finalizeAlterations(bool squeezeStorage)
918924	m_cells.sync ();
919925	m_interfaces.sync ();
920926	m_vertices.sync ();
927+ 
928+ 	return  adaptionData;
921929}
922930
923931/* !
@@ -1064,43 +1072,79 @@ void PatchKernel::resetCells()
10641072
10651073	This function doesn't change the build strategy, it only resets the 
10661074	existing interface. 
1075+ 
1076+ 	\param trackAdaption if set to true the changes to the patch will be 
1077+ 	tracked 
10671078*/ 
1068- void  PatchKernel::resetInterfaces ()
1079+ std::vector<adaption::Info>  PatchKernel::resetInterfaces (bool  trackAdaption )
10691080{
1081+ 	std::vector<adaption::Info> adaptionData;
1082+ 
10701083	//  Early return if no interfaces have been built
10711084	if  (getInterfacesBuildStrategy () == INTERFACES_NONE) {
1072- 		return ;
1085+ 		return  adaptionData ;
10731086	}
10741087
10751088	//  Reset the interfaces
1076- 	_resetInterfaces (false );
1089+ 	adaptionData =  _resetInterfaces (trackAdaption,  false );
10771090
10781091	//  Mark cell interfaces as dirty
10791092	setCellAlterationFlags (FLAG_INTERFACES_DIRTY);
10801093
10811094	//  Clear list of altered interfaces
10821095	m_alteredInterfaces.clear ();
1096+ 
1097+ 	return  adaptionData;
10831098}
10841099
10851100/* !
10861101	Internal function to reset the interfaces of the patch. 
10871102
10881103	This function doesn't change the alteration flags. 
10891104
1105+ 	\param trackAdaption if set to true the changes to the patch will be 
1106+ 	tracked 
10901107	\param release if it's true the memory hold by the interfaces will be 
10911108	released, otherwise the interfaces will be reset but their memory will 
10921109	not be released 
10931110*/ 
1094- void  PatchKernel::_resetInterfaces (bool  release)
1111+ std::vector<adaption::Info>  PatchKernel::_resetInterfaces (bool  trackAdaption,  bool  release)
10951112{
1113+ 	//  Reset cell interfaces
10961114	for  (auto  &cell : m_cells) {
10971115		cell.resetInterfaces (!release);
10981116	}
10991117
1118+ 	//  Track deleted interfaces
1119+ 	adaption::InfoCollection adaptionData;
1120+ 	if  (trackAdaption) {
1121+ 		//  Identify interior interfaces
1122+ 		std::unordered_set<long > internalInterfaces;
1123+ 		for  (CellConstIterator cellItr = internalCellBegin (); cellItr != internalCellEnd (); ++cellItr) {
1124+ 			const  Cell &cell = *cellItr;
1125+ 			const  int  nCellInterfaces = cell.getInterfaceCount ();
1126+ 			const  long  *cellInterfaces = cell.getInterfaces ();
1127+ 			for  (int  k = 0 ; k < nCellInterfaces; ++k) {
1128+ 				long  interfaceId = cellInterfaces[k];
1129+ 				internalInterfaces.insert (interfaceId);
1130+ 			}
1131+ 		}
1132+ 
1133+ 		//  Track interfaces that will be deleted
1134+ 		// 
1135+ 		//  Only interfaces on interior cells will be tracked.
1136+ 		std::size_t  adaptionInfoId = adaptionData.insert (adaption::TYPE_DELETION, adaption::ENTITY_INTERFACE);
1137+ 		adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
1138+ 		adaptionInfo.previous  = std::vector<long >(internalInterfaces.begin (), internalInterfaces.end ());
1139+ 	}
1140+ 
1141+ 	//  Delete interfaces
11001142	m_interfaces.clear (release);
11011143	if  (m_interfaceIdGenerator) {
11021144		m_interfaceIdGenerator->reset ();
11031145	}
1146+ 
1147+ 	return  adaptionData.dump ();
11041148}
11051149
11061150/* !
@@ -6377,9 +6421,12 @@ void PatchKernel::buildInterfaces()
63776421	adjacencies are not yet initialized an exception is thrown. 
63786422
63796423	\param strategy is the build strategy that will be used 
6424+ 	\param trackAdaption if set to true the changes to the patch will be tracked 
63806425*/ 
6381- void  PatchKernel::initializeInterfaces (InterfacesBuildStrategy strategy)
6426+ std::vector<adaption::Info>  PatchKernel::initializeInterfaces (InterfacesBuildStrategy strategy,  bool  trackAdaption )
63826427{
6428+ 	std::vector<adaption::Info> adaptionData;
6429+ 
63836430	//  Interfaces need adjacencies
63846431	if  (getAdjacenciesBuildStrategy () == ADJACENCIES_NONE) {
63856432		throw  std::runtime_error  (" Adjacencies are mandatory for building the interfaces." 
@@ -6391,10 +6438,10 @@ void PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy)
63916438	//  Early return if we don't need interfaces
63926439	if  (strategy == INTERFACES_NONE) {
63936440		if  (currentStrategy != INTERFACES_NONE) {
6394- 			destroyInterfaces ();
6441+ 			mergeAdaptionInfo ( destroyInterfaces (trackAdaption), adaptionData );
63956442		}
63966443
6397- 		return ;
6444+ 		return  adaptionData ;
63986445	}
63996446
64006447	//  Update the build strategy
@@ -6403,30 +6450,35 @@ void PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy)
64036450	}
64046451
64056452	//  Reset interfaces
6406- 	resetInterfaces ();
6453+ 	mergeAdaptionInfo ( resetInterfaces (trackAdaption), adaptionData );
64076454
64086455	//  Update the interfaces
6409- 	updateInterfaces ();
6456+ 	mergeAdaptionInfo (updateInterfaces (false , trackAdaption), adaptionData);
6457+ 
6458+ 	return  adaptionData;
64106459}
64116460
64126461/* !
64136462	Update the interfaces of the patch. 
64146463
64156464	\param forcedUpdated if set to true, bounding box information will be 
64166465	updated also if they are not marked as dirty 
6466+ 	\param trackAdaption if set to true the changes to the patch will be tracked 
64176467*/ 
6418- void  PatchKernel::updateInterfaces (bool  forcedUpdated)
6468+ std::vector<adaption::Info>  PatchKernel::updateInterfaces (bool  forcedUpdated,  bool  trackAdaption )
64196469{
6470+ 	std::vector<adaption::Info> adaptionData;
6471+ 
64206472	//  Early return if interfaces are not built
64216473	InterfacesBuildStrategy currentStrategy = getInterfacesBuildStrategy ();
64226474	if  (currentStrategy == INTERFACES_NONE) {
6423- 		return ;
6475+ 		return  adaptionData ;
64246476	}
64256477
64266478	//  Check if the interfaces are dirty
64276479	bool  interfacesDirty = areInterfacesDirty ();
64286480	if  (!interfacesDirty && !forcedUpdated) {
6429- 		return ;
6481+ 		return  adaptionData ;
64306482	}
64316483
64326484	//  Interfaces need up-to-date adjacencies
@@ -6440,10 +6492,10 @@ void PatchKernel::updateInterfaces(bool forcedUpdated)
64406492		setExpert (true );
64416493
64426494		//  Prune stale interfaces
6443- 		pruneStaleInterfaces ();
6495+ 		mergeAdaptionInfo ( pruneStaleInterfaces (trackAdaption), adaptionData );
64446496
64456497		//  Update interfaces
6446- 		_updateInterfaces ();
6498+ 		mergeAdaptionInfo ( _updateInterfaces (trackAdaption), adaptionData );
64476499
64486500		//  Interfaces are now updated
64496501		unsetCellAlterationFlags (FLAG_INTERFACES_DIRTY);
@@ -6452,25 +6504,32 @@ void PatchKernel::updateInterfaces(bool forcedUpdated)
64526504		//  Set original advanced editing status
64536505		setExpert (originalExpertStatus);
64546506	} else  {
6455- 		initializeInterfaces (currentStrategy);
6507+ 		mergeAdaptionInfo ( initializeInterfaces (currentStrategy, trackAdaption), adaptionData );
64566508	}
6509+ 
6510+ 	return  adaptionData;
64576511}
64586512
64596513/* !
64606514	Destroy the interfaces. 
64616515
64626516	After deleting the interfaces, this function changes the build strategy 
64636517	to "None". 
6518+ 
6519+ 	\param trackAdaption if set to true the changes to the patch will be 
6520+ 	tracked 
64646521*/ 
6465- void  PatchKernel::destroyInterfaces ()
6522+ std::vector<adaption::Info>  PatchKernel::destroyInterfaces (bool  trackAdaption )
64666523{
6524+ 	std::vector<adaption::Info> adaptionData;
6525+ 
64676526	//  Early return if no interfaces have been built
64686527	if  (getInterfacesBuildStrategy () == INTERFACES_NONE) {
6469- 		return ;
6528+ 		return  adaptionData ;
64706529	}
64716530
6472- 	//  Destroy  the interfaces
6473- 	_resetInterfaces (true );
6531+ 	//  Reset  the interfaces
6532+ 	adaptionData =  _resetInterfaces (trackAdaption,  true );
64746533
64756534	//  Clear list of cells with dirty interfaces
64766535	unsetCellAlterationFlags (FLAG_INTERFACES_DIRTY);
@@ -6480,19 +6539,26 @@ void PatchKernel::destroyInterfaces()
64806539
64816540	//  Set interface build strategy
64826541	setInterfacesBuildStrategy (INTERFACES_NONE);
6542+ 
6543+ 	return  adaptionData;
64836544}
64846545
64856546/* !
64866547	Prune stale interfaces. 
64876548
64886549	The list of cells to process and the list of stale interfaces are filled 
64896550	during cell deletion. 
6551+ 
6552+ 	\param trackAdaption if set to true the changes to the patch will be tracked 
6553+ 	\result If the adaption is tracked, returns a vector of adaption::Info 
6554+ 	with all the changes done to the patch during the adaption, otherwise an 
6555+ 	empty vector will be returned. 
64906556*/ 
6491- void  PatchKernel::pruneStaleInterfaces ()
6557+ std::vector<adaption::Info>  PatchKernel::pruneStaleInterfaces (bool  trackAdaption )
64926558{
64936559	//  Early return if no interfaces have been built
64946560	if  (getInterfacesBuildStrategy () == INTERFACES_NONE) {
6495- 		return ;
6561+ 		return  std::vector<adaption::Info>() ;
64966562	}
64976563
64986564	//  Remove dangling interfaces from cells
@@ -6537,15 +6603,27 @@ void PatchKernel::pruneStaleInterfaces()
65376603		danglingInterfaces.push_back (interfaceId);
65386604	}
65396605	deleteInterfaces (danglingInterfaces);
6606+ 
6607+ 	//  Track changes
6608+ 	adaption::InfoCollection adaptionData;
6609+ 	if  (trackAdaption) {
6610+ 		std::size_t  adaptionInfoId = adaptionData.insert (adaption::TYPE_DELETION, adaption::ENTITY_INTERFACE);
6611+ 		adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
6612+ 		adaptionInfo.previous  = std::move (danglingInterfaces);
6613+ 	}
6614+ 
6615+ 	return  adaptionData.dump ();
65406616}
65416617
65426618/* !
65436619	Internal function to update the interfaces of the patch. 
65446620
65456621	The function will process the cells whose interfaces have been marked as 
65466622	dirty. 
6623+ 
6624+ 	\param trackAdaption if set to true the changes to the patch will be tracked 
65476625*/ 
6548- void  PatchKernel::_updateInterfaces ()
6626+ std::vector<adaption::Info>  PatchKernel::_updateInterfaces (bool  trackAdaption )
65496627{
65506628	//  Update interfaces
65516629	// 
@@ -6558,6 +6636,7 @@ void PatchKernel::_updateInterfaces()
65586636	// 
65596637	//  On border faces of internal cells we need to build an interface, also
65606638	//  if there are no adjacencies.
6639+ 	std::vector<long > createdInterfaces;
65616640	for  (const  auto  &entry : m_alteredCells) {
65626641		AlterationFlags cellAlterationFlags = entry.second ;
65636642		if  (!testAlterationFlags (cellAlterationFlags, FLAG_INTERFACES_DIRTY)) {
@@ -6587,14 +6666,35 @@ void PatchKernel::_updateInterfaces()
65876666
65886667					int  neighFace = findAdjoinNeighFace (cell, face, *neigh);
65896668
6590- 					buildCellInterface (&cell, face, neigh, neighFace);
6669+ 					//  Build the interface
6670+ 					InterfaceIterator interfaceIterator = buildCellInterface (&cell, face, neigh, neighFace);
6671+ 
6672+ 					//  Track changes
6673+ 					if  (trackAdaption) {
6674+ 						createdInterfaces.push_back (interfaceIterator.getId ());
6675+ 					}
65916676				}
65926677			} else  if  (nFaceInterfaces == 0 ) {
65936678				//  Internal borderes need an interface
6594- 				buildCellInterface (&cell, face, nullptr , -1 );
6679+ 				InterfaceIterator interfaceIterator = buildCellInterface (&cell, face, nullptr , -1 );
6680+ 
6681+ 				//  Track changes
6682+ 				if  (trackAdaption) {
6683+ 					createdInterfaces.push_back (interfaceIterator.getId ());
6684+ 				}
65956685			}
65966686		}
65976687	}
6688+ 
6689+ 	//  Track changes
6690+ 	adaption::InfoCollection adaptionData;
6691+ 	if  (trackAdaption) {
6692+ 		std::size_t  adaptionInfoId = adaptionData.insert (adaption::TYPE_CREATION, adaption::ENTITY_INTERFACE);
6693+ 		adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
6694+ 		adaptionInfo.current  = std::move (createdInterfaces);
6695+ 	}
6696+ 
6697+ 	return  adaptionData.dump ();
65986698}
65996699
66006700/* !
@@ -8445,12 +8545,15 @@ void PatchKernel::mergeAdaptionInfo(std::vector<adaption::Info> &&source, std::v
84458545{
84468546	if  (source.empty ()) {
84478547		return ;
8448- 	} else  if  (destination.empty ()) {
8548+ 	}
8549+ 
8550+ 	if  (destination.empty ()) {
84498551		destination.swap (source);
84508552		return ;
84518553	}
84528554
8453- 	throw  std::runtime_error  (" Unable to merge the adaption info." 
8555+ 	destination.insert (destination.end (), std::make_move_iterator (source.begin ()), std::make_move_iterator (source.end ()));
8556+ 	source.clear ();
84548557}
84558558
84568559}
0 commit comments