From 0e54e260e682582a6d7fda06ff789ba02a001918 Mon Sep 17 00:00:00 2001
From: HRN <hamid.r.norouzi@gmail.com>
Date: Sun, 5 May 2024 23:05:23 +0330
Subject: [PATCH] boundaryProcessor for dataTransfer - in boundaryList in
 afterIteration, data transfer occurs to transfer data between prcocessors -
 transferData method is added to boundaryBase - Some modification to format
 the output messages in terminal

---
 .../ContactSearch/ContactSearch.hpp           |  7 ------
 .../boundaryContactSearch.cpp                 |  4 +--
 .../contactSearch/contactSearch.cpp           |  4 +--
 src/Interaction/interaction/interaction.cpp   |  9 +++----
 .../boundarySphereInteraction.cpp             |  4 +--
 .../boundarySphereInteractionList.cpp         |  2 +-
 .../sphereInteraction/sphereInteraction.cpp   |  3 ---
 src/phasicFlow/eventManagement/message.hpp    | 10 +++++---
 src/phasicFlow/globals/globalSettings.cpp     | 10 +++++++-
 src/phasicFlow/globals/globalSettings.hpp     |  2 ++
 .../boundaries/boundaryBase/boundaryBase.cpp  | 25 +++++++++++++++----
 .../boundaries/boundaryBase/boundaryBase.hpp  | 16 ++++++++++++
 .../boundaryBase/boundaryBaseKernels.cpp      | 18 ++++++++++---
 .../boundaryBase/boundaryBaseKernels.hpp      |  3 ++-
 .../boundaries/boundaryList.cpp               | 20 +++++++++++++--
 15 files changed, 99 insertions(+), 38 deletions(-)

diff --git a/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp b/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp
index 8906eaa5..d80813ca 100644
--- a/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp
+++ b/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp
@@ -76,10 +76,6 @@ public:
 			*this)
 	{
 
-		/*auto method = dict().getVal<word>("method");
-				
-		auto nbDict = dict().subDict(method+"Info");*/
-
 		real minD;
 		real maxD;
 		this->Particles().boundingSphereMinMax(minD, maxD);
@@ -110,9 +106,6 @@ public:
 				wVertices,
 				wNormals
 			);
-		REPORT(2)<<"Contact search algorithm for particle-particle is "<<
-				 Green_Text(ppwContactSearch_().typeName())<<END_REPORT;
-
 	}
 
 
