@@ -629,7 +629,7 @@ std::vector<adaption::Info> PatchKernel::update(bool trackAdaption, bool squeeze
629629	}
630630
631631	//  Finalize alterations
632- 	finalizeAlterations (squeezeStorage);
632+ 	mergeAdaptionInfo ( finalizeAlterations (trackAdaption,  squeezeStorage), adaptionData );
633633
634634	//  Spawn
635635	bool  spawnNeeed = (getSpawnStatus () == SPAWN_NEEDED);
@@ -795,7 +795,9 @@ std::vector<adaption::Info> PatchKernel::adaptionPrepare(bool trackAdaption)
795795	 - new ghost cells that have been created; 
796796	 - new ghost vertices that have been created; 
797797	 - ghost cells that have been deleted; 
798- 	 - ghost vertices that have been deleted. 
798+ 	 - ghost vertices that have been deleted; 
799+ 	 - new interfaces that have been created; 
800+ 	 - interfaces that have been deleted. 
799801
800802	\param trackAdaption if set to true the function will return the changes 
801803	done to the patch during the adaption 
@@ -818,10 +820,10 @@ std::vector<adaption::Info> PatchKernel::adaptionAlter(bool trackAdaption, bool
818820	}
819821
820822	//  Adapt the patch
821- 	adaptionData =  _adaptionAlter (trackAdaption);
823+ 	mergeAdaptionInfo ( _adaptionAlter (trackAdaption), adaptionData );
822824
823825	//  Finalize patch alterations
824- 	finalizeAlterations (squeezeStorage);
826+ 	mergeAdaptionInfo ( finalizeAlterations (trackAdaption,  squeezeStorage), adaptionData );
825827
826828	//  Update the status
827829	setAdaptionStatus (ADAPTION_ALTERED);
@@ -864,11 +866,15 @@ void PatchKernel::settleAdaptionMarkers()
864866/* !
865867	Finalize patch alterations. 
866868
869+ 	\param trackAdaption if set to true the function will return the changes 
870+ 	that will be performed in the alter step 
867871	\param squeezeStorage if set to true patch data structures will be 
868872	squeezed 
869873*/ 
870- void  PatchKernel::finalizeAlterations (bool  squeezeStorage)
874+ std::vector<adaption::Info>  PatchKernel::finalizeAlterations (bool  trackAdaption,  bool  squeezeStorage)
871875{
876+ 	std::vector<adaption::Info> adaptionData;
877+ 
872878	//  Flush vertex data structures
873879	m_vertices.flush ();
874880
@@ -890,7 +896,7 @@ void PatchKernel::finalizeAlterations(bool squeezeStorage)
890896	//  Update interfaces
891897	bool  interfacesDirty = areInterfacesDirty ();
892898	if  (interfacesDirty) {
893- 		updateInterfaces ();
899+ 		mergeAdaptionInfo ( updateInterfaces (false , trackAdaption), adaptionData );
894900	}
895901
896902	//  Flush interfaces data structures
@@ -917,6 +923,8 @@ void PatchKernel::finalizeAlterations(bool squeezeStorage)
917923	m_cells.sync ();
918924	m_interfaces.sync ();
919925	m_vertices.sync ();
926+ 
927+ 	return  adaptionData;
920928}
921929
922930/* !
@@ -1063,43 +1071,79 @@ void PatchKernel::resetCells()
10631071
10641072	This function doesn't change the build strategy, it only resets the 
10651073	existing interface. 
1074+ 
1075+ 	\param trackAdaption if set to true the changes to the patch will be 
1076+ 	tracked 
10661077*/ 
1067- void  PatchKernel::resetInterfaces ()
1078+ std::vector<adaption::Info>  PatchKernel::resetInterfaces (bool  trackAdaption )
10681079{
1080+ 	std::vector<adaption::Info> adaptionData;
1081+ 
10691082	//  Early return if no interfaces have been built
10701083	if  (getInterfacesBuildStrategy () == INTERFACES_NONE) {
1071- 		return ;
1084+ 		return  adaptionData ;
10721085	}
10731086
10741087	//  Reset the interfaces
1075- 	_resetInterfaces (false );
1088+ 	adaptionData =  _resetInterfaces (trackAdaption,  false );
10761089
10771090	//  Mark cell interfaces as dirty
10781091	setCellAlterationFlags (FLAG_INTERFACES_DIRTY);
10791092
10801093	//  Clear list of altered interfaces
10811094	m_alteredInterfaces.clear ();
1095+ 
1096+ 	return  adaptionData;
10821097}
10831098
10841099/* !
10851100	Internal function to reset the interfaces of the patch. 
10861101
10871102	This function doesn't change the alteration flags. 
10881103
1104+ 	\param trackAdaption if set to true the changes to the patch will be 
1105+ 	tracked 
10891106	\param release if it's true the memory hold by the interfaces will be 
10901107	released, otherwise the interfaces will be reset but their memory will 
10911108	not be released 
10921109*/ 
1093- void  PatchKernel::_resetInterfaces (bool  release)
1110+ std::vector<adaption::Info>  PatchKernel::_resetInterfaces (bool  trackAdaption,  bool  release)
10941111{
1112+ 	//  Reset cell interfaces
10951113	for  (auto  &cell : m_cells) {
10961114		cell.resetInterfaces (!release);
10971115	}
10981116
1117+ 	//  Track deleted interfaces
1118+ 	adaption::InfoCollection adaptionData;
1119+ 	if  (trackAdaption) {
1120+ 		//  Identify interior interfaces
1121+ 		std::unordered_set<long > internalInterfaces;
1122+ 		for  (CellConstIterator cellItr = internalCellBegin (); cellItr != internalCellEnd (); ++cellItr) {
1123+ 			const  Cell &cell = *cellItr;
1124+ 			const  int  nCellInterfaces = cell.getInterfaceCount ();
1125+ 			const  long  *cellInterfaces = cell.getInterfaces ();
1126+ 			for  (int  k = 0 ; k < nCellInterfaces; ++k) {
1127+ 				long  interfaceId = cellInterfaces[k];
1128+ 				internalInterfaces.insert (interfaceId);
1129+ 			}
1130+ 		}
1131+ 
1132+ 		//  Track interfaces that will be deleted
1133+ 		// 
1134+ 		//  Only interfaces on interior cells will be tracked.
1135+ 		std::size_t  adaptionInfoId = adaptionData.insert (adaption::TYPE_DELETION, adaption::ENTITY_INTERFACE);
1136+ 		adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
1137+ 		adaptionInfo.previous  = std::vector<long >(internalInterfaces.begin (), internalInterfaces.end ());
1138+ 	}
1139+ 
1140+ 	//  Delete interfaces
10991141	m_interfaces.clear (release);
11001142	if  (m_interfaceIdGenerator) {
11011143		m_interfaceIdGenerator->reset ();
11021144	}
1145+ 
1146+ 	return  adaptionData.dump ();
11031147}
11041148
11051149/* !
@@ -6335,9 +6379,12 @@ void PatchKernel::buildInterfaces()
63356379	adjacencies are not yet initialized an exception is thrown. 
63366380
63376381	\param strategy is the build strategy that will be used 
6382+ 	\param trackAdaption if set to true the changes to the patch will be tracked 
63386383*/ 
6339- void  PatchKernel::initializeInterfaces (InterfacesBuildStrategy strategy)
6384+ std::vector<adaption::Info>  PatchKernel::initializeInterfaces (InterfacesBuildStrategy strategy,  bool  trackAdaption )
63406385{
6386+ 	std::vector<adaption::Info> adaptionData;
6387+ 
63416388	//  Interfaces need adjacencies
63426389	if  (getAdjacenciesBuildStrategy () == ADJACENCIES_NONE) {
63436390		throw  std::runtime_error  (" Adjacencies are mandatory for building the interfaces." 
@@ -6349,10 +6396,10 @@ void PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy)
63496396	//  Early return if we don't need interfaces
63506397	if  (strategy == INTERFACES_NONE) {
63516398		if  (currentStrategy != INTERFACES_NONE) {
6352- 			destroyInterfaces ();
6399+ 			mergeAdaptionInfo ( destroyInterfaces (trackAdaption), adaptionData );
63536400		}
63546401
6355- 		return ;
6402+ 		return  adaptionData ;
63566403	}
63576404
63586405	//  Update the build strategy
@@ -6361,30 +6408,35 @@ void PatchKernel::initializeInterfaces(InterfacesBuildStrategy strategy)
63616408	}
63626409
63636410	//  Reset interfaces
6364- 	resetInterfaces ();
6411+ 	mergeAdaptionInfo ( resetInterfaces (trackAdaption), adaptionData );
63656412
63666413	//  Update the interfaces
6367- 	updateInterfaces ();
6414+ 	mergeAdaptionInfo (updateInterfaces (false , trackAdaption), adaptionData);
6415+ 
6416+ 	return  adaptionData;
63686417}
63696418
63706419/* !
63716420	Update the interfaces of the patch. 
63726421
63736422	\param forcedUpdated if set to true, bounding box information will be 
63746423	updated also if they are not marked as dirty 
6424+ 	\param trackAdaption if set to true the changes to the patch will be tracked 
63756425*/ 
6376- void  PatchKernel::updateInterfaces (bool  forcedUpdated)
6426+ std::vector<adaption::Info>  PatchKernel::updateInterfaces (bool  forcedUpdated,  bool  trackAdaption )
63776427{
6428+ 	std::vector<adaption::Info> adaptionData;
6429+ 
63786430	//  Early return if interfaces are not built
63796431	InterfacesBuildStrategy currentStrategy = getInterfacesBuildStrategy ();
63806432	if  (currentStrategy == INTERFACES_NONE) {
6381- 		return ;
6433+ 		return  adaptionData ;
63826434	}
63836435
63846436	//  Check if the interfaces are dirty
63856437	bool  interfacesDirty = areInterfacesDirty ();
63866438	if  (!interfacesDirty && !forcedUpdated) {
6387- 		return ;
6439+ 		return  adaptionData ;
63886440	}
63896441
63906442	//  Interfaces need up-to-date adjacencies
@@ -6398,10 +6450,10 @@ void PatchKernel::updateInterfaces(bool forcedUpdated)
63986450		setExpert (true );
63996451
64006452		//  Prune stale interfaces
6401- 		pruneStaleInterfaces ();
6453+ 		mergeAdaptionInfo ( pruneStaleInterfaces (trackAdaption), adaptionData );
64026454
64036455		//  Update interfaces
6404- 		_updateInterfaces ();
6456+ 		mergeAdaptionInfo ( _updateInterfaces (trackAdaption), adaptionData );
64056457
64066458		//  Interfaces are now updated
64076459		unsetCellAlterationFlags (FLAG_INTERFACES_DIRTY);
@@ -6410,25 +6462,32 @@ void PatchKernel::updateInterfaces(bool forcedUpdated)
64106462		//  Set original advanced editing status
64116463		setExpert (originalExpertStatus);
64126464	} else  {
6413- 		initializeInterfaces (currentStrategy);
6465+ 		mergeAdaptionInfo ( initializeInterfaces (currentStrategy, trackAdaption), adaptionData );
64146466	}
6467+ 
6468+ 	return  adaptionData;
64156469}
64166470
64176471/* !
64186472	Destroy the interfaces. 
64196473
64206474	After deleting the interfaces, this function changes the build strategy 
64216475	to "None". 
6476+ 
6477+ 	\param trackAdaption if set to true the changes to the patch will be 
6478+ 	tracked 
64226479*/ 
6423- void  PatchKernel::destroyInterfaces ()
6480+ std::vector<adaption::Info>  PatchKernel::destroyInterfaces (bool  trackAdaption )
64246481{
6482+ 	std::vector<adaption::Info> adaptionData;
6483+ 
64256484	//  Early return if no interfaces have been built
64266485	if  (getInterfacesBuildStrategy () == INTERFACES_NONE) {
6427- 		return ;
6486+ 		return  adaptionData ;
64286487	}
64296488
6430- 	//  Destroy  the interfaces
6431- 	_resetInterfaces (true );
6489+ 	//  Reset  the interfaces
6490+ 	adaptionData =  _resetInterfaces (trackAdaption,  true );
64326491
64336492	//  Clear list of cells with dirty interfaces
64346493	unsetCellAlterationFlags (FLAG_INTERFACES_DIRTY);
@@ -6438,19 +6497,26 @@ void PatchKernel::destroyInterfaces()
64386497
64396498	//  Set interface build strategy
64406499	setInterfacesBuildStrategy (INTERFACES_NONE);
6500+ 
6501+ 	return  adaptionData;
64416502}
64426503
64436504/* !
64446505	Prune stale interfaces. 
64456506
64466507	The list of cells to process and the list of stale interfaces are filled 
64476508	during cell deletion. 
6509+ 
6510+ 	\param trackAdaption if set to true the changes to the patch will be tracked 
6511+ 	\result If the adaption is tracked, returns a vector of adaption::Info 
6512+ 	with all the changes done to the patch during the adaption, otherwise an 
6513+ 	empty vector will be returned. 
64486514*/ 
6449- void  PatchKernel::pruneStaleInterfaces ()
6515+ std::vector<adaption::Info>  PatchKernel::pruneStaleInterfaces (bool  trackAdaption )
64506516{
64516517	//  Early return if no interfaces have been built
64526518	if  (getInterfacesBuildStrategy () == INTERFACES_NONE) {
6453- 		return ;
6519+ 		return  std::vector<adaption::Info>() ;
64546520	}
64556521
64566522	//  Remove dangling interfaces from cells
@@ -6495,15 +6561,27 @@ void PatchKernel::pruneStaleInterfaces()
64956561		danglingInterfaces.push_back (interfaceId);
64966562	}
64976563	deleteInterfaces (danglingInterfaces);
6564+ 
6565+ 	//  Track changes
6566+ 	adaption::InfoCollection adaptionData;
6567+ 	if  (trackAdaption) {
6568+ 		std::size_t  adaptionInfoId = adaptionData.insert (adaption::TYPE_DELETION, adaption::ENTITY_INTERFACE);
6569+ 		adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
6570+ 		adaptionInfo.previous  = std::move (danglingInterfaces);
6571+ 	}
6572+ 
6573+ 	return  adaptionData.dump ();
64986574}
64996575
65006576/* !
65016577	Internal function to update the interfaces of the patch. 
65026578
65036579	The function will process the cells whose interfaces have been marked as 
65046580	dirty. 
6581+ 
6582+ 	\param trackAdaption if set to true the changes to the patch will be tracked 
65056583*/ 
6506- void  PatchKernel::_updateInterfaces ()
6584+ std::vector<adaption::Info>  PatchKernel::_updateInterfaces (bool  trackAdaption )
65076585{
65086586	//  Update interfaces
65096587	// 
@@ -6516,6 +6594,7 @@ void PatchKernel::_updateInterfaces()
65166594	// 
65176595	//  On border faces of internal cells we need to build an interface, also
65186596	//  if there are no adjacencies.
6597+ 	std::vector<long > createdInterfaces;
65196598	for  (const  auto  &entry : m_alteredCells) {
65206599		AlterationFlags cellAlterationFlags = entry.second ;
65216600		if  (!testAlterationFlags (cellAlterationFlags, FLAG_INTERFACES_DIRTY)) {
@@ -6545,14 +6624,35 @@ void PatchKernel::_updateInterfaces()
65456624
65466625					int  neighFace = findAdjoinNeighFace (cell, face, *neigh);
65476626
6548- 					buildCellInterface (&cell, face, neigh, neighFace);
6627+ 					//  Build the interface
6628+ 					InterfaceIterator interfaceIterator = buildCellInterface (&cell, face, neigh, neighFace);
6629+ 
6630+ 					//  Track changes
6631+ 					if  (trackAdaption) {
6632+ 						createdInterfaces.push_back (interfaceIterator.getId ());
6633+ 					}
65496634				}
65506635			} else  if  (nFaceInterfaces == 0 ) {
65516636				//  Internal borderes need an interface
6552- 				buildCellInterface (&cell, face, nullptr , -1 );
6637+ 				InterfaceIterator interfaceIterator = buildCellInterface (&cell, face, nullptr , -1 );
6638+ 
6639+ 				//  Track changes
6640+ 				if  (trackAdaption) {
6641+ 					createdInterfaces.push_back (interfaceIterator.getId ());
6642+ 				}
65536643			}
65546644		}
65556645	}
6646+ 
6647+ 	//  Track changes
6648+ 	adaption::InfoCollection adaptionData;
6649+ 	if  (trackAdaption) {
6650+ 		std::size_t  adaptionInfoId = adaptionData.insert (adaption::TYPE_CREATION, adaption::ENTITY_INTERFACE);
6651+ 		adaption::Info &adaptionInfo = adaptionData[adaptionInfoId];
6652+ 		adaptionInfo.current  = std::move (createdInterfaces);
6653+ 	}
6654+ 
6655+ 	return  adaptionData.dump ();
65566656}
65576657
65586658/* !
@@ -8342,12 +8442,15 @@ void PatchKernel::mergeAdaptionInfo(std::vector<adaption::Info> &&source, std::v
83428442{
83438443	if  (source.empty ()) {
83448444		return ;
8345- 	} else  if  (destination.empty ()) {
8445+ 	}
8446+ 
8447+ 	if  (destination.empty ()) {
83468448		destination.swap (source);
83478449		return ;
83488450	}
83498451
8350- 	throw  std::runtime_error  (" Unable to merge the adaption info." 
8452+ 	destination.insert (destination.end (), std::make_move_iterator (source.begin ()), std::make_move_iterator (source.end ()));
8453+ 	source.clear ();
83518454}
83528455
83538456}
0 commit comments