diff --git a/src/Interaction/contactSearch/boundaries/boundaryContactSearch/boundaryContactSearch.cpp b/src/Interaction/contactSearch/boundaries/boundaryContactSearch/boundaryContactSearch.cpp
index e7d6145e..d0d31a61 100644
--- a/src/Interaction/contactSearch/boundaries/boundaryContactSearch/boundaryContactSearch.cpp
+++ b/src/Interaction/contactSearch/boundaries/boundaryContactSearch/boundaryContactSearch.cpp
@@ -50,13 +50,13 @@ pFlow::boundaryContactSearch::create(
 
 	if( boundaryBasevCtorSelector_.search(bType) )
 	{
-		REPORT(2)<<"Creating contact search boundary "<< Green_Text(bType)<<
+		pOutput.space(4)<<"Creating contact search boundary "<< Green_Text(bType)<<
 		" for "<<boundary.name()<<endl;
 		return boundaryBasevCtorSelector_[bType](dict, boundary, cSearch);
 	}
 	else if(boundaryBasevCtorSelector_.search(altBType))
 	{
-		REPORT(2)<<"Creating contact search boundary "<< Green_Text(altBType)<<
+		pOutput.space(4)<<"Creating contact search boundary "<< Green_Text(altBType)<<
 		" for "<<boundary.name()<<endl;
 		return boundaryBasevCtorSelector_[altBType](dict, boundary, cSearch);
 	}
diff --git a/src/Interaction/contactSearch/contactSearch/contactSearch.cpp b/src/Interaction/contactSearch/contactSearch/contactSearch.cpp
index 03574077..8e8ca3dc 100644
--- a/src/Interaction/contactSearch/contactSearch/contactSearch.cpp
+++ b/src/Interaction/contactSearch/contactSearch/contactSearch.cpp
@@ -55,13 +55,11 @@ pFlow::uniquePtr<pFlow::contactSearch> pFlow::contactSearch::create(
 	word baseMethName	= dict.getVal<word>("method");	
 
 	auto model = angleBracketsNames("ContactSearch", baseMethName);
-
-	REPORT(1)<<"Selecting contact search model . . ."<<END_REPORT;
 	
+	pOutput.space(2)<<"Selecting contact search model "<<Green_Text(model)<<endl;	
 	if( dictionaryvCtorSelector_.search(model))
 	{
 		auto objPtr = dictionaryvCtorSelector_[model] (dict, extDomain, prtcl, geom, timers);
-		REPORT(2)<<"Model "<< Green_Text(model)<<" is created."<< END_REPORT;
 		return objPtr;
 	}
 	else
diff --git a/src/Interaction/interaction/interaction.cpp b/src/Interaction/interaction/interaction.cpp
index 84786617..c6099405 100644
--- a/src/Interaction/interaction/interaction.cpp
+++ b/src/Interaction/interaction/interaction.cpp
@@ -71,15 +71,14 @@ pFlow::uniquePtr<pFlow::interaction> pFlow::interaction::create
 			clType);
 
 
-	
-	REPORT(1)<<"Creating interaction "<<Green_Text(interactionModel)<<" . . ."<<END_REPORT;
+	gSettings::sleepMiliSeconds(
+			1000*(pFlowProcessors().localSize()-pFlowProcessors().localRank()-1));
+	pOutput.space(2)<<"Creating interaction "<<Green_Text(interactionModel)<<" . . ."<<END_REPORT;
 	if( systemControlvCtorSelector_.search(interactionModel) )
 	{
 		auto objPtr = 
 			systemControlvCtorSelector_[interactionModel]
-			(control, prtcl, geom);
-
-		
+			(control, prtcl, geom);	
 		return objPtr;
 	}
 	else
diff --git a/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.cpp b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.cpp
index 0f2f64fb..f9f6374a 100644
--- a/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.cpp
+++ b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.cpp
@@ -56,7 +56,7 @@ pFlow::boundarySphereInteraction<cFM, gMM>::create(
 
 	if (boundaryBasevCtorSelector_.search(boundaryTypeName))
 	{
-		REPORT(2) << "Creating boundry type " << Green_Text(boundaryTypeName) << 
+		pOutput.space(4) << "Creating boundry type " << Green_Text(boundaryTypeName) << 
 		" for boundary " << boundary.name() << " . . ." << END_REPORT;
 		return boundaryBasevCtorSelector_[boundaryTypeName](
 			boundary,
@@ -67,7 +67,7 @@ pFlow::boundarySphereInteraction<cFM, gMM>::create(
 	{
 		// if boundary condition is not implemented, the default is used
 		
-		REPORT(2) << "Creating boundry type " << Green_Text(altBTypeName) << 
+		pOutput.space(4) << "Creating boundry type " << Green_Text(altBTypeName) << 
 		" for boundary " << boundary.name() << " . . ." << END_REPORT;
 		return boundaryBasevCtorSelector_[altBTypeName](
 			boundary,
diff --git a/src/Interaction/sphereInteraction/boundaries/boundarySphereInteractionList.cpp b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteractionList.cpp
index 7bc37847..00b86bc4 100644
--- a/src/Interaction/sphereInteraction/boundaries/boundarySphereInteractionList.cpp
+++ b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteractionList.cpp
@@ -10,7 +10,7 @@ pFlow::boundarySphereInteractionList<CFModel, gMModel>::boundarySphereInteractio
 	ListPtr<boundarySphereInteraction<CFModel,gMModel>>(6),
 	boundaries_(sphPrtcls.pStruct().boundaries())
 {
-
+	//gSettings::sleepMiliSeconds(1000*pFlowProcessors().localRank());
 	for(uint32 i=0; i<6; i++)
 	{
 		this->set(
diff --git a/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.cpp b/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.cpp
index 40176d02..b4546521 100644
--- a/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.cpp
+++ b/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.cpp
@@ -26,7 +26,6 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::createSphereInteraction()
 
 	auto modelDict = this->subDict("model");
 
-	REPORT(1)<<"Createing contact force model . . ."<<END_REPORT;
 	forceModel_ = makeUnique<ContactForceModel>(
 		this->numMaterials(),
 		rhoD.deviceView(),
@@ -46,8 +45,6 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::createSphereInteraction()
 	
 	pwContactList_ = makeUnique<ContactListType>(nPrtcl/5+1);
 
-	
-
 	return true;
 }
 
diff --git a/src/phasicFlow/eventManagement/message.hpp b/src/phasicFlow/eventManagement/message.hpp
index e5e1bfb0..3ece7411 100644
--- a/src/phasicFlow/eventManagement/message.hpp
+++ b/src/phasicFlow/eventManagement/message.hpp
@@ -47,13 +47,15 @@ public:
 		BNDR_TRANSFER   = 9,  // boundary indices transfered
 		BNDR_RESET		= 10,  // boundary indices reset entirely  
 		BNDR_DELETE 	= 11,  // boundary indices deleted
-		BNDR_APPEND		= 12
+		BNDR_APPEND		= 12,  // 
+		BNDR_PROCTRANS1 = 13,  // transfer of data between processors step 1 
+		BNDR_PROCTRANS2 = 14   // transfer of data between processors step 2
 	};
 
 	
 private:
 
-	static constexpr size_t numberOfEvents_ = 13;
+	static constexpr size_t numberOfEvents_ = 15;
 
 	std::bitset<numberOfEvents_> events_{0x0000};
 	
@@ -72,7 +74,9 @@ private:
 		"transferredIndices",
 		"",
 		"deletedIndices",
-		"appendedIndices"
+		"appendedIndices",
+		"transferredIndices",
+		"numberRecieved"
 	};
 
 public:
diff --git a/src/phasicFlow/globals/globalSettings.cpp b/src/phasicFlow/globals/globalSettings.cpp
index 36115c8c..ced0f76a 100644
--- a/src/phasicFlow/globals/globalSettings.cpp
+++ b/src/phasicFlow/globals/globalSettings.cpp
@@ -1,6 +1,14 @@
 
+#include <chrono>
+#include <thread>
 
 #include "globalSettings.hpp"
 
 
-const double pFlow::gSettings::vectorGrowthFactor__ = 1.1;
\ No newline at end of file
+
+const double pFlow::gSettings::vectorGrowthFactor__ = 1.1;
+
+void pFlow::gSettings::sleepMiliSeconds(int miliSeconds)
+{
+    std::this_thread::sleep_for(std::chrono::milliseconds(miliSeconds));
+}
diff --git a/src/phasicFlow/globals/globalSettings.hpp b/src/phasicFlow/globals/globalSettings.hpp
index 734db3c3..21dead3f 100755
--- a/src/phasicFlow/globals/globalSettings.hpp
+++ b/src/phasicFlow/globals/globalSettings.hpp
@@ -28,6 +28,8 @@ namespace pFlow::gSettings
 
 extern const double vectorGrowthFactor__;
 
+void sleepMiliSeconds(int miliSeconds);
+
 }
 
 
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.cpp b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.cpp
index 596eb238..f8307478 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.cpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.cpp
@@ -98,15 +98,11 @@ bool pFlow::boundaryBase::removeIndices
 		keepIndices
 	);
 	
-	if(!internal_.deletePoints(removeIndices))
+	if(!setRemoveKeepIndices(removeIndices, keepIndices))
 	{
-		fatalErrorInFunction<<
-		"error in deleting points from boundary "<< name()<<endl;
 		return false;
 	}
 
-	setNewIndices(keepIndices);
-
 	anyList aList;
 	
 	aList.emplaceBack(
@@ -129,6 +125,25 @@ bool pFlow::boundaryBase::removeIndices
 	return true;
 }
 
+bool pFlow::boundaryBase::setRemoveKeepIndices
+(
+	const uint32Vector_D &removeIndices, 
+	const uint32Vector_D &keepIndices
+)
+{
+
+	if(!internal_.deletePoints(removeIndices))
+	{
+		fatalErrorInFunction<<
+		"error in deleting points from boundary "<< name()<<endl;
+		return false;
+	}
+
+	setNewIndices(keepIndices);
+
+    return true;
+}
+
 bool pFlow::boundaryBase::transferPoints
 (
 	uint32 numTransfer, 
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.hpp b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.hpp
index 54fb94d0..9b63c9df 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.hpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.hpp
@@ -102,6 +102,10 @@ protected:
 		uint32 numRemove, 
 		const uint32Vector_D& removeMask);
 	
+	bool setRemoveKeepIndices(
+		const uint32Vector_D& removeIndices,
+		const uint32Vector_D& keepIndices);
+	
 	bool transferPoints(
 		uint32 numTransfer, 
 		const uint32Vector_D& transferMask,
@@ -133,6 +137,18 @@ protected:
 	{
 		return true;
 	}
+
+	/// @brief This method is called when a transfer of data 
+	/// is to be performed between processors (in afterIteration).
+	/// @param step is the step in the transfer of data. 
+	/// @return true: if operation requires at least one additional step 
+	/// to complete. false: if the operation is complete and no need for
+	/// additional step in operation. 
+	virtual 
+	bool transferData(int step)
+	{
+		return false;
+	}
 	
 public:
 
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBaseKernels.cpp b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBaseKernels.cpp
index 0b0fd10c..df8cdfa5 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBaseKernels.cpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBaseKernels.cpp
@@ -67,14 +67,26 @@ void pFlow::boundaryBaseKernels::createRemoveKeepIndices
     uint32 numRemove,
     const uint32Vector_D& removeMask, 
     uint32Vector_D& removeIndices, 
-    uint32Vector_D& keepIndices
+    uint32Vector_D& keepIndices,
+    bool exactCap
 )
 {
     uint32 numTotal = indices.size();
     uint32 numKeep = numTotal - numRemove;
+    if(exactCap)
+    {
+        removeIndices.reallocate(numRemove, numRemove);
+        keepIndices.reallocate(numKeep, numKeep);
+    }
+    else
+    {
+        removeIndices.clear();
+        removeIndices.resize(numRemove);
+        
+        keepIndices.clear();
+        keepIndices.resize(numKeep);
+    }
     
-    removeIndices.reallocate(numRemove, numRemove);
-    keepIndices.reallocate(numKeep, numKeep);
 
     auto maskD = removeMask.deviceViewAll();
     const auto& removeD = removeIndices.deviceViewAll();
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBaseKernels.hpp b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBaseKernels.hpp
index 780360f7..60f08c83 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBaseKernels.hpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBaseKernels.hpp
@@ -38,7 +38,8 @@ void createRemoveKeepIndices(
     uint32 numRemove,
     const uint32Vector_D& removeMask, 
     uint32Vector_D& removeIndices, 
-    uint32Vector_D& keepIndices);
+    uint32Vector_D& keepIndices,
+    bool exactCap = true);
 
 
 }
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryList.cpp b/src/phasicFlow/structuredData/boundaries/boundaryList.cpp
index a00476d6..6cccb194 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryList.cpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryList.cpp
@@ -205,7 +205,23 @@ pFlow::boundaryList::iterate(uint32 iter, real t, real dt)
 bool
 pFlow::boundaryList::afterIteration(uint32 iter, real t, real dt)
 {
-	for (auto& bdry : *this)
+	
+	std::array<bool,6> requireStep{true, true, true, true, true, true};
+
+	int step = 1;
+	while(std::any_of(requireStep.begin(), requireStep.end(), [](bool v) { return v==true; }))
+	{
+		for(auto i=0uL; i<6; i++)
+		{
+			if(requireStep[i])
+			{
+				requireStep[i] = this->operator[](i).transferData(step);
+			}
+		}
+		step++;
+	}
+
+	/*for (auto& bdry : *this)
 	{
 		if (!bdry->afterIteration(iter, t, dt))
 		{
@@ -213,6 +229,6 @@ pFlow::boundaryList::afterIteration(uint32 iter, real t, real dt)
 			                     << bdry->name() << endl;
 			return false;
 		}
-	}
+	}*/
 	return true;
 }