From 173d3c49178143e0362515ba6fa9888c4e4303dc Mon Sep 17 00:00:00 2001
From: HRN <hamid.r.norouzi@gmail.com>
Date: Sat, 21 Sep 2024 13:37:03 +0330
Subject: [PATCH 1/2] first commit after code loss - develop branch

---
 .../AdamsBashforth2/AB2Kernels.hpp            | 63 +++++++++++++
 .../boundaries/boundaryIntegration.cpp        | 55 +++++++++++
 .../boundaries/boundaryIntegration.hpp        | 91 +++++++++++++++++++
 .../boundaries/boundaryIntegrationList.cpp    | 41 +++++++++
 .../boundaries/boundaryIntegrationList.hpp    | 45 +++++++++
 src/Interaction/CMakeLists.txt                |  5 +-
 .../boundarySphereParticles.cpp               | 64 +++++++++++++
 .../boundarySphereParticles.hpp               | 80 ++++++++++++++++
 .../boundarySphereParticlesList.cpp           | 19 ++++
 .../boundarySphereParticlesList.hpp           | 36 ++++++++
 src/phasicFlow/globals/boundaryConfigs.hpp    | 10 ++
 src/phasicFlow/processors/MPITimer.cpp        | 88 ++++++++++++++++++
 src/phasicFlow/processors/MPITimer.hpp        | 55 +++++++++++
 .../boundaries/boundariesMask.hpp             | 50 ++++++++++
 14 files changed, 700 insertions(+), 2 deletions(-)
 create mode 100644 src/Integration/AdamsBashforth2/AB2Kernels.hpp
 create mode 100644 src/Integration/boundaries/boundaryIntegration.cpp
 create mode 100644 src/Integration/boundaries/boundaryIntegration.hpp
 create mode 100644 src/Integration/boundaries/boundaryIntegrationList.cpp
 create mode 100644 src/Integration/boundaries/boundaryIntegrationList.hpp
 create mode 100644 src/Particles/SphereParticles/boundarySphereParticles.cpp
 create mode 100644 src/Particles/SphereParticles/boundarySphereParticles.hpp
 create mode 100644 src/Particles/SphereParticles/boundarySphereParticlesList.cpp
 create mode 100644 src/Particles/SphereParticles/boundarySphereParticlesList.hpp
 create mode 100644 src/phasicFlow/globals/boundaryConfigs.hpp
 create mode 100644 src/phasicFlow/processors/MPITimer.cpp
 create mode 100644 src/phasicFlow/processors/MPITimer.hpp
 create mode 100644 src/phasicFlow/structuredData/boundaries/boundariesMask.hpp

diff --git a/src/Integration/AdamsBashforth2/AB2Kernels.hpp b/src/Integration/AdamsBashforth2/AB2Kernels.hpp
new file mode 100644
index 00000000..578cf07e
--- /dev/null
+++ b/src/Integration/AdamsBashforth2/AB2Kernels.hpp
@@ -0,0 +1,63 @@
+
+
+#ifndef __AB2Kernels_hpp__
+#define __AB2Kernels_hpp__
+
+#include "KokkosTypes.hpp"
+#include "types.hpp"
+
+namespace pFlow::AB2Kernels
+{
+inline
+bool intAllActive(
+    const word& name,
+	real dt, 
+    rangeU32 activeRng,
+	const deviceViewType1D<realx3>& y, 
+	const deviceViewType1D<realx3>& dy,
+	const deviceViewType1D<realx3>& dy1
+)
+{
+	Kokkos::parallel_for(
+		name,
+		deviceRPolicyStatic (activeRng.start(), activeRng.end()),
+		LAMBDA_HD(uint32 i){
+			y[i] +=  dt*(static_cast<real>(1.5) * dy[i] - static_cast<real>(0.5) * dy1[i]);
+			dy1[i] = dy[i];
+		});
+	Kokkos::fence();
+
+	return true;	
+}
+
+inline
+bool intScattered
+(
+	const word& name,
+	real dt, 
+    const pFlagTypeDevice& activePoints,
+	const deviceViewType1D<realx3>& y, 
+	const deviceViewType1D<realx3>& dy,
+	const deviceViewType1D<realx3>& dy1
+)
+{
+
+	Kokkos::parallel_for(
+		name,
+		deviceRPolicyStatic (activePoints.activeRange().start(), activePoints.activeRange().end()),
+		LAMBDA_HD(uint32 i){
+			if( activePoints(i))
+			{
+				y[i] +=  dt*(static_cast<real>(1.5) * dy[i] - static_cast<real>(0.5) * dy1[i]);
+				dy1[i] = dy[i];
+			}
+		});
+	Kokkos::fence();
+
+
+	return true;
+}
+
+}
+
+#endif
\ No newline at end of file
diff --git a/src/Integration/boundaries/boundaryIntegration.cpp b/src/Integration/boundaries/boundaryIntegration.cpp
new file mode 100644
index 00000000..e13a5624
--- /dev/null
+++ b/src/Integration/boundaries/boundaryIntegration.cpp
@@ -0,0 +1,55 @@
+#include "boundaryIntegration.hpp"
+#include "pointStructure.hpp"
+
+
+pFlow::boundaryIntegration::boundaryIntegration(
+    const boundaryBase &boundary, 
+    const pointStructure &pStruct,  
+    const word &method,
+    integration& intgrtn
+)
+:
+    generalBoundary(boundary, pStruct, "", method),
+    integration_(intgrtn)
+{}
+
+pFlow::uniquePtr<pFlow::boundaryIntegration> pFlow::boundaryIntegration::create(
+    const boundaryBase &boundary, 
+    const pointStructure &pStruct,  
+    const word &method,
+    integration& intgrtn
+)
+{
+
+    word bType = angleBracketsNames2( 
+		"boundaryIntegration",
+		boundary.type(),
+        method);
+
+	word altBType{"boundaryIntegration<none>"};
+
+	if( boundaryBasevCtorSelector_.search(bType) )
+	{
+		pOutput.space(4)<<"Creating boundary "<< Green_Text(bType)<<
+		" for "<<boundary.name()<<endl;
+		return boundaryBasevCtorSelector_[bType](boundary, pStruct, method, intgrtn);
+	}
+	else if(boundaryBasevCtorSelector_.search(altBType))
+	{
+		pOutput.space(4)<<"Creating boundary "<< Green_Text(altBType)<<
+		" for "<<boundary.name()<<endl;
+		return boundaryBasevCtorSelector_[altBType](boundary, pStruct, method, intgrtn);
+	}
+	else
+	{
+		printKeys( 
+			fatalError << "Ctor Selector "<< bType<<
+			" and "<< altBType << " do not exist. \n"
+			<<"Avaiable ones are: \n",
+			boundaryBasevCtorSelector_
+		);
+		fatalExit;
+	}
+	
+	return nullptr;
+}
diff --git a/src/Integration/boundaries/boundaryIntegration.hpp b/src/Integration/boundaries/boundaryIntegration.hpp
new file mode 100644
index 00000000..b3a20805
--- /dev/null
+++ b/src/Integration/boundaries/boundaryIntegration.hpp
@@ -0,0 +1,91 @@
+
+#ifndef __boundaryIntegration_hpp__
+#define __boundaryIntegration_hpp__
+
+
+#include "generalBoundary.hpp"
+#include "virtualConstructor.hpp"
+#include "pointFields.hpp"
+
+namespace pFlow
+{
+
+class integration;
+
+class boundaryIntegration
+:
+    public generalBoundary
+{
+private:
+
+	const integration& 		integration_;
+
+public:
+
+    TypeInfo("boundaryIntegration<none>");
+
+    boundaryIntegration(
+        const boundaryBase& boundary,
+        const pointStructure& pStruct, 
+        const word& method,
+        integration& intgrtn);
+
+    ~boundaryIntegration()override = default;
+
+    create_vCtor(
+        boundaryIntegration,
+        boundaryBase,
+        (
+            const boundaryBase& boundary,
+            const pointStructure& pStruct, 
+            const word& method,
+			integration& intgrtn
+        ),
+        (boundary, pStruct, method, intgrtn)
+    );
+    
+    add_vCtor(
+        boundaryIntegration,
+        boundaryIntegration,
+        boundaryBase
+    );
+
+    bool hearChanges(
+        real t,
+        real dt,
+        uint32 iter,
+        const message &msg,
+        const anyList &varList) override
+    {
+        return true;
+    }
+
+	const integration& Integration()const
+	{
+		return integration_;
+	}
+
+	virtual
+	bool correct(real dt, const realx3PointField_D& y, const realx3PointField_D& dy)
+	{
+		return true;
+	}
+
+    virtual
+    bool correctPStruct(real dt, const realx3PointField_D& vel)
+    {
+        return true;
+    }
+
+    static
+    uniquePtr<boundaryIntegration> create(
+        const boundaryBase& boundary,
+        const pointStructure& pStruct, 
+        const word& method,
+		integration& intgrtn);
+
+};
+
+}
+
+#endif
\ No newline at end of file
diff --git a/src/Integration/boundaries/boundaryIntegrationList.cpp b/src/Integration/boundaries/boundaryIntegrationList.cpp
new file mode 100644
index 00000000..c7e2ad3b
--- /dev/null
+++ b/src/Integration/boundaries/boundaryIntegrationList.cpp
@@ -0,0 +1,41 @@
+#include "boundaryIntegrationList.hpp"
+#include "integration.hpp"
+
+pFlow::boundaryIntegrationList::boundaryIntegrationList(
+    const pointStructure &pStruct, 
+    const word &method, 
+    integration &intgrtn
+)
+:
+    ListPtr<boundaryIntegration>(6),
+	boundaries_(pStruct.boundaries())
+{
+    
+    for(uint32 i=0; i<6; i++)
+	{
+		this->set(
+			i,
+			boundaryIntegration::create(
+				boundaries_[i],
+				pStruct, 
+				method,
+                intgrtn
+            )
+        );
+	}	
+
+}
+
+bool pFlow::boundaryIntegrationList::correct(real dt, realx3PointField_D &y, realx3PointField_D &dy)
+{
+	for(auto& bndry:*this)
+	{
+		if(!bndry->correct(dt, y, dy))
+		{
+			fatalErrorInFunction;
+			return false;
+		}
+		
+    }
+    return true;
+}
diff --git a/src/Integration/boundaries/boundaryIntegrationList.hpp b/src/Integration/boundaries/boundaryIntegrationList.hpp
new file mode 100644
index 00000000..a4e262a0
--- /dev/null
+++ b/src/Integration/boundaries/boundaryIntegrationList.hpp
@@ -0,0 +1,45 @@
+
+#ifndef __boundaryIntegrationList_hpp__
+#define __boundaryIntegrationList_hpp__
+
+
+#include "boundaryList.hpp"
+#include "ListPtr.hpp"
+#include "boundaryIntegration.hpp"
+
+
+namespace pFlow
+{
+
+class integration;
+
+class boundaryIntegrationList
+:
+    public ListPtr<boundaryIntegration>
+{
+private:
+
+    const boundaryList&         boundaries_;
+
+public:
+
+    boundaryIntegrationList(
+        const pointStructure& pStruct, 
+        const word& method,
+		integration& intgrtn
+    );
+
+    ~boundaryIntegrationList()=default;
+
+    bool correct(
+		real dt, 
+		realx3PointField_D& y, 
+		realx3PointField_D& dy);
+};
+
+
+
+}
+
+
+#endif //__boundaryIntegrationList_hpp__
\ No newline at end of file
diff --git a/src/Interaction/CMakeLists.txt b/src/Interaction/CMakeLists.txt
index c0265808..3b985647 100644
--- a/src/Interaction/CMakeLists.txt
+++ b/src/Interaction/CMakeLists.txt
@@ -7,8 +7,7 @@ contactSearch/methods/cellBased/NBS/NBS.cpp
 contactSearch/methods/cellBased/NBS/cellsWallLevel0.cpp
 
 contactSearch/boundaries/boundaryContactSearch/boundaryContactSearch.cpp
-contactSearch/boundaries/twoPartContactSearch/twoPartContactSearchKernels.cpp
-contactSearch/boundaries/twoPartContactSearch/twoPartContactSearch.cpp
+
 contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearchKernels.cpp
 contactSearch/boundaries/periodicBoundaryContactSearch/ppwBndryContactSearch.cpp
 contactSearch/boundaries/periodicBoundaryContactSearch/wallBoundaryContactSearch.cpp
@@ -28,6 +27,8 @@ if(pFlow_Build_MPI)
     list(APPEND SourceFiles 
     contactSearch/boundaries/processorBoundaryContactSearch/processorBoundaryContactSearch.cpp
     sphereInteraction/boundaries/processorBoundarySphereInteraction/processorBoundarySphereInteractions.cpp
+    contactSearch/boundaries/twoPartContactSearch/twoPartContactSearchKernels.cpp
+    contactSearch/boundaries/twoPartContactSearch/twoPartContactSearch.cpp
     )
 endif()
 
diff --git a/src/Particles/SphereParticles/boundarySphereParticles.cpp b/src/Particles/SphereParticles/boundarySphereParticles.cpp
new file mode 100644
index 00000000..8eb5eaa0
--- /dev/null
+++ b/src/Particles/SphereParticles/boundarySphereParticles.cpp
@@ -0,0 +1,64 @@
+#include "boundarySphereParticles.hpp"
+#include "boundaryBase.hpp"
+#include "sphereParticles.hpp"
+
+
+pFlow::boundarySphereParticles::boundarySphereParticles(
+    const boundaryBase &boundary, 
+    sphereParticles &prtcls
+)
+:
+    generalBoundary(boundary, prtcls.pStruct(), "", ""),
+    particles_(prtcls)
+{
+
+}
+
+pFlow::sphereParticles &pFlow::boundarySphereParticles::Particles()
+{
+    return particles_;
+}
+
+const pFlow::sphereParticles &pFlow::boundarySphereParticles::Particles() const
+{
+    return particles_;
+}
+
+pFlow::uniquePtr<pFlow::boundarySphereParticles> pFlow::boundarySphereParticles::create(
+    const boundaryBase &boundary, 
+    sphereParticles &prtcls
+)
+{
+	
+	word bType = angleBracketsNames2( 
+		"boundarySphereParticles",
+		pFlowProcessors().localRunTypeName(), 
+		boundary.type());
+
+	word altBType{"boundarySphereParticles<none>"};
+
+	if( boundaryBasevCtorSelector_.search(bType) )
+	{
+		pOutput.space(4)<<"Creating boundary "<< Green_Text(bType)<<
+		" for "<<boundary.name()<<endl;
+		return boundaryBasevCtorSelector_[bType](boundary, prtcls);
+	}
+	else if(boundaryBasevCtorSelector_.search(altBType))
+	{
+		pOutput.space(4)<<"Creating boundary "<< Green_Text(altBType)<<
+		" for "<<boundary.name()<<endl;
+		return boundaryBasevCtorSelector_[altBType](boundary, prtcls);
+	}
+	else
+	{
+		printKeys( 
+			fatalError << "Ctor Selector "<< bType<<
+			" and "<< altBType << " do not exist. \n"
+			<<"Avaiable ones are: \n",
+			boundaryBasevCtorSelector_
+		);
+		fatalExit;
+	}
+	
+	return nullptr;
+}
diff --git a/src/Particles/SphereParticles/boundarySphereParticles.hpp b/src/Particles/SphereParticles/boundarySphereParticles.hpp
new file mode 100644
index 00000000..f4662307
--- /dev/null
+++ b/src/Particles/SphereParticles/boundarySphereParticles.hpp
@@ -0,0 +1,80 @@
+
+
+#ifndef __boundarySphereParticles_hpp__
+#define __boundarySphereParticles_hpp__
+
+#include "generalBoundary.hpp"
+#include "virtualConstructor.hpp"
+#include "timeInfo.hpp"
+
+namespace pFlow
+{
+
+class sphereParticles;
+
+class boundarySphereParticles
+    : public generalBoundary
+{
+private:
+
+    sphereParticles&        particles_;
+
+public:
+
+    /// type info
+    TypeInfo("boundarySphereParticles<none>");
+
+    boundarySphereParticles(
+        const boundaryBase &boundary,
+        sphereParticles&  prtcls
+    );
+
+    create_vCtor(
+        boundarySphereParticles,
+        boundaryBase,
+        (
+            const boundaryBase &boundary,
+            sphereParticles&  prtcls
+        ),
+        (boundary, prtcls)
+    );
+
+    add_vCtor(
+        boundarySphereParticles,
+        boundarySphereParticles,
+        boundaryBase
+    );
+
+    sphereParticles& Particles();
+
+    const sphereParticles& Particles()const;
+
+    bool hearChanges(
+        real t,
+        real dt,
+        uint32 iter,
+        const message &msg,
+        const anyList &varList) override
+    {
+        return true;
+    }
+
+    virtual
+    bool acceleration(const timeInfo& ti, const realx3& g)
+    {
+        return true;
+    }
+
+    static
+    uniquePtr<boundarySphereParticles> create(
+        const boundaryBase &boundary,
+        sphereParticles&  prtcls);
+    
+};
+
+
+}
+
+
+
+#endif
diff --git a/src/Particles/SphereParticles/boundarySphereParticlesList.cpp b/src/Particles/SphereParticles/boundarySphereParticlesList.cpp
new file mode 100644
index 00000000..5cbebc32
--- /dev/null
+++ b/src/Particles/SphereParticles/boundarySphereParticlesList.cpp
@@ -0,0 +1,19 @@
+#include "boundarySphereParticlesList.hpp"
+
+pFlow::boundarySphereParticlesList::boundarySphereParticlesList(
+    const boundaryList &bndrs, 
+    sphereParticles &prtcls
+)
+:
+    ListPtr(bndrs.size()), 
+    boundaries_(bndrs)
+{
+    for(auto i=0; i<boundaries_.size(); i++)
+    {
+        this->set
+        (
+            i, 
+            boundarySphereParticles::create(boundaries_[i], prtcls)
+        );
+    }
+}
\ No newline at end of file
diff --git a/src/Particles/SphereParticles/boundarySphereParticlesList.hpp b/src/Particles/SphereParticles/boundarySphereParticlesList.hpp
new file mode 100644
index 00000000..cd6770df
--- /dev/null
+++ b/src/Particles/SphereParticles/boundarySphereParticlesList.hpp
@@ -0,0 +1,36 @@
+
+
+#ifndef __boundarySphereParticlesList_hpp__
+#define __boundarySphereParticlesList_hpp__
+
+#include "ListPtr.hpp"
+#include "boundaryList.hpp"
+#include "boundarySphereParticles.hpp"
+
+namespace pFlow
+{
+
+class boundarySphereParticlesList
+:
+    public ListPtr<boundarySphereParticles>
+{
+private:
+
+    const boundaryList&         boundaries_;
+
+public:
+
+    boundarySphereParticlesList(
+        const boundaryList& bndrs,
+        sphereParticles& prtcls
+    );
+
+    ~boundarySphereParticlesList()=default;
+
+};
+
+}
+
+
+
+#endif 
\ No newline at end of file
diff --git a/src/phasicFlow/globals/boundaryConfigs.hpp b/src/phasicFlow/globals/boundaryConfigs.hpp
new file mode 100644
index 00000000..11574957
--- /dev/null
+++ b/src/phasicFlow/globals/boundaryConfigs.hpp
@@ -0,0 +1,10 @@
+#ifndef __boundaryConfigs_hpp__
+#define __boundaryConfigs_hpp__
+
+
+#ifndef BoundaryModel1
+//#define BoundaryModel1
+#endif
+
+
+#endif //__boundaryConfigs_hpp__
\ No newline at end of file
diff --git a/src/phasicFlow/processors/MPITimer.cpp b/src/phasicFlow/processors/MPITimer.cpp
new file mode 100644
index 00000000..cfa55631
--- /dev/null
+++ b/src/phasicFlow/processors/MPITimer.cpp
@@ -0,0 +1,88 @@
+#include "MPITimer.hpp"
+
+#ifdef pFlow_Build_MPI
+    #include "pFlowProcessors.hpp"
+    #include "procCommunication.hpp"
+#endif
+
+pFlow::real pFlow::MPITimer::totalTimeMax() const
+{
+    return accTimersTotalMax();
+}
+
+std::vector<pFlow::real> pFlow::MPITimer::totalTimeAllToAll() const
+{
+#ifdef pFlow_Build_MPI
+    MPI::procCommunication comm(pFlowProcessors());
+    auto [totTime, succs] = comm.collectAllToAll(totalTime());
+    return totTime;
+#else
+    return std::vector<real>(1, totalTime());
+#endif
+}
+
+std::vector<pFlow::real> pFlow::MPITimer::totalTimeAllToMaster() const
+{
+#ifdef pFlow_Build_MPI
+	MPI::procCommunication comm(pFlowProcessors());
+	auto [totTime, succs] = comm.collectAllToMaster(totalTime());
+	return totTime;
+#else
+		return std::vector<real>(1, totalTime());
+#endif
+}
+
+pFlow::real pFlow::MPITimer::averageTimeMax() const
+{
+    return Timer::averageTimeMax();
+}
+
+std::vector<pFlow::real> pFlow::MPITimer::averageTimeAllToAll() const
+{
+#ifdef pFlow_Build_MPI
+    MPI::procCommunication comm(pFlowProcessors());
+    auto [totTime, succs] = comm.collectAllToAll(averageTime());
+    return totTime;
+#else
+    return std::vector<real>(1, averageTime());
+#endif
+}
+
+std::vector<pFlow::real> pFlow::MPITimer::averageTimeAllAtoMaster() const
+{
+#ifdef pFlow_Build_MPI
+	MPI::procCommunication comm(pFlowProcessors());
+	auto [totTime, succs] = comm.collectAllToMaster(averageTime());
+	return totTime;
+#else
+		return std::vector<real>(1, averageTime());
+#endif
+}
+
+bool pFlow::MPITimer::write(iOstream &os) const
+{
+	const auto ts = totalTimeAllToAll();
+	auto maxloc = std::distance(ts.begin(), std::max_element(ts.begin(), ts.end()));
+	os<<'(';
+	for(auto i=0; i<ts.size(); i++)
+	{
+		if(maxloc == i)
+			os<<Red_Text(ts[i]);
+		else
+			os<<ts[i];
+		
+		if(i != ts.size()-1)
+			os<<' ';
+		else
+			os<<')'<<endl;
+	}
+
+    return true;
+}
+
+static pFlow::MPITimer ComputationTimer__{"ComputationTimer"};
+
+pFlow::MPITimer &pFlow::ComputationTimer()
+{
+    return ComputationTimer__;
+}
diff --git a/src/phasicFlow/processors/MPITimer.hpp b/src/phasicFlow/processors/MPITimer.hpp
new file mode 100644
index 00000000..a3d1f306
--- /dev/null
+++ b/src/phasicFlow/processors/MPITimer.hpp
@@ -0,0 +1,55 @@
+
+
+#ifndef __MPITimer_hpp__
+#define __MPITimer_hpp__
+
+#include "Timer.hpp"
+
+
+namespace pFlow
+{
+
+class MPITimer
+:
+    public Timer
+{
+private:
+
+    // hiding methods
+    using Timer::accTimersTotal;
+    using Timer::averageTime;
+
+public:
+
+    TypeInfo("MPITimer");
+
+    explicit MPITimer(const word& name)
+	: 
+    Timer(name)
+	{}
+
+	
+    real totalTimeMax()const;
+
+    std::vector<real> totalTimeAllToAll()const;
+
+    std::vector<real> totalTimeAllToMaster()const;
+
+    real averageTimeMax()const;
+
+    std::vector<real> averageTimeAllToAll()const;
+
+    std::vector<real> averageTimeAllAtoMaster()const;
+
+    // call this from all processors in pFlowProcessors
+    bool write(iOstream& os)const;
+
+};
+
+MPITimer& ComputationTimer();
+
+}
+
+
+
+#endif
\ No newline at end of file
diff --git a/src/phasicFlow/structuredData/boundaries/boundariesMask.hpp b/src/phasicFlow/structuredData/boundaries/boundariesMask.hpp
new file mode 100644
index 00000000..13875f2b
--- /dev/null
+++ b/src/phasicFlow/structuredData/boundaries/boundariesMask.hpp
@@ -0,0 +1,50 @@
+
+#ifndef __boundariesMask_hpp__
+#define __boundariesMask_hpp__
+
+#include <array>
+
+namespace pFlow
+{
+
+template<size_t N>
+class boundariesMask
+:
+    public std::array<bool,N> 
+{
+public:
+    
+    boundariesMask()=default;
+
+    boundariesMask(bool val)
+    {
+        this->fill(val);
+    }
+
+    boundariesMask(std::initializer_list<bool> l)
+    :
+        std::array<bool,N>(l)
+    {}
+
+    inline
+    bool allElements(bool val)
+    {
+        return std::all_of(this->begin(), this->end(), [val](bool v) { return v==val;} );
+    }
+
+    inline
+    bool anyElement(bool val)
+    {
+        return std::any_of(this->begin(), this->end(), [val](bool v) { return v==val;} );
+    }
+    
+    inline
+    bool noElement(bool val)
+    {
+        return std::none_of(this->begin(), this->end(), [val](bool v) { return v==val;} );
+    }
+};
+
+}
+
+#endif //__boundariesMask_hpp__
\ No newline at end of file

From d3ccf354b7ba8477d2fdf9c2ed144247036752e4 Mon Sep 17 00:00:00 2001
From: HRN <hamid.r.norouzi@gmail.com>
Date: Fri, 18 Oct 2024 23:13:20 +0330
Subject: [PATCH 2/2] code recovery regular part

---
 .../AdamsBashforth2/AdamsBashforth2.cpp       |  59 +++++--
 .../AdamsBashforth2/AdamsBashforth2.hpp       |  21 ++-
 src/Integration/CMakeLists.txt                |   5 +-
 .../boundaries/boundaryIntegrationList.cpp    |  20 ++-
 .../boundaries/boundaryIntegrationList.hpp    |   6 +
 src/Integration/integration/integration.hpp   |   4 +-
 .../ContactSearch/ContactSearch.hpp           | 119 +++++--------
 .../boundaries/boundaryContactSearchList.cpp  |   5 +-
 .../boundaries/boundaryContactSearchList.hpp  |   8 +
 .../contactSearch/contactSearch.cpp           |  74 +++++++-
 .../contactSearch/contactSearch.hpp           | 120 +++++++++----
 .../methods/particleWallContactSearchs.cpp    |  70 ++++----
 .../methods/particleWallContactSearchs.hpp    |  31 ----
 .../boundarySphereInteraction.hpp             |   2 +-
 .../sphereInteraction/sphereInteraction.cpp   | 161 ++++++++++--------
 .../sphereInteraction/sphereInteraction.hpp   |  18 +-
 src/Particles/CMakeLists.txt                  |   5 +-
 .../sphereParticles/sphereParticles.cpp       |  15 +-
 .../sphereParticles/sphereParticles.hpp       |   4 +
 .../dynamicPointStructure.cpp                 |   4 +-
 src/phasicFlow/CMakeLists.txt                 |   2 +
 src/phasicFlow/Timer/Timer.cpp                |  16 +-
 src/phasicFlow/Timer/Timer.hpp                |  33 +++-
 src/phasicFlow/Timer/Timers.hpp               |   5 +-
 src/phasicFlow/containers/Field/Field.cpp     |  26 ++-
 src/phasicFlow/containers/Field/Field.hpp     |   2 +-
 .../boundaryField/boundaryField.cpp           |   8 +-
 .../boundaryField/boundaryField.hpp           |  10 ++
 .../boundaryField/boundaryFieldList.hpp       |   9 +
 .../generalBoundary/generalBoundary.hpp       |   2 +-
 .../internalField/internalField.hpp           |   2 +-
 src/phasicFlow/demComponent/demComponent.cpp  |   5 +
 src/phasicFlow/demComponent/demComponent.hpp  |   5 +
 src/phasicFlow/dictionary/dictionary.hpp      |  52 +++++-
 src/phasicFlow/eventManagement/subscriber.cpp |  32 +---
 src/phasicFlow/eventManagement/subscriber.hpp |   6 +
 src/phasicFlow/processors/processors.cpp      |   5 +
 .../boundaries/boundaryBase/boundaryBase.cpp  |  73 +++++---
 .../boundaries/boundaryBase/boundaryBase.hpp  |  66 ++++---
 .../boundaries/boundaryExit/boundaryExit.cpp  | 112 ++++++------
 .../boundaries/boundaryExit/boundaryExit.hpp  |  14 +-
 .../boundaries/boundaryList.cpp               | 111 +++++++-----
 .../boundaries/boundaryList.hpp               |  29 +++-
 .../boundaries/boundaryNone/boundaryNone.cpp  |  37 ++--
 .../boundaries/boundaryNone/boundaryNone.hpp  |  13 +-
 .../boundaryPeriodic/boundaryPeriodic.cpp     | 122 ++++++-------
 .../boundaryPeriodic/boundaryPeriodic.hpp     |  17 +-
 .../boundaryReflective/boundaryReflective.cpp |  19 +--
 .../boundaryReflective/boundaryReflective.hpp |  14 +-
 .../domain/regularSimulationDomain.cpp        |  50 +-----
 .../domain/regularSimulationDomain.hpp        |   2 -
 .../domain/simulationDomain.cpp               |  89 ++++++++--
 .../domain/simulationDomain.hpp               |  46 +++--
 .../pointStructure/pointStructure.cpp         |  18 +-
 54 files changed, 1108 insertions(+), 695 deletions(-)

diff --git a/src/Integration/AdamsBashforth2/AdamsBashforth2.cpp b/src/Integration/AdamsBashforth2/AdamsBashforth2.cpp
index c6bb54a6..7969b184 100644
--- a/src/Integration/AdamsBashforth2/AdamsBashforth2.cpp
+++ b/src/Integration/AdamsBashforth2/AdamsBashforth2.cpp
@@ -90,8 +90,6 @@ bool intScattered
 
 }
 
-
-
 pFlow::AdamsBashforth2::AdamsBashforth2
 (
 	const word& baseName,
@@ -113,15 +111,19 @@ pFlow::AdamsBashforth2::AdamsBashforth2
 		pStruct,
 		zero3,
 		zero3
-	)
+	),
+	boundaryList_(pStruct, method, *this)
 {}
 
-bool pFlow::AdamsBashforth2::predict
-(
-	real UNUSED(dt),
-	realx3PointField_D& UNUSED(y),
-	realx3PointField_D& UNUSED(dy)
-)
+void pFlow::AdamsBashforth2::updateBoundariesSlaveToMasterIfRequested()
+{
+	realx3PointField_D::updateBoundariesSlaveToMasterIfRequested();
+}
+
+bool pFlow::AdamsBashforth2::predict(
+    real UNUSED(dt),
+    realx3PointField_D &UNUSED(y),
+    realx3PointField_D &UNUSED(dy))
 {
 	return true;
 }
@@ -142,25 +144,46 @@ bool pFlow::AdamsBashforth2::correct
 	realx3PointField_D& y,
 	realx3PointField_D& dy
 )
-{
-	return correct(dt, y.field(), dy);
-}
-
-bool pFlow::AdamsBashforth2::correct(real dt, realx3Field_D &y, realx3PointField_D &dy)
 {
 	auto& dy1l = dy1();
-
+	bool success = false;
 	if(dy1l.isAllActive())
 	{
-		return intAllActive(dt, y, dy, dy1l);
+		success = intAllActive(dt, y.field(), dy, dy1l);
 	}
 	else
 	{
-		return intScattered(dt, y, dy, dy1l);
+		success = intScattered(dt, y.field(), dy, dy1l);
 	}
-    return false;
+
+	success = success && boundaryList_.correct(dt, y, dy);
+
+	return success;
+
 }
 
+bool pFlow::AdamsBashforth2::correctPStruct(
+	real dt, 
+	pointStructure &pStruct, 
+	realx3PointField_D &vel)
+{
+	auto& dy1l = dy1();
+	bool success = false;
+	if(dy1l.isAllActive())
+	{
+		success = intAllActive(dt, pStruct.pointPosition(), vel, dy1l);
+	}
+	else
+	{
+		success = intScattered(dt, pStruct.pointPosition(), vel, dy1l);
+	}
+
+	success = success && boundaryList_.correctPStruct(dt, pStruct, vel);
+
+	return success;
+}
+
+
 bool pFlow::AdamsBashforth2::setInitialVals(
 	const int32IndexContainer& newIndices,
 	const realx3Vector& y)
diff --git a/src/Integration/AdamsBashforth2/AdamsBashforth2.hpp b/src/Integration/AdamsBashforth2/AdamsBashforth2.hpp
index 13685bab..e8abc026 100644
--- a/src/Integration/AdamsBashforth2/AdamsBashforth2.hpp
+++ b/src/Integration/AdamsBashforth2/AdamsBashforth2.hpp
@@ -17,13 +17,13 @@ Licence:
   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 -----------------------------------------------------------------------------*/
-
 #ifndef __AdamsBashforth2_hpp__
 #define __AdamsBashforth2_hpp__
 
 
 #include "integration.hpp"
 #include "pointFields.hpp"
+#include "boundaryIntegrationList.hpp"
 
 namespace pFlow
 {
@@ -41,6 +41,15 @@ class AdamsBashforth2
 {
 private:
 
+	boundaryIntegrationList boundaryList_;
+
+	friend class processorAB2BoundaryIntegration;
+
+	const auto& dy1()const
+	{
+		return static_cast<const realx3PointField_D&>(*this);
+	}
+
 	auto& dy1()
 	{
 		return static_cast<realx3PointField_D&>(*this);
@@ -71,6 +80,9 @@ public:
 
 
 	// - Methods
+
+		void updateBoundariesSlaveToMasterIfRequested()override;
+
 		/// return integration method 
 		word method()const override
 		{
@@ -92,10 +104,11 @@ public:
 			realx3PointField_D& y, 
 			realx3PointField_D& dy) final;
 
-		bool correct(
+		bool correctPStruct(
 			real dt, 
-			realx3Field_D& y, 
-			realx3PointField_D& dy) final;
+			pointStructure& pStruct, 
+			realx3PointField_D& vel) final;
+			
 		
 		/*bool hearChanges
 		(
diff --git a/src/Integration/CMakeLists.txt b/src/Integration/CMakeLists.txt
index fca650cd..c6ed9818 100644
--- a/src/Integration/CMakeLists.txt
+++ b/src/Integration/CMakeLists.txt
@@ -1,7 +1,10 @@
 
 list(APPEND SourceFiles 
-integration/integration.cpp 
+integration/integration.cpp
+boundaries/boundaryIntegration.cpp
+boundaries/boundaryIntegrationList.cpp 
 AdamsBashforth2/AdamsBashforth2.cpp
+AdamsBashforth2/processorAB2BoundaryIntegration.cpp
 #AdamsBashforth5/AdamsBashforth5.cpp
 #AdamsBashforth4/AdamsBashforth4.cpp
 #AdamsBashforth3/AdamsBashforth3.cpp
diff --git a/src/Integration/boundaries/boundaryIntegrationList.cpp b/src/Integration/boundaries/boundaryIntegrationList.cpp
index c7e2ad3b..9dfa1538 100644
--- a/src/Integration/boundaries/boundaryIntegrationList.cpp
+++ b/src/Integration/boundaries/boundaryIntegrationList.cpp
@@ -32,10 +32,28 @@ bool pFlow::boundaryIntegrationList::correct(real dt, realx3PointField_D &y, rea
 	{
 		if(!bndry->correct(dt, y, dy))
 		{
-			fatalErrorInFunction;
+			fatalErrorInFunction<<"Error in correcting boundary "<<
+			bndry->boundaryName()<<endl;
 			return false;
 		}
 		
     }
     return true;
 }
+
+bool pFlow::boundaryIntegrationList::correctPStruct(
+	real dt, 
+	pointStructure &pStruct, 
+	const realx3PointField_D &vel)
+{
+	for(auto& bndry:*this)
+	{
+		if(!bndry->correctPStruct(dt, vel))
+		{
+			fatalErrorInFunction<<"Error in correcting boundary "<<
+			bndry->boundaryName()<<" in pointStructure."<<endl;
+			return false;
+		}
+	}
+    return true;
+}
diff --git a/src/Integration/boundaries/boundaryIntegrationList.hpp b/src/Integration/boundaries/boundaryIntegrationList.hpp
index a4e262a0..b8194a32 100644
--- a/src/Integration/boundaries/boundaryIntegrationList.hpp
+++ b/src/Integration/boundaries/boundaryIntegrationList.hpp
@@ -35,6 +35,12 @@ public:
 		real dt, 
 		realx3PointField_D& y, 
 		realx3PointField_D& dy);
+
+    bool correctPStruct(
+        real dt, 
+        pointStructure& pStruct, 
+        const realx3PointField_D& vel);
+
 };
 
 
diff --git a/src/Integration/integration/integration.hpp b/src/Integration/integration/integration.hpp
index 4769c3ec..2c95813e 100644
--- a/src/Integration/integration/integration.hpp
+++ b/src/Integration/integration/integration.hpp
@@ -131,6 +131,8 @@ public:
 			return owner_;
 		}
 
+		virtual 
+		void updateBoundariesSlaveToMasterIfRequested() = 0;
 		/// return integration method 
 		virtual 
 		word method()const = 0 ;
@@ -147,7 +149,7 @@ public:
 		bool correct(real dt, realx3PointField_D& y, realx3PointField_D& dy) = 0;
 
 		virtual 
-		bool correct(real dt, realx3Field_D& y, realx3PointField_D& dy) = 0;
+		bool correctPStruct(real dt, pointStructure& pStruct, realx3PointField_D& vel) = 0;
 
 		/// Set the initial values for new indices 
 		virtual 
diff --git a/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp b/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp
index f2dda414..e024295c 100644
--- a/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp
+++ b/src/Interaction/contactSearch/ContactSearch/ContactSearch.hpp
@@ -53,6 +53,47 @@ private:
 
 	boundaryContactSearchList 		csBoundaries_;
 
+	bool BroadSearch(
+		const timeInfo& ti,
+		csPairContainerType& ppPairs,
+		csPairContainerType& pwPairs,
+		bool force = false) override
+	{
+		
+		const auto& position = Particles().pointPosition().deviceViewAll();
+		const auto& flags = Particles().dynPointStruct().activePointsMaskDevice();
+		const auto& diam = Particles().boundingSphere().deviceViewAll();
+
+		return ppwContactSearch_().broadSearch(
+			ti.iter(),
+			ti.t(),
+			ti.dt(),
+			ppPairs, 
+			pwPairs,
+			position, 
+			flags, 
+			diam,
+			force
+		);
+	}
+
+	bool BoundaryBroadSearch(
+		uint32 bndryIndex,
+		const timeInfo& ti,
+		csPairContainerType& ppPairs,
+		csPairContainerType& pwPairs,
+		bool force = false)override
+	{		
+		return csBoundaries_[bndryIndex].broadSearch(
+			ti.iter(), 
+			ti.t(), 
+			ti.dt(), 
+			ppPairs, 
+			pwPairs, 
+			force
+		);
+	}
+
 public:
 
 	TypeInfoTemplate11("ContactSearch", SearchMethodType);
@@ -108,87 +149,14 @@ public:
 			);
 	}
 
-
 	add_vCtor(
 		contactSearch,
 		ContactSearch,
 		dictionary);
 
-	
-	bool broadSearch(
-		uint32 iter,
-		real t,
-		real dt,
-		csPairContainerType& ppPairs,
-		csPairContainerType& pwPairs,
-		bool force = false) override
+	bool enterBroadSearchBoundary(const timeInfo& ti, bool force=false)const override
 	{
-		
-
-		ppTimer().start();
-	
-		const auto& position = Particles().pointPosition().deviceViewAll();
-		const auto& flags = Particles().dynPointStruct().activePointsMaskDevice();
-		const auto& diam = Particles().boundingSphere().deviceViewAll();
-		
-		
-		if( !ppwContactSearch_().broadSearch(
-			iter,
-			t,
-			dt,
-			ppPairs, 
-			pwPairs,
-			position, 
-			flags, 
-			diam,
-			force) )
-		{
-			fatalErrorInFunction;
-			return false;
-		}
-		ppTimer().end();
-
-		return true;
-	}
-
-	bool boundaryBroadSearch(
-		uint32 i,
-		uint32 iter,
-		real t,
-		real dt,
-		csPairContainerType& ppPairs,
-		csPairContainerType& pwPairs,
-		bool force = false)override
-	{
-		if(i==0u)
-			Particles().boundingSphere().updateBoundaries(DataDirection::SlaveToMaster);
-		return csBoundaries_[i].broadSearch(
-			iter, 
-			t, 
-			dt, 
-			ppPairs, 
-			pwPairs, 
-			force);
-	}
-
-	bool enterBroadSearch(uint32 iter, real t, real dt)const override
-	{
-		if(ppwContactSearch_)
-		{
-			return ppwContactSearch_().performSearch(iter); 
-		}
-		return false;
-	}
-
-	bool performedBroadSearch()const override
-	{
-		return ppwContactSearch_().performedSearch();
-	}
-
-	
-	uint32 updateInterval()const override
-	{
-		return ppwContactSearch_().updateInterval();
+		return enterBroadSearch(ti, force) || csBoundaries_.boundariesUpdated();
 	}
 
 	real sizeRatio()const override
@@ -196,7 +164,6 @@ public:
 		return ppwContactSearch_().sizeRatio();
 	}
 
-	 
 	real cellExtent()const override
 	{
 		return ppwContactSearch_().cellExtent();
diff --git a/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.cpp b/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.cpp
index 4f114430..ae86d7ab 100644
--- a/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.cpp
+++ b/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.cpp
@@ -26,4 +26,7 @@ pFlow::boundaryContactSearchList::boundaryContactSearchList(
     setList(dict, cSearch);
 }
 
-
+bool pFlow::boundaryContactSearchList::boundariesUpdated() const
+{
+    return boundaries_.boundariesUpdated();
+}
diff --git a/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.hpp b/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.hpp
index 40e9f32e..9f1951b8 100644
--- a/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.hpp
+++ b/src/Interaction/contactSearch/boundaries/boundaryContactSearchList.hpp
@@ -28,6 +28,14 @@ public:
         const contactSearch& cSearch);
     
     ~boundaryContactSearchList()=default;
+
+    inline
+    const boundaryList& boundaries()const
+    {
+        return boundaries_;
+    } 
+
+    bool boundariesUpdated()const;
     
 };
 
diff --git a/src/Interaction/contactSearch/contactSearch/contactSearch.cpp b/src/Interaction/contactSearch/contactSearch/contactSearch.cpp
index 8e8ca3dc..7394e295 100644
--- a/src/Interaction/contactSearch/contactSearch/contactSearch.cpp
+++ b/src/Interaction/contactSearch/contactSearch/contactSearch.cpp
@@ -33,8 +33,8 @@ pFlow::contactSearch::contactSearch(
 	extendedDomainBox_(extDomain),
 	particles_(prtcl),
 	geometry_(geom),
-	ppTimer_("particle-particle contact search", &timers),
-	pwTimer_("particle-wall contact search", &timers),
+	bTimer_("Boundary particles contact search", &timers),
+	ppTimer_("Internal particles contact search", &timers),
 	dict_(dict)
 {
 
@@ -45,6 +45,76 @@ const pFlow::pointStructure &pFlow::contactSearch::pStruct() const
    return particles_.pStruct();
 }
 
+bool pFlow::contactSearch::broadSearch
+(
+	const timeInfo &ti, 
+	csPairContainerType &ppPairs, 
+	csPairContainerType &pwPairs, 
+	bool force
+)
+{
+
+	if(enterBroadSearch(ti, force))
+	{
+		ppTimer_.start();
+		if( !BroadSearch(
+			ti,
+			ppPairs,
+			pwPairs,
+			force ) )
+		{
+			fatalErrorInFunction;
+			performedSearch_ = false;
+			return false;
+		}
+		ppTimer_.end();
+		performedSearch_ = true;
+	}
+	else
+	{
+		performedSearch_ = false;
+	}
+
+	return true;
+}
+
+bool pFlow::contactSearch::boundaryBroadSearch
+(
+	uint32 bndryIndex, 
+	const timeInfo &ti, 
+	csPairContainerType &ppPairs, 
+	csPairContainerType &pwPairs, 
+	bool force
+)
+{
+	if(enterBroadSearchBoundary(ti, force))
+	{
+		bTimer_.start();
+		for(uint32 i=0u; i<6u; i++)
+		{
+			if(!BoundaryBroadSearch(
+				i,
+				ti,
+				ppPairs,
+				pwPairs,
+				force))
+			{
+				performedSearchBoundary_ = false;
+				return false;
+			}
+		}
+		bTimer_.end();
+		performedSearchBoundary_ = true;
+	}
+	else
+	{
+
+		performedSearchBoundary_ = false;
+	}
+
+    return true;
+}
+
 pFlow::uniquePtr<pFlow::contactSearch> pFlow::contactSearch::create(
     const dictionary &dict,
     const box &extDomain,
diff --git a/src/Interaction/contactSearch/contactSearch/contactSearch.hpp b/src/Interaction/contactSearch/contactSearch/contactSearch.hpp
index 865ec291..f9f4370f 100644
--- a/src/Interaction/contactSearch/contactSearch/contactSearch.hpp
+++ b/src/Interaction/contactSearch/contactSearch/contactSearch.hpp
@@ -26,6 +26,7 @@ Licence:
 #include "contactSearchGlobals.hpp"
 #include "dictionary.hpp"
 #include "virtualConstructor.hpp"
+#include "timeInfo.hpp"
 #include "Timer.hpp"
 
 namespace pFlow
@@ -44,16 +45,47 @@ private:
 
 	const box& 	extendedDomainBox_;
 
+	/// @brief update interval in terms of iteration numebr 
+	uint32 		updateInterval_= 1;
+
+	/// @brief  last iteration number which contact search has been performed
+	uint32 		lastUpdated_ 	= 0;
+
+	/// @brief performed search? 
+	bool 		performedSearch_ = false;
+
+	/// @brief performed search in boundaries
+	bool 		performedSearchBoundary_ = false;
+
+	/// const ref to particles
 	const particles& 		particles_;
 
+	/// const ref to geometry 
 	const geometry&			geometry_;
 
+	Timer 		bTimer_;
+
 	Timer 		ppTimer_;
 
-	Timer 		pwTimer_;
-
 	dictionary 	dict_;
 
+	virtual
+	bool BroadSearch(
+		const timeInfo& ti,
+		csPairContainerType& ppPairs,
+		csPairContainerType& pwPairs,
+		bool force
+	)=0;
+
+	virtual
+	bool  BoundaryBroadSearch(
+		uint32 bndryIndex,
+		const timeInfo& ti,
+		csPairContainerType& ppPairs,
+		csPairContainerType& pwPairs,
+		bool force = false
+	)=0;
+
 public:
 
 	TypeInfo("contactSearch");
@@ -82,66 +114,92 @@ public:
 	 	(dict, domain, prtcl, geom, timers)
 	);
 
-	
-	const auto& dict()const
+	inline
+	bool performedSearch()const
+	{
+		return performedSearch_;
+	}
+
+	inline 
+	bool performedSearchBoundary()const 
+	{
+		return performedSearchBoundary_;
+	}
+
+	inline
+	bool performSearch(uint32 iter, bool force = false)const
+	{
+		if((iter-lastUpdated_) % updateInterval_ == 0 || iter == 0 || force )
+		{
+			return true;
+		}
+		return false;		
+	}
+
+	bool enterBroadSearch(const timeInfo& ti, bool force = false)const
+	{
+		return performSearch(ti.iter(), force);
+	}
+
+	virtual 
+	bool enterBroadSearchBoundary(const timeInfo& ti, bool force=false)const = 0;
+
+	inline
+	uint32 updateInterval()const
+	{
+		return updateInterval_;
+	}
+
+	inline
+	const dictionary& dict()const
 	{
 		return dict_;
 	}
 
-	const auto& extendedDomainBox()const
+	inline
+	const box& extendedDomainBox()const
 	{
 		return extendedDomainBox_;
 	}
 
-	const auto& Particles()const
+	inline
+	const particles& Particles()const
 	{
 		return particles_;
 	}
 
 	const pointStructure& pStruct()const;
 
-	const auto& Geometry()const
+	inline
+	const geometry& Geometry()const
 	{
 		return geometry_;
 	}
 
-	auto& ppTimer()
+	inline
+	Timer& ppTimer()
 	{
 		return ppTimer_;
 	}
 
-	auto& pwTimer()
+	inline
+	Timer& bTimer()
 	{
-		return pwTimer_;
+		return bTimer_;
 	}
-
-	virtual 
+ 
 	bool broadSearch(
-		uint32 iter,
-		real t,
-		real dt,
+		const timeInfo& ti,
 		csPairContainerType& ppPairs,
 		csPairContainerType& pwPairs,
-		bool force = false) = 0;
+		bool force = false);
 	
-	virtual 
 	bool boundaryBroadSearch(
-		uint32 i,
-		uint32 iter,
-		real t,
-		real dt,
+		uint32 bndryIndex,
+		const timeInfo& ti,
 		csPairContainerType& ppPairs,
 		csPairContainerType& pwPairs,
-		bool force = false)=0;
-
-	virtual 
-	bool enterBroadSearch(uint32 iter, real t, real dt)const = 0;
-
-	virtual 
-	bool performedBroadSearch()const = 0;
-
-	virtual
-	uint32 updateInterval()const = 0;
+		bool force = false);
 
 	virtual 
 	real sizeRatio()const = 0;
diff --git a/src/Interaction/contactSearch/methods/particleWallContactSearchs.cpp b/src/Interaction/contactSearch/methods/particleWallContactSearchs.cpp
index ee414f3b..95a37309 100644
--- a/src/Interaction/contactSearch/methods/particleWallContactSearchs.cpp
+++ b/src/Interaction/contactSearch/methods/particleWallContactSearchs.cpp
@@ -31,48 +31,36 @@ pFlow::particleWallContactSearchs<method>::particleWallContactSearchs
     const ViewType1D<real, memory_space> &diam
 )
 :
-    domainBox_(domain),
-    updateInterval_
-    (
-        max(dict.getValOrSet<uint32>("updateInterval", 1),1u)
-    )
-{
-    
-}
+    domainBox_(domain)
+{}
 
 template <typename method>
 bool pFlow::particleWallContactSearchs<method>::broadSearch
-	(
-		uint32 iter,
-		real t,
-		real dt,
-		csPairContainerType& ppPairs,
-		csPairContainerType& pwPairs,
-		const deviceViewType1D<realx3>& pointPos,
-		const pFlagTypeDevice& flags,
-		const deviceViewType1D<real>& diameter,
-		bool  force
-	)
+(
+	uint32 iter,
+	real t,
+	real dt,
+	csPairContainerType& ppPairs,
+	csPairContainerType& pwPairs,
+	const deviceViewType1D<realx3>& pointPos,
+	const pFlagTypeDevice& flags,
+	const deviceViewType1D<real>& diameter,
+	bool  force
+)
+{
+	
+	if(!getMethod().impl_broadSearch(
+		ppPairs,
+		pwPairs,
+		pointPos,
+		flags,
+		diameter))
 	{
-		
-		performedSearch_ = false;
-		if( !performSearch(iter, force) ) return true;
-
-		if(!getMethod().impl_broadSearch(
-			ppPairs,
-			pwPairs,
-			pointPos,
-			flags,
-			diameter))
-		{
-			fatalErrorInFunction<<
-			"Error in performing particle-particle broadSearch in method"<<
-			getMethod().typeName()<<endl;
-			return false;
-		}
-
-		lastUpdated_ = iter;
-		
-		performedSearch_ = true;		
-		return true;
-	}
\ No newline at end of file
+		fatalErrorInFunction<<
+		"Error in performing particle-particle broadSearch in method"<<
+		getMethod().typeName()<<endl;
+		return false;
+	}
+	
+	return true;
+}
\ No newline at end of file
diff --git a/src/Interaction/contactSearch/methods/particleWallContactSearchs.hpp b/src/Interaction/contactSearch/methods/particleWallContactSearchs.hpp
index 1bf5dab3..71d2245c 100644
--- a/src/Interaction/contactSearch/methods/particleWallContactSearchs.hpp
+++ b/src/Interaction/contactSearch/methods/particleWallContactSearchs.hpp
@@ -48,18 +48,6 @@ private:
 	/// @brief  box enclosing the simulation domain (local to processor)
 	box 		domainBox_;
 
-	/*/// @brief box enclosing the area for contact search (region with points)
-	box 		searchBox_;*/
-
-	/// @brief update interval in terms of iteration numebr 
-	uint32 		updateInterval_= 1;
-
-	/// @brief  last iteration number which contact search has been performed
-	uint32 		lastUpdated_ 	= 0;
-
-	/// @brief performed search? 
-	bool 		performedSearch_ = false;
-
 protected:
 
 	inline
@@ -98,25 +86,6 @@ public:
     	const deviceViewType1D<real>& diameter,
 		bool  force = false
 	);
-		
-	bool performedSearch()const
-	{
-		return performedSearch_;
-	}
-
-	bool performSearch(uint32 iter, bool force = false)const
-	{
-		if((iter-lastUpdated_) % updateInterval_ == 0 || iter == 0 || force )
-		{
-			return true;
-		}
-		return false;		
-	}
-
-	uint32 updateInterval()const
-	{
-		return updateInterval_;
-	}
 
 	real sizeRatio()const
 	{
diff --git a/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.hpp b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.hpp
index 708fb61e..b36188c5 100644
--- a/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.hpp
+++ b/src/Interaction/sphereInteraction/boundaries/boundarySphereInteraction/boundarySphereInteraction.hpp
@@ -165,7 +165,7 @@ public:
     {
 		
 		pOutput<<"Function (hearChanges in boundarySphereInteractions)is not implmented Message "<<
-		 msg <<endl<<" name "<< this->name() <<" type "<< this->type()<<endl;;
+		 msg <<endl<<" name "<< this->boundaryName() <<" type "<< this->type()<<endl;;
 		//notImplementedFunction;
 		return true;
 	}
diff --git a/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.cpp b/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.cpp
index 2aa10ef8..9001a5b8 100644
--- a/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.cpp
+++ b/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.cpp
@@ -134,18 +134,22 @@ pFlow::sphereInteraction<cFM,gMM, cLT>::sphereInteraction
 	geometryMotion_(dynamic_cast<const GeometryMotionModel&>(geom)),
 	sphParticles_(dynamic_cast<const sphereParticles&>(prtcl)),
 	boundaryInteraction_(sphParticles_,geometryMotion_),
-	ppInteractionTimer_("sphere-sphere interaction", &this->timers()),
-	pwInteractionTimer_("sphere-wall interaction", &this->timers()),
-	contactListMangementTimer_("contact-list management", &this->timers()),
-	boundaryContactSearchTimer_("contact search for boundary", &this->timers()),
-	boundaryInteractionTimer_("interaction for boundary", &this->timers()),
-	contactListBoundaryTimer_("contact-list management for boundary", &this->timers())
+	ppInteractionTimer_("sphere-sphere interaction (internal)", &this->timers()),
+	pwInteractionTimer_("sphere-wall interaction (internal)", &this->timers()),
+	boundaryInteractionTimer_("sphere-sphere interaction (boundary)",&this->timers()),
+	contactListMangementTimer_("list management (interal)", &this->timers()),
+	contactListMangementBoundaryTimer_("list management (boundary)", &this->timers())
 {
 	
 	if(!createSphereInteraction())
 	{
 		fatalExit;
 	}
+
+	for(uint32 i=0; i<6; i++)
+	{
+		activeBoundaries_[i] = boundaryInteraction_[i].ppPairsAllocated();
+	}
 }
 
 template<typename cFM,typename gMM,template <class, class, class> class cLT>
@@ -158,45 +162,55 @@ template<typename cFM,typename gMM,template <class, class, class> class cLT>
 bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
 {
 	
-	auto iter = this->currentIter();
-	auto t = this->currentTime();
-	auto dt = this->dt();
+	timeInfo ti = this->TimeInfo();
+	auto iter = ti.iter();
+	auto t = ti.t();
+	auto dt = ti.dt();
 
-	
-	bool broadSearch = contactSearch_().enterBroadSearch(iter, t, dt);
+	auto& contactSearchRef = contactSearch_();
 
+	bool broadSearch = contactSearchRef.enterBroadSearch(ti);
+	bool broadSearchBoundary = contactSearchRef.enterBroadSearchBoundary(ti);
+
+	/// update boundaries of the fields that are being used by inreaction 
 	sphParticles_.diameter().updateBoundaries(DataDirection::SlaveToMaster);
 	sphParticles_.velocity().updateBoundaries(DataDirection::SlaveToMaster);
 	sphParticles_.rVelocity().updateBoundaries(DataDirection::SlaveToMaster);
-	sphParticles_.mass().updateBoundaries(DataDirection::SlaveToMaster);
-	sphParticles_.I().updateBoundaries(DataDirection::SlaveToMaster);
 	sphParticles_.propertyId().updateBoundaries(DataDirection::SlaveToMaster);
 	
-	
+	/// lists 
 	if(broadSearch)
 	{
 		contactListMangementTimer_.start();
-		ppContactList_().beforeBroadSearch();
-		pwContactList_().beforeBroadSearch();
+		ComputationTimer().start();
+			ppContactList_().beforeBroadSearch();
+			pwContactList_().beforeBroadSearch();
+		ComputationTimer().end();
 		contactListMangementTimer_.pause();
 	} 
 
-	contactListBoundaryTimer_.start();
-	for(uint32 i=0; i<6u; i++)
+	if(broadSearchBoundary)
 	{
-		auto& BI = boundaryInteraction_[i];
-		if(BI.ppPairsAllocated()) BI.ppPairs().beforeBroadSearch();
-		if(BI.pwPairsAllocated()) BI.pwPairs().beforeBroadSearch();
+		contactListMangementBoundaryTimer_.start();
+		ComputationTimer().start();
+		for(uint32 i=0; i<6u; i++)
+		{
+			if(activeBoundaries_[i])
+			{
+				auto& BI = boundaryInteraction_[i];
+				BI.ppPairs().beforeBroadSearch();
+				BI.pwPairs().beforeBroadSearch();
+			} 
+		}
+		ComputationTimer().end();
+		contactListMangementBoundaryTimer_.pause();	
 	}
-	contactListBoundaryTimer_.pause();
 	
 	if( sphParticles_.numActive()<=0)return true;
 	
-	
-	if( !contactSearch_().broadSearch(
-			iter,
-			t,
-			dt,		
+	ComputationTimer().start();
+	if( !contactSearchRef.broadSearch(
+			ti,		
 			ppContactList_(),
 			pwContactList_()) )
 	{
@@ -205,62 +219,64 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
 		fatalExit;
 	}
 	
-	boundaryContactSearchTimer_.start();
 	for(uint32 i=0; i<6u; i++)
 	{
-		auto& BI =boundaryInteraction_[i];
-		if(BI.ppPairsAllocated())
+		if(activeBoundaries_[i])
 		{
-			if( !contactSearch_().boundaryBroadSearch(
+			auto& BI = boundaryInteraction_[i];
+			if(!contactSearchRef.boundaryBroadSearch(
 				i,
-				iter,
-				t,
-				dt,
+				ti,
 				BI.ppPairs(),
-				BI.pwPairs()))
+				BI.pwPairs())
+			)
 			{
 				fatalErrorInFunction<<
 				"failed to perform broadSearch for boundary index "<<i<<endl;
 				return false;
 			}
-		} 
+		}
 	}
-	boundaryContactSearchTimer_.end();
+	ComputationTimer().end();
 	
-	if(broadSearch && contactSearch_().performedBroadSearch())
+	if(broadSearch && contactSearchRef.performedSearch())
 	{
 		contactListMangementTimer_.resume();
-		ppContactList_().afterBroadSearch();
-		pwContactList_().afterBroadSearch();
+		ComputationTimer().start();
+			ppContactList_().afterBroadSearch();
+			pwContactList_().afterBroadSearch();
+		ComputationTimer().end();
 		contactListMangementTimer_.end();
 	}
 
-	contactListBoundaryTimer_.resume();
-	for(uint32 i=0; i<6u; i++)
+	if(broadSearchBoundary && contactSearchRef.performedSearchBoundary())
 	{
-		auto& BI = boundaryInteraction_[i];
-		if(BI.ppPairsAllocated()) BI.ppPairs().afterBroadSearch();
-		if(BI.pwPairsAllocated()) BI.pwPairs().afterBroadSearch();
+		contactListMangementBoundaryTimer_.resume();
+		ComputationTimer().start();
+		for(uint32 i=0; i<6u; i++)
+		{
+			if(activeBoundaries_[i])
+			{
+				auto& BI = boundaryInteraction_[i];
+				BI.ppPairs().afterBroadSearch();
+				BI.pwPairs().afterBroadSearch();
+			}
+		}
+		ComputationTimer().end();
+		contactListMangementBoundaryTimer_.end();
 	}
-	contactListBoundaryTimer_.end();
 	
-	
-	{
-	boundaryInteractionTimer_.start();
-	std::array<bool,6> requireStep{
-		boundaryInteraction_[0].isBoundaryMaster(),
-		boundaryInteraction_[1].isBoundaryMaster(),
-		boundaryInteraction_[2].isBoundaryMaster(),
-		boundaryInteraction_[3].isBoundaryMaster(),
-		boundaryInteraction_[4].isBoundaryMaster(),
-		boundaryInteraction_[5].isBoundaryMaster()};
-	int step = 1;
+	/// peform contact search on boundareis with active contact search (master boundaries)
+	auto requireStep = boundariesMask<6>(true);
 	const auto& cfModel = this->forceModel_();
-	while( std::any_of(requireStep.begin(), requireStep.end(), [](bool v) { return v==true; }))
+	uint32 step=1;
+	boundaryInteractionTimer_.start();
+	ComputationTimer().start();
+	while(requireStep.anyElement(true) && step <= 10)
 	{
 		for(uint32 i=0; i<6u; i++)
 		{
-			if(step==1u || requireStep[i] )
+			if(requireStep[i] )
 			{
 				requireStep[i] = boundaryInteraction_[i].sphereSphereInteraction(
 					dt, 
@@ -271,30 +287,31 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
 		}
 		step++;
 	}
+	ComputationTimer().end();
 	boundaryInteractionTimer_.pause();
-	}
+	
+
 	ppInteractionTimer_.start();
+	ComputationTimer().start();
 		sphereSphereInteraction();
+	ComputationTimer().end();
 	ppInteractionTimer_.end();
 
 	
 	pwInteractionTimer_.start();
+	ComputationTimer().start();
 		sphereWallInteraction();
+	ComputationTimer().start();
 	pwInteractionTimer_.end();
 
 	{
 	boundaryInteractionTimer_.resume();
-	std::array<bool,6> requireStep{
-		!boundaryInteraction_[0].isBoundaryMaster(),
-		!boundaryInteraction_[1].isBoundaryMaster(),
-		!boundaryInteraction_[2].isBoundaryMaster(),
-		!boundaryInteraction_[3].isBoundaryMaster(),
-		!boundaryInteraction_[4].isBoundaryMaster(),
-		!boundaryInteraction_[5].isBoundaryMaster()};
+	ComputationTimer().start();
+	auto requireStep = boundariesMask<6>(true);
 
-	int step = 2;
+	uint32 step = 11;
 	const auto& cfModel = this->forceModel_();
-	while(std::any_of(requireStep.begin(), requireStep.end(), [](bool v) { return v==true; }))
+	while( requireStep.anyElement(true) && step < 20 )
 	{
 		for(uint32 i=0; i<6u; i++)
 		{
@@ -302,13 +319,14 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
 			{
 				requireStep[i] = boundaryInteraction_[i].sphereSphereInteraction(
 					dt, 
-					this->forceModel_(),
+					cfModel,
 					step
 				);
 			}		
 		}
 		step++;
 	}
+	ComputationTimer().end();
 	boundaryInteractionTimer_.end();
 	}
 	
@@ -336,5 +354,4 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::hearChanges
 		notImplementedFunction;
 	}
 	return true;
-}
-
+}
\ No newline at end of file
diff --git a/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.hpp b/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.hpp
index 74cb2442..472ba519 100644
--- a/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.hpp
+++ b/src/Interaction/sphereInteraction/sphereInteraction/sphereInteraction.hpp
@@ -25,6 +25,8 @@ Licence:
 #include "sphereParticles.hpp"
 #include "boundarySphereInteractionList.hpp"
 #include "sphereInteractionKernels.hpp"
+#include "boundariesMask.hpp"
+#include "MPITimer.hpp"
 //#include "unsortedContactList.hpp"
 
 
@@ -74,6 +76,9 @@ private:
 	/// particle-particle and particle-wall interactions at boundaries 
 	BoundaryListType 					boundaryInteraction_;	
 
+	/// a mask for active boundaries (boundaries with intreaction)
+	boundariesMask<6> 					activeBoundaries_;
+
 	/// contact search object for pp and pw interactions 
 	uniquePtr<contactSearch> 			contactSearch_ = nullptr;
 
@@ -93,14 +98,13 @@ private:
 	/// timer for particle-wall interaction computations
 	Timer       pwInteractionTimer_;
 
-	/// timer for managing contact lists (only inernal points)
-	Timer 		contactListMangementTimer_;
-
-	Timer 		boundaryContactSearchTimer_;
 	/// timer for boundary interaction time 
 	Timer 		boundaryInteractionTimer_;
 
-	Timer 		contactListBoundaryTimer_;
+	/// timer for managing contact lists (only inernal points)
+	Timer 		contactListMangementTimer_;	
+
+	Timer 		contactListMangementBoundaryTimer_;
 
 	
 
@@ -110,10 +114,6 @@ private:
 
 	bool sphereWallInteraction();
 
-	//bool managePPContactLists();
-
-	//bool managePWContactLists();
-
 	/// range policy for p-p interaction execution 
 	using rpPPInteraction = 
 		Kokkos::RangePolicy<Kokkos::IndexType<uint32>, Kokkos::Schedule<Kokkos::Dynamic>>;
diff --git a/src/Particles/CMakeLists.txt b/src/Particles/CMakeLists.txt
index 4a11e460..b7f5ddc6 100644
--- a/src/Particles/CMakeLists.txt
+++ b/src/Particles/CMakeLists.txt
@@ -9,6 +9,8 @@ particles/regularParticleIdHandler/regularParticleIdHandler.cpp
 SphereParticles/sphereShape/sphereShape.cpp
 SphereParticles/sphereParticles/sphereParticles.cpp
 SphereParticles/sphereParticles/sphereParticlesKernels.cpp
+SphereParticles/boundarySphereParticles.cpp
+SphereParticles/boundarySphereParticlesList.cpp
 Insertion/collisionCheck/collisionCheck.cpp
 Insertion/insertionRegion/insertionRegion.cpp
 Insertion/insertion/insertion.cpp
@@ -18,7 +20,8 @@ Insertion/Insertion/Insertions.cpp
 
 if(pFlow_Build_MPI)
     list(APPEND SourceFiles 
-    particles/MPIParticleIdHandler/MPIParticleIdHandler.cpp)
+    particles/MPIParticleIdHandler/MPIParticleIdHandler.cpp
+    SphereParticles/processorBoundarySphereParticles.cpp)
 endif()
 
 set(link_libs Kokkos::kokkos phasicFlow Integration Property)
diff --git a/src/Particles/SphereParticles/sphereParticles/sphereParticles.cpp b/src/Particles/SphereParticles/sphereParticles/sphereParticles.cpp
index df7b98b8..9274f48c 100644
--- a/src/Particles/SphereParticles/sphereParticles/sphereParticles.cpp
+++ b/src/Particles/SphereParticles/sphereParticles/sphereParticles.cpp
@@ -384,6 +384,11 @@ pFlow::sphereParticles::sphereParticles(
 		dynPointStruct(),
 		zero3
 	),
+	boundarySphereParticles_
+	(
+		dynPointStruct().boundaries(),
+		*this
+	),
 	accelerationTimer_(
 		"Acceleration", &this->timers() ),
 	intPredictTimer_(
@@ -523,6 +528,7 @@ bool pFlow::sphereParticles::beforeIteration()
 	I_.updateBoundariesSlaveToMasterIfRequested();
 	rVelocity_.updateBoundariesSlaveToMasterIfRequested();
 	rAcceleration_.updateBoundariesSlaveToMasterIfRequested();
+	rVelIntegration_().updateBoundariesSlaveToMasterIfRequested();
 	fieldUpdateTimer_.end();
 	
 	return true;
@@ -531,10 +537,13 @@ bool pFlow::sphereParticles::beforeIteration()
 bool pFlow::sphereParticles::iterate() 
 {
 
+	timeInfo ti = TimeInfo();
+	realx3 g = control().g();
+
 	particles::iterate();
 	accelerationTimer_.start();
 		pFlow::sphereParticlesKernels::acceleration(
-			control().g(),
+			g,
 			mass().deviceViewAll(),
 			contactForce().deviceViewAll(),
 			I().deviceViewAll(),
@@ -543,6 +552,10 @@ bool pFlow::sphereParticles::iterate()
 			accelertion().deviceViewAll(),
 			rAcceleration().deviceViewAll()
 			);
+		for(auto& bndry:boundarySphereParticles_)
+		{
+			bndry->acceleration(ti, g);
+		}
 	accelerationTimer_.end();
 	
 	intCorrectTimer_.start();
diff --git a/src/Particles/SphereParticles/sphereParticles/sphereParticles.hpp b/src/Particles/SphereParticles/sphereParticles/sphereParticles.hpp
index d71e751a..9b3bddbc 100644
--- a/src/Particles/SphereParticles/sphereParticles/sphereParticles.hpp
+++ b/src/Particles/SphereParticles/sphereParticles/sphereParticles.hpp
@@ -33,6 +33,7 @@ Licence:
 #include "particles.hpp"
 #include "property.hpp"
 #include "sphereShape.hpp"
+#include "boundarySphereParticlesList.hpp"
 #include "systemControl.hpp"
 
 namespace pFlow
@@ -67,6 +68,9 @@ private:
 	/// pointField of rotational acceleration of particles on device
 	realx3PointField_D     rAcceleration_;
 
+	/// boundaries 
+	boundarySphereParticlesList boundarySphereParticles_;
+
 	/// rotational velocity integrator
 	uniquePtr<integration> rVelIntegration_ = nullptr;
 
diff --git a/src/Particles/dynamicPointStructure/dynamicPointStructure.cpp b/src/Particles/dynamicPointStructure/dynamicPointStructure.cpp
index 6ad16556..f0875341 100644
--- a/src/Particles/dynamicPointStructure/dynamicPointStructure.cpp
+++ b/src/Particles/dynamicPointStructure/dynamicPointStructure.cpp
@@ -85,6 +85,8 @@ bool pFlow::dynamicPointStructure::beforeIteration()
 	if(!pointStructure::beforeIteration())return false;
 	velocityUpdateTimer_.start();
 	velocity_.updateBoundariesSlaveToMasterIfRequested();
+	integrationPos_->updateBoundariesSlaveToMasterIfRequested();
+	integrationVel_->updateBoundariesSlaveToMasterIfRequested();
 	velocityUpdateTimer_.end();
 	return true;
 }
@@ -118,7 +120,7 @@ bool pFlow::dynamicPointStructure::correct
 {
 	//auto& pos = pStruct().pointPosition();
 	
-	if(!integrationPos_().correct(dt, pointPosition(), velocity_) )return false;
+	if(!integrationPos_().correctPStruct(dt, *this, velocity_) )return false;
 	
 	if(!integrationVel_().correct(dt, velocity_, acceleration))return false;
 
diff --git a/src/phasicFlow/CMakeLists.txt b/src/phasicFlow/CMakeLists.txt
index 7de9ceda..eb50c1a7 100644
--- a/src/phasicFlow/CMakeLists.txt
+++ b/src/phasicFlow/CMakeLists.txt
@@ -10,6 +10,8 @@ globals/globalSettings.cpp
 processors/processors.cpp
 processors/localProcessors.cpp
 processors/pFlowProcessors.cpp
+processors/MPITimer.cpp
+
 
 streams/token/tokenIO.cpp
 streams/token/token.cpp
diff --git a/src/phasicFlow/Timer/Timer.cpp b/src/phasicFlow/Timer/Timer.cpp
index 9a8b7812..467bee14 100644
--- a/src/phasicFlow/Timer/Timer.cpp
+++ b/src/phasicFlow/Timer/Timer.cpp
@@ -22,9 +22,19 @@ Licence:
 #include "Timers.hpp"
 #include "streams.hpp"
 
-pFlow::Timer::Timer(const word& name, Timers* parrent)
-  : name_(name),
-    parrent_(parrent)
+pFlow::real pFlow::Timer::averageTimeMax() const
+{
+    return 0.0;
+}
+
+pFlow::real pFlow::Timer::accTimersTotalMax() const
+{
+    return 0.0;
+}
+
+pFlow::Timer::Timer(const word &name, Timers *parrent)
+    : name_(name),
+      parrent_(parrent)
 {
 	if (parrent_)
 		parrent_->addToList(this);
diff --git a/src/phasicFlow/Timer/Timer.hpp b/src/phasicFlow/Timer/Timer.hpp
index b621a00a..6f9af9d7 100644
--- a/src/phasicFlow/Timer/Timer.hpp
+++ b/src/phasicFlow/Timer/Timer.hpp
@@ -22,7 +22,6 @@ Licence:
 #define __Timerr_hpp__
 
 #include <chrono>
-
 #include "types.hpp"
 
 namespace pFlow
@@ -33,7 +32,7 @@ class Timers;
 
 class Timer
 {
-protected:
+private:
 
 	using timer = std::chrono::high_resolution_clock;
 
@@ -59,6 +58,12 @@ protected:
 	/// @brief  parrent of timer
 	Timers*           parrent_ = nullptr;
 
+protected:
+
+	real averageTimeMax()const;
+
+	real accTimersTotalMax()const;
+
 public:
 
 	TypeInfo("Timer");
@@ -91,12 +96,19 @@ public:
 		return false;
 	}
 
+	Timers* parrent()const
+	{
+		return parrent_;
+	} 
+
+	inline
 	void start()
 	{
 		start_       = timer::now();
 		stepAccTime_ = 0;
 	}
 
+	inline
 	void pause()
 	{
 		auto end = timer::now();
@@ -107,11 +119,13 @@ public:
 		        .count();
 	}
 
+	inline
 	void resume()
 	{
 		start_ = timer::now();
 	}
 
+	inline
 	void end()
 	{
 		pause();
@@ -121,27 +135,32 @@ public:
 		accTime_ += lastTime_;
 	}
 
-	inline bool timerActive() const
+	inline 
+	bool timerActive() const
 	{
 		return numIteration_ != 0;
 	}
 
-	inline real lastTime() const
+	inline 
+	real lastTime() const
 	{
 		return lastTime_;
 	}
 
-	inline real totalTime() const
+	inline 
+	real totalTime() const
 	{
 		return accTime_;
 	}
 
-	inline real averageTime() const
+	inline 
+	real averageTime() const
 	{
 		return accTime_ / max(numIteration_, 1);
 	}
 
-	virtual real accTimersTotal() const
+	virtual 
+	real accTimersTotal() const
 	{
 		return totalTime();
 	}
diff --git a/src/phasicFlow/Timer/Timers.hpp b/src/phasicFlow/Timer/Timers.hpp
index fea6604b..1ea7d96a 100644
--- a/src/phasicFlow/Timer/Timers.hpp
+++ b/src/phasicFlow/Timer/Timers.hpp
@@ -22,7 +22,6 @@ Licence:
 #define __Timerss_hpp__
 
 
-
 #include "List.hpp"
 #include "Timer.hpp"
 
@@ -54,9 +53,9 @@ public:
 	:
 		Timer(name, parrent)
 	{
-		if(parrent_)
+		if(parrent)
 		{
-			level_ = parrent_->level()+1;
+			level_ = parrent->level()+1;
 		}
 	}
 
diff --git a/src/phasicFlow/containers/Field/Field.cpp b/src/phasicFlow/containers/Field/Field.cpp
index 10e14df8..8711d01d 100644
--- a/src/phasicFlow/containers/Field/Field.cpp
+++ b/src/phasicFlow/containers/Field/Field.cpp
@@ -21,17 +21,13 @@ Licence:
 template<class T, class MemorySpace>
 bool pFlow::Field<T, MemorySpace>::read
 (
-	iIstream& is,
-	bool resume
+	iIstream& is
 )
 {
 	
 	bool tokenFound = true;
 	
-	if(resume)
-		tokenFound = is.findTokenResume(fieldKey_);
-	else
-		tokenFound = is.findToken(fieldKey_);
+    tokenFound = is.findToken(fieldKey_);
 
 	if( !tokenFound )
 	{
@@ -63,16 +59,17 @@ bool pFlow::Field<T, MemorySpace>::read
 {
 	
 	bool tokenFound = true;
-	
-    if(iop.thisProcReadData())
+	if(resume)
 	{
-		if(resume)
-			tokenFound = is.findTokenResume(fieldKey_);
-		else
-			tokenFound = is.findToken(fieldKey_);
+		if(iop.thisProcReadData())
+        	tokenFound = is.findTokenResume(fieldKey_);
 	}
-	
-
+	else
+	{
+		if(iop.thisProcReadData())
+        	tokenFound = is.findToken(fieldKey_);
+	}
+    
 	if( !tokenFound )
 	{
 		ioErrorInFile( is.name(), is.lineNumber() ) <<
@@ -86,6 +83,7 @@ bool pFlow::Field<T, MemorySpace>::read
 		"error in reading field data from field "<< this->name()<<endl;
 		return false;
 	}
+	
     if(iop.thisProcReadData())
 	    is.readEndStatement("Field::read");
 
diff --git a/src/phasicFlow/containers/Field/Field.hpp b/src/phasicFlow/containers/Field/Field.hpp
index b38d3017..1fa326db 100644
--- a/src/phasicFlow/containers/Field/Field.hpp
+++ b/src/phasicFlow/containers/Field/Field.hpp
@@ -197,7 +197,7 @@ public:
 		
 	//// - IO operations 
 		
-		bool read(iIstream& is, bool resume = false);
+		bool read(iIstream& is);
 		
 		bool write(iOstream& os)const;			
 
diff --git a/src/phasicFlow/containers/pointField/boundaryField/boundaryField/boundaryField.cpp b/src/phasicFlow/containers/pointField/boundaryField/boundaryField/boundaryField.cpp
index b2674920..1d31e39b 100644
--- a/src/phasicFlow/containers/pointField/boundaryField/boundaryField/boundaryField.cpp
+++ b/src/phasicFlow/containers/pointField/boundaryField/boundaryField/boundaryField.cpp
@@ -41,8 +41,8 @@ typename pFlow::boundaryField<T, MemorySpace>::ProcVectorType&
 pFlow::boundaryField<T, MemorySpace>::neighborProcField()
 {
 	static ProcVectorType dummyVector{"dummyVector"};
-	notImplementedFunction;
-	fatalExit;
+	//notImplementedFunction;
+	//fatalExit;
 	return dummyVector;
 }
 
@@ -51,8 +51,8 @@ const typename pFlow::boundaryField<T, MemorySpace>::ProcVectorType&
 pFlow::boundaryField<T, MemorySpace>::neighborProcField() const
 {
 	static ProcVectorType dummyVector{"dummyVector"};
-	notImplementedFunction;
-	fatalExit;
+	//notImplementedFunction;
+	//fatalExit;
 	return dummyVector;
 }
 
diff --git a/src/phasicFlow/containers/pointField/boundaryField/boundaryField/boundaryField.hpp b/src/phasicFlow/containers/pointField/boundaryField/boundaryField/boundaryField.hpp
index 20267f33..4f7526be 100644
--- a/src/phasicFlow/containers/pointField/boundaryField/boundaryField/boundaryField.hpp
+++ b/src/phasicFlow/containers/pointField/boundaryField/boundaryField/boundaryField.hpp
@@ -133,6 +133,16 @@ public:
 		return internal_;
 	}
 
+	word fieldName()const
+	{
+		return internal_.name(); 
+	}
+
+	word name()const
+	{
+		return groupNames(fieldName(),boundaryName());
+	}
+
 	FieldAccessType thisField()const
 	{
         if constexpr(isDeviceAccessible<execution_space>())
diff --git a/src/phasicFlow/containers/pointField/boundaryField/boundaryFieldList.hpp b/src/phasicFlow/containers/pointField/boundaryField/boundaryFieldList.hpp
index 9ef6fcb1..9d929490 100644
--- a/src/phasicFlow/containers/pointField/boundaryField/boundaryFieldList.hpp
+++ b/src/phasicFlow/containers/pointField/boundaryField/boundaryFieldList.hpp
@@ -24,6 +24,7 @@ Licence:
 #include "boundaryList.hpp"
 #include "ListPtr.hpp"
 
+
 namespace pFlow
 {
 
@@ -67,9 +68,17 @@ public:
         if( direction == DataDirection::SlaveToMaster 
             && slaveToMasterUpdateIter_ == iter) return;
         
+        
+        
         // first step
+        uint32 i=0;
         for(auto b:*this)
         {
+            if(i==0 ) 
+            {
+                //pOutput<<"request for update boundaries for field "<< b->name()<<endl;
+                i++;
+            }
             b->updateBoundary(1, direction);
         }
 
diff --git a/src/phasicFlow/containers/pointField/boundaryField/generalBoundary/generalBoundary.hpp b/src/phasicFlow/containers/pointField/boundaryField/generalBoundary/generalBoundary.hpp
index 6a1f6808..8fef9628 100644
--- a/src/phasicFlow/containers/pointField/boundaryField/generalBoundary/generalBoundary.hpp
+++ b/src/phasicFlow/containers/pointField/boundaryField/generalBoundary/generalBoundary.hpp
@@ -123,7 +123,7 @@ public:
     }
 
     inline
-    const word& name()const
+    const word& boundaryName()const
     {
         return boundary_.name();
     }
diff --git a/src/phasicFlow/containers/pointField/internalField/internalField.hpp b/src/phasicFlow/containers/pointField/internalField/internalField.hpp
index ab26c663..9b6df04b 100644
--- a/src/phasicFlow/containers/pointField/internalField/internalField.hpp
+++ b/src/phasicFlow/containers/pointField/internalField/internalField.hpp
@@ -160,7 +160,7 @@ public:
 	}
 
 	inline
-	auto activeRange()const
+	rangeU32 activeRange()const
 	{
 		return internalPoints_.activeRange();
 	}
diff --git a/src/phasicFlow/demComponent/demComponent.cpp b/src/phasicFlow/demComponent/demComponent.cpp
index 9225eb17..7c4d020b 100644
--- a/src/phasicFlow/demComponent/demComponent.cpp
+++ b/src/phasicFlow/demComponent/demComponent.cpp
@@ -44,3 +44,8 @@ pFlow::uint32 pFlow::demComponent::currentIter() const
 {
   return time_.currentIter();
 }
+
+pFlow::timeInfo pFlow::demComponent::TimeInfo() const
+{
+    return time_.TimeInfo();
+}
diff --git a/src/phasicFlow/demComponent/demComponent.hpp b/src/phasicFlow/demComponent/demComponent.hpp
index cbab450e..1a67fbd0 100644
--- a/src/phasicFlow/demComponent/demComponent.hpp
+++ b/src/phasicFlow/demComponent/demComponent.hpp
@@ -23,6 +23,7 @@ Licence:
 
 #include "types.hpp"
 #include "typeInfo.hpp"
+#include "timeInfo.hpp"
 #include "Timers.hpp"
 
 namespace pFlow
@@ -102,7 +103,11 @@ public:
 		/// Current simulation time 
 		real currentTime()const;
 
+		/// @brief return current iteration number 
 		uint32 currentIter()const;
+
+		/// return time info of the simulaiton 
+		timeInfo TimeInfo()const;
 		
 		inline
 		const auto& time()const
diff --git a/src/phasicFlow/dictionary/dictionary.hpp b/src/phasicFlow/dictionary/dictionary.hpp
index 1684987c..e64dfec1 100644
--- a/src/phasicFlow/dictionary/dictionary.hpp
+++ b/src/phasicFlow/dictionary/dictionary.hpp
@@ -259,11 +259,29 @@ public:
 		template<typename T>
 		T getVal(const word& keyword) const;
 
+		/// get the value of data entry and return max(value, maxVal)
+		template<typename T>
+		T getValMax(const word& keyword, const T& maxVal)const;
+
+		/// get the value of data entry and return min(value, minVal)
+		template<typename T>
+		T getValMin(const word& keyword, const T& minVal)const;
+
 		/// get the value of data entry or 
 		/// if not found, set the value to setVal
 		template<typename T>
 		T getValOrSet(const word& keyword, const T& setVal)const;
 
+		/// get the value of data entry anf return max(setMaxVal, value)
+		/// if not found, set the value to setMaxVal 
+		template<typename T>
+		T getValOrSetMax(const word& keyword, const T& setMaxVal)const;
+
+		/// get the value of data entry anf return max(setMinVal, value)
+		/// if not found, set the value to setMinVal 
+		template<typename T>
+		T getValOrSetMin(const word& keyword, const T& setMinVal)const;
+
 		/// return number of entris in this dictionary
 		size_t numEntries()const;
 		
@@ -372,6 +390,26 @@ T dictionary::getVal
 	return val;
 }
 
+template<typename T>
+T dictionary::getValMax
+(
+	const word& keyword,
+	const T& maxVal
+)const 
+{
+	return max(getVal<T>(keyword), maxVal);
+}
+
+template<typename T>
+T dictionary::getValMin
+(
+	const word& keyword, 
+	const T& minVal
+)const
+{
+	return min(getVal<T>(keyword), minVal);
+}
+
 template<typename T>
 T dictionary::getValOrSet
 (
@@ -390,6 +428,18 @@ T dictionary::getValOrSet
 	}
 }
 
+template<typename T>
+T dictionary::getValOrSetMax(const word& keyword, const T& setMaxVal)const
+{
+	return max(getValOrSet(keyword, setMaxVal), setMaxVal);
+}
+
+template<typename T>
+T dictionary::getValOrSetMin(const word& keyword, const T& setMinVal)const
+{
+	return min(getValOrSet(keyword, setMinVal), setMinVal);
+}
+
 template <typename T>
 inline bool dictionary::addOrReplace
 (
@@ -402,8 +452,6 @@ inline bool dictionary::addOrReplace
 }
 
 
-
-
 } // pFlow
 
 #endif // __dictionary_hpp__
diff --git a/src/phasicFlow/eventManagement/subscriber.cpp b/src/phasicFlow/eventManagement/subscriber.cpp
index 6393e974..75ec485c 100644
--- a/src/phasicFlow/eventManagement/subscriber.cpp
+++ b/src/phasicFlow/eventManagement/subscriber.cpp
@@ -153,35 +153,7 @@ bool pFlow::subscriber::notify
 	return true;
 }
 
-/*bool pFlow::subscriber::notify
-(
-	const eventMessage &msg
-)
+bool pFlow::subscriber::notify(const timeInfo &ti, const message msg, const anyList &varList)
 {
-	for ( auto& observer:observerList_ )
-	{
-		if(observer)
-			if( !observer->update(msg) ) return false;
-	}
-
-	return true;
+    return notify(ti.iter(), ti.t(), ti.dt(), msg, varList);
 }
-
-bool pFlow::eventSubscriber::notify
-(
-	const eventMessage& msg,
-	const List<eventObserver*>& exclutionList
-)
-{
-	Set<eventObserver*> sortedExcList(exclutionList.begin(),exclutionList.end());
-
-	for(auto& observer:observerList_)
-	{
-		if( observer && sortedExcList.count(observer) == 0 )
-		{
-			if(!observer->update(msg)) return false;
-		}
-	}
-
-	return true;
-}*/
\ No newline at end of file
diff --git a/src/phasicFlow/eventManagement/subscriber.hpp b/src/phasicFlow/eventManagement/subscriber.hpp
index 1cf419f3..82b368fd 100644
--- a/src/phasicFlow/eventManagement/subscriber.hpp
+++ b/src/phasicFlow/eventManagement/subscriber.hpp
@@ -26,6 +26,7 @@ Licence:
 
 #include "List.hpp"
 #include "message.hpp"
+#include "timeInfo.hpp"
 
 namespace pFlow
 {
@@ -76,6 +77,11 @@ public:
 		const message msg, 
 		const anyList& varList);
 	
+	bool notify(
+		const timeInfo& ti,
+		const message msg, 
+		const anyList& varList);
+	
 	const word& subscriberName()const
 	{
 		return subName_;
diff --git a/src/phasicFlow/processors/processors.cpp b/src/phasicFlow/processors/processors.cpp
index 078c9a5d..8edb3b3a 100644
--- a/src/phasicFlow/processors/processors.cpp
+++ b/src/phasicFlow/processors/processors.cpp
@@ -35,6 +35,7 @@ Licence:
     pFlow::MPI::DataType pFlow::MPI::realx3Type__;
     pFlow::MPI::DataType pFlow::MPI::realx4Type__;
     pFlow::MPI::DataType pFlow::MPI::int32x3Type__;
+	pFlow::MPI::DataType pFlow::MPI::uint32x3Type__;
     
 #endif
 
@@ -74,6 +75,9 @@ void pFlow::processors::initProcessors(int argc, char *argv[])
 		MPI_Type_contiguous(3, pFlow::MPI::Type<int32>(), &pFlow::MPI::int32x3Type__);
 		MPI_Type_commit(&pFlow::MPI::int32x3Type__);
 
+		MPI_Type_contiguous(3, pFlow::MPI::Type<uint32>(), &pFlow::MPI::uint32x3Type__);
+		MPI_Type_commit(&pFlow::MPI::uint32x3Type__);
+
 	}
 #else
 
@@ -90,6 +94,7 @@ void pFlow::processors::finalizeProcessors()
         MPI::TypeFree(&pFlow::MPI::realx3Type__);
         MPI::TypeFree(&pFlow::MPI::realx4Type__);
 		MPI::TypeFree(&pFlow::MPI::int32x3Type__);
+		MPI::TypeFree(&pFlow::MPI::uint32x3Type__);
 		CheckMPI(MPI_Finalize(), true);
 	}
 #else
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.cpp b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.cpp
index 906d5fd9..d375635b 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.cpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.cpp
@@ -190,29 +190,58 @@ bool pFlow::boundaryBase::transferPointsToMirror
 	
 }
 
-pFlow::boundaryBase::boundaryBase
-(
+pFlow::uint32 pFlow::boundaryBase::markInNegativeSide(const word &name, uint32Vector_D &markedIndices) const
+{
+
+	uint32 s = size();
+
+	markedIndices.reallocate(s+1, s+1);
+	markedIndices.fill(0u);
+
+	const auto& markedIndicesD = markedIndices.deviceViewAll();
+	pointFieldAccessType points = thisPoints();
+	infinitePlane p = boundaryPlane().infPlane();
+
+	uint32 numMark = 0;	
+
+	Kokkos::parallel_reduce
+	(
+		"boundaryProcessor::afterIteration",
+		deviceRPolicyStatic(0,s),
+		LAMBDA_HD(uint32 i, uint32& markToUpdate)
+		{
+			if(p.pointInNegativeSide(points(i)))
+			{
+				markedIndicesD(i)=1;
+				markToUpdate++;
+			}
+		}, 
+		numMark
+	);
+
+    return numMark;
+}
+
+pFlow::boundaryBase::boundaryBase(
     const dictionary &dict,
-    const plane 	&bplane,
-    internalPoints 	&internal,
-	boundaryList	&bndrs,
-	uint32 			thisIndex
-)
-: 
-	subscriber(dict.name()),
-	boundaryPlane_(bplane),
-	indexList_(groupNames("indexList", dict.name())),
-	indexListHost_(groupNames("hostIndexList",dict.name())),
-	neighborLength_(dict.getVal<real>("neighborLength")),
-	updateInetrval_(dict.getVal<uint32>("updateInterval")),
-	boundaryExtntionLengthRatio_(dict.getVal<real>("boundaryExtntionLengthRatio")),
-	internal_(internal),
-	boundaries_(bndrs),
-	thisBoundaryIndex_(thisIndex),
-	neighborProcessorNo_(dict.getVal<int32>("neighborProcessorNo")),
-	isBoundaryMaster_(thisProcessorNo()>=neighborProcessorNo()),
-	name_(dict.name()),
-	type_(dict.getVal<word>("type"))
+    const plane &bplane,
+    internalPoints &internal,
+    boundaryList &bndrs,
+    uint32 thisIndex)
+    : subscriber(dict.name()),
+      boundaryPlane_(bplane),
+      indexList_(groupNames("indexList", dict.name())),
+      indexListHost_(groupNames("hostIndexList", dict.name())),
+      neighborLength_(dict.getVal<real>("neighborLength")),
+      // updateInetrval_(dict.getVal<uint32>("updateInterval")),
+      boundaryExtntionLengthRatio_(dict.getVal<real>("boundaryExtntionLengthRatio")),
+      internal_(internal),
+      boundaries_(bndrs),
+      thisBoundaryIndex_(thisIndex),
+      neighborProcessorNo_(dict.getVal<int32>("neighborProcessorNo")),
+      isBoundaryMaster_(thisProcessorNo() >= neighborProcessorNo()),
+      name_(dict.name()),
+      type_(dict.getVal<word>("type"))
 {
 	unSyncLists();
 }
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.hpp b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.hpp
index b1f8008a..9a3d13c0 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.hpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryBase/boundaryBase.hpp
@@ -17,7 +17,6 @@ Licence:
   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 -----------------------------------------------------------------------------*/
-
 #ifndef __boundaryBase_hpp__
 #define __boundaryBase_hpp__
 
@@ -26,8 +25,8 @@ Licence:
 #include "VectorSingles.hpp"
 #include "plane.hpp"
 #include "scatteredFieldAccess.hpp"
+#include "timeInfo.hpp"
 
-#include "streams.hpp"
 
 namespace pFlow
 {
@@ -68,8 +67,9 @@ private:
 	/// The length defined for creating neighbor list
 	real                   neighborLength_;
 
-	/// time steps between successive update of boundary lists  
-	uint32 				   updateInetrval_;
+	bool 				   updateTime_ = false;
+
+	bool 				   iterBeforeUpdate_ = false;
 
 	/// the extra boundary extension beyound actual limits of boundary 
 	real 				   boundaryExtntionLengthRatio_;
@@ -100,6 +100,12 @@ protected:
 	/// boundaryBase::setSize(newSize) too. 
 	virtual void setSize(uint32 newSize);
 
+
+	void setUpdateTime(bool val)
+	{
+		updateTime_ = val;
+	}
+
 	void setNewIndices(const uint32Vector_D& newIndices);
 
 	bool appendNewIndices(const uint32Vector_D& newIndices);
@@ -132,12 +138,6 @@ protected:
 		}
 	}
 
-	/// Is this iter the right time for updating bounday list
-	bool boundaryListUpdate(uint32 iter)const
-	{
-		return iter%updateInetrval_ == 0u || iter == 0u;
-	}
-
 	/// Update this boundary data in two steps (1 and 2).
 	/// This is called after calling beforeIteration for 
 	/// all boundaries, so any particle addition, deletion,
@@ -152,17 +152,19 @@ protected:
 
 	/// @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. 
+	/// @param step is the step in the transfer of data.
+	/// @param callAgain if operation requires at least one additional step 
+	/// to complete it should be set to true and if the operation is complete and no need for
+	/// additional step, it should be set to false;  
+	/// @return true: succesful, false: fail
 	virtual 
-	bool transferData(uint32 iter, int step)
+	bool transferData(uint32 iter, int step, bool& callAgain)
 	{
-		return false;
+		callAgain = false;
+		return true;
 	}
 	
-	 
+	uint32 markInNegativeSide(const word& name, uint32Vector_D& markedIndices )const;
 
 public:
 
@@ -231,6 +233,19 @@ public:
 		return -boundaryExtntionLengthRatio_*neighborLength_ * boundaryPlane_.normal();
 	}
 
+	/// Is this iter the right time for updating bounday list
+	inline
+	bool performBoundarytUpdate()const
+	{
+		return updateTime_;
+	}
+
+	inline
+	bool iterBeforeBoundaryUpdate()const
+	{
+		return iterBeforeUpdate_;
+	}
+
 	inline
 	const word& type()const
 	{
@@ -339,13 +354,24 @@ public:
 	
 
 	virtual 
-    bool beforeIteration(uint32 step, uint32 iterNum, real t, real dt) = 0 ;
+	bool beforeIteration(
+		uint32 step, 
+		const timeInfo& ti, 
+		bool updateIter, 
+		bool iterBeforeUpdate , 
+		bool& callAgain
+	)
+	{
+		updateTime_ = updateIter;
+		iterBeforeUpdate_ = iterBeforeUpdate;
+		return true;
+	}
 
 	virtual 
-    bool iterate(uint32 iterNum, real t, real dt) = 0;
+	bool iterate(const timeInfo& ti) = 0;
 
 	virtual 
-    bool afterIteration(uint32 iterNum, real t, real dt) = 0;
+	bool afterIteration(const timeInfo& ti) = 0;
 	
     pointFieldAccessType thisPoints()const;
 
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryExit/boundaryExit.cpp b/src/phasicFlow/structuredData/boundaries/boundaryExit/boundaryExit.cpp
index ce874e67..acf8fd9c 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryExit/boundaryExit.cpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryExit/boundaryExit.cpp
@@ -42,72 +42,80 @@ pFlow::boundaryExit::boundaryExit
 
 bool pFlow::boundaryExit::beforeIteration
 (
-	uint32 step,
-	uint32 iterNum, 
-	real t,
-	real dt
+	uint32 step, 
+	const timeInfo& ti, 
+	bool updateIter, 
+	bool iterBeforeUpdate , 
+	bool& callAgain
 )
 {
-	if(step!= 2 )return true;
 	
-	if( !boundaryListUpdate(iterNum))return true;
-
-	// nothing have to be done
-	if(empty())
+	if(step == 1)
 	{
+		boundaryBase::beforeIteration(step, ti, updateIter, iterBeforeUpdate, callAgain);
+		callAgain = true;
 		return true;
-	}
+	} 
+	else if(step == 2 )
+	{
+		callAgain = false;
 
-	uint32 s = size();
-	uint32Vector_D deleteFlags("deleteFlags",s+1, s+1, RESERVE());
-	deleteFlags.fill(0u);
-
-	const auto& deleteD = deleteFlags.deviceViewAll();
-	auto points = thisPoints();
-	auto p = boundaryPlane().infPlane();
-
-	uint32 numDeleted = 0;	
-
-	Kokkos::parallel_reduce
-	(
-		"boundaryExit::beforeIteration",
-		deviceRPolicyStatic(0,s),
-		LAMBDA_HD(uint32 i, uint32& delToUpdate)
+		if( !performBoundarytUpdate())
 		{
-			if(p.pointInNegativeSide(points(i)))
-			{
-				deleteD(i)=1;
-				delToUpdate++;
-			}
-		}, 
-		numDeleted
-	);
-		
-	// no point is deleted
-	if(numDeleted == 0 )
-	{
-		return true;
-	}
+			return true;
+		}
 
-	return this->removeIndices(numDeleted, deleteFlags);
+		// nothing have to be done
+		if(empty())
+		{
+			return true;
+		}
+
+		uint32 s = size();
+		uint32Vector_D deleteFlags("deleteFlags",s+1, s+1, RESERVE());
+		deleteFlags.fill(0u);
+
+		const auto& deleteD = deleteFlags.deviceViewAll();
+		auto points = thisPoints();
+		auto p = boundaryPlane().infPlane();
+
+		uint32 numDeleted = 0;	
+
+		Kokkos::parallel_reduce
+		(
+			"boundaryExit::beforeIteration",
+			deviceRPolicyStatic(0,s),
+			LAMBDA_HD(uint32 i, uint32& delToUpdate)
+			{
+				if(p.pointInNegativeSide(points(i)))
+				{
+					deleteD(i)=1;
+					delToUpdate++;
+				}
+			}, 
+			numDeleted
+		);
+			
+		// no point is deleted
+		if(numDeleted == 0 )
+		{
+			return true;
+		}
+
+		return this->removeIndices(numDeleted, deleteFlags);
+
+	}
+		
+	return true;
+	
 }
 
-bool pFlow::boundaryExit::iterate
-(
-	uint32 iterNum, 
-	real t,
-	real dt
-)
+bool pFlow::boundaryExit::iterate(const timeInfo& ti)
 {
 	return true;
 }
 
-bool pFlow::boundaryExit::afterIteration
-(
-	uint32 iterNum, 
-	real t,
-	real dt
-)
+bool pFlow::boundaryExit::afterIteration(const timeInfo& ti)
 {
 	return true;
 }
\ No newline at end of file
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryExit/boundaryExit.hpp b/src/phasicFlow/structuredData/boundaries/boundaryExit/boundaryExit.hpp
index b4763e26..a3b73cd5 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryExit/boundaryExit.hpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryExit/boundaryExit.hpp
@@ -63,11 +63,17 @@ public:
 		dictionary
 	);
 
-	bool beforeIteration(uint32 step, uint32 iterNum, real t, real dt) override;
+	bool beforeIteration(
+		uint32 step, 
+		const timeInfo& ti, 
+		bool updateIter, 
+		bool iterBeforeUpdate , 
+		bool& callAgain
+	) final;
 
-	bool iterate(uint32 iterNum, real t, real dt) override;
-
-	bool afterIteration(uint32 iterNum, real t, real dt) override;
+	bool iterate(const timeInfo& ti) final;
+	 
+	bool afterIteration(const timeInfo& ti)final;
 
 
 };
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryList.cpp b/src/phasicFlow/structuredData/boundaries/boundaryList.cpp
index 707e00ea..444119e1 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryList.cpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryList.cpp
@@ -90,25 +90,50 @@ pFlow::boundaryList::updateNeighborLists()
 
 pFlow::boundaryList::boundaryList(pointStructure& pStruct)
   : ListPtr<boundaryBase>(pStruct.simDomain().sizeOfBoundaries()),
-    pStruct_(pStruct),
-    neighborListUpdateInterval_(
-        max(
-            pStruct.simDomain().subDict("boundaries").getVal<uint32>(
-                "neighborListUpdateInterval"
-            ),
-            1u
-        )
-	)
+    pStruct_(pStruct)
 {
+	const dictionary& dict= pStruct_.simDomain().thisBoundariesDict();
+
+	neighborListUpdateInterval_ = dict.getValMax(
+			"neighborListUpdateInterval",
+			1u
+		);
+
+	updateInterval_ = dict.getVal<uint32>("updateInterval");
 }
 
 bool
 pFlow::boundaryList::updateNeighborLists(uint32 iter, bool force)
 {
+	neighborListUpdate_ = false;
+	boundaryUpdate_ = false;
+	iterBeforeBoundaryUpdate_ = false;
+
 	if(iter%neighborListUpdateInterval_==0u || iter == 0u || force)
 	{
-		return updateNeighborLists();
+		if(updateNeighborLists())
+		{
+			neighborListUpdate_ = true;
+			lastNeighborUpdated_ = iter;
+		}
+		else
+		{
+			fatalErrorInFunction<<"error in updating neighbor lists of boundaries"<<endl;
+			return false;
+		}
+		
 	}
+
+	if( iter%updateInterval_ == 0u || iter == 0u || force )
+	{
+		boundaryUpdate_ = true; 
+	}
+
+	if((iter+1)%updateInterval_ == 0u)
+	{
+		iterBeforeBoundaryUpdate_ = true;
+	}
+	
 	return true;
 }
 
@@ -158,37 +183,42 @@ pFlow::boundaryList::internalDomainBox() const
 }
 
 bool
-pFlow::boundaryList::beforeIteration(uint32 iter, real t, real dt, bool force)
+pFlow::boundaryList::beforeIteration(const timeInfo& ti, bool force)
 {
 	// it is time to update lists
-	if(!updateNeighborLists(iter , force) )
+	if(!updateNeighborLists(ti.iter() , force) )
 	{
-		fatalErrorInFunction;
 		return false;
 	}
 
-	// this forces performing updating the list on each boundary
-	if(force) iter = 0; 
-	
-	for (auto bdry : *this)
-	{
-		if (!bdry->beforeIteration(1, iter, t, dt))
-		{
-			fatalErrorInFunction << "Error in beforeIteration in boundary "
-			                     << bdry->name() << endl;
-			return false;
-		}
-	}
+	auto callAgain = boundariesMask<6>(true);
 
-	for (auto bdry : *this)
+	uint32 step = 1;
+
+	while(callAgain.anyElement(true) && step <= 10u)
 	{
-		if (!bdry->beforeIteration(2, iter, t, dt))
+		for(size_t i=0; i<6ul; i++)
 		{
-			fatalErrorInFunction << "Error in beforeIteration in boundary "
-			                     << bdry->name() << endl;
-			return false;
+
+			if(callAgain[i])
+			{
+				if(! boundary(i).beforeIteration(
+					step, 
+					ti,
+					boundaryUpdate_,
+					iterBeforeBoundaryUpdate_,
+					callAgain[i]))
+				{
+					fatalErrorInFunction<<"error in performing beforeIteration for boundary"<<
+					boundary(i).name()<<" at step "<< step<<endl;
+					return false;
+				}
+			}			
 		}
+
+		step++;
 	}
+	
 
 	for (auto bdry : *this)
 	{
@@ -204,11 +234,11 @@ pFlow::boundaryList::beforeIteration(uint32 iter, real t, real dt, bool force)
 }
 
 bool
-pFlow::boundaryList::iterate(uint32 iter, real t, real dt)
+pFlow::boundaryList::iterate(const timeInfo& ti, bool force)
 {
 	for (auto& bdry : *this)
 	{
-		if (!bdry->iterate(iter, t, dt))
+		if (!bdry->iterate(ti))
 		{
 			fatalErrorInFunction << "Error in iterate in boundary "
 			                     << bdry->name() << endl;
@@ -219,19 +249,24 @@ pFlow::boundaryList::iterate(uint32 iter, real t, real dt)
 }
 
 bool
-pFlow::boundaryList::afterIteration(uint32 iter, real t, real dt)
+pFlow::boundaryList::afterIteration(const timeInfo& ti, bool force)
 {
 	
-	std::array<bool,6> requireStep{true, true, true, true, true, true};
+	auto callAgain = boundariesMask<6>(true);
 
 	int step = 1;
-	while(std::any_of(requireStep.begin(), requireStep.end(), [](bool v) { return v==true; }))
+	while(callAgain.anyElement(true)&& step <=10)
 	{
-		for(auto i=0uL; i<6; i++)
+		for(size_t i=0; i<6; i++)
 		{
-			if(requireStep[i])
+			if(callAgain[i])
 			{
-				requireStep[i] = this->operator[](i).transferData(iter, step);
+				if( !boundary(i).transferData(ti.iter(), step, callAgain[i]))
+				{
+					fatalErrorInFunction<<"Error in transfering data for boundary "<<
+					boundary(i).name()<<endl;
+					return false;
+				}
 			}
 		}
 		step++;
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryList.hpp b/src/phasicFlow/structuredData/boundaries/boundaryList.hpp
index 8d4c8710..ddcb708c 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryList.hpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryList.hpp
@@ -23,6 +23,8 @@ Licence:
 #include "domain.hpp"
 #include "boundaryBase.hpp"
 #include "ListPtr.hpp"
+#include "timeInfo.hpp"
+#include "boundariesMask.hpp"
 
 
 namespace pFlow
@@ -41,11 +43,21 @@ private:
 
 	uint32 			neighborListUpdateInterval_;
 
-	domain          extendedDomain_;
+	uint32 			updateInterval_;
 
-	box             internalDomainBox_;
+	uint32 			lastNeighborUpdated_ = 0;
 
-	bool            listSet_ = false;
+	bool 			neighborListUpdate_;
+
+	bool 			boundaryUpdate_;
+
+	bool 			iterBeforeBoundaryUpdate_;
+
+	domain 			extendedDomain_;
+
+	box				internalDomainBox_;
+
+	bool			listSet_ = false;
 
 	void setExtendedDomain();
 
@@ -91,6 +103,11 @@ public:
 		return ListPtr<boundaryBase>::operator[](i);
 	}
 
+	inline 
+	bool boundariesUpdated()const 
+	{
+		return boundaryUpdate_;
+	}
 
 	inline
 	const auto& extendedDomain()const
@@ -106,11 +123,11 @@ public:
 
 	box internalDomainBox()const;
 	
-	bool beforeIteration(uint32 iter, real t, real dt, bool force = false);
+	bool beforeIteration(const timeInfo& tf, bool force = false);
 
-	bool iterate(uint32 iter, real t, real dt);
+	bool iterate(const timeInfo& tf, bool force = false);
 
-	bool afterIteration(uint32 iter, real t, real dt);
+	bool afterIteration(const timeInfo& tf, bool force = false);
 	
 };
 
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryNone/boundaryNone.cpp b/src/phasicFlow/structuredData/boundaries/boundaryNone/boundaryNone.cpp
index 7f228562..91502ced 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryNone/boundaryNone.cpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryNone/boundaryNone.cpp
@@ -32,33 +32,24 @@ pFlow::boundaryNone::boundaryNone
 	boundaryBase(dict, bplane, internal, bndrs, thisIndex)
 {}
 
-bool pFlow::boundaryNone::beforeIteration
-(
-	uint32 step,
-	uint32 iterNum, 
-	real t,
-	real dt
-)
+bool pFlow::boundaryNone::beforeIteration(
+	uint32 step, 
+	const timeInfo &ti, 
+	bool updateIter, 
+	bool iterBeforeUpdate, 
+	bool &callAgain)
+{
+	boundaryBase::beforeIteration(step, ti, updateIter, iterBeforeUpdate, callAgain);
+	callAgain = false;
+  return true;
+}
+
+bool pFlow::boundaryNone::iterate(const timeInfo &ti)
 {
 	return true;
 }
 
-bool pFlow::boundaryNone::iterate
-(
-	uint32 iterNum, 
-	real t,
-	real dt
-)
-{
-	return true;
-}
-
-bool pFlow::boundaryNone::afterIteration
-(
-	uint32 iterNum, 
-	real t,
-	real dt
-)
+bool pFlow::boundaryNone::afterIteration(const timeInfo& ti)
 {
 	return true;
 }
\ No newline at end of file
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryNone/boundaryNone.hpp b/src/phasicFlow/structuredData/boundaries/boundaryNone/boundaryNone.hpp
index 68ddf33f..41c3cad9 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryNone/boundaryNone.hpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryNone/boundaryNone.hpp
@@ -52,12 +52,17 @@ public:
 		dictionary
 	);
 
-	bool beforeIteration(uint32 step, uint32 iterNum, real t, real dt) final;
+	bool beforeIteration(
+		uint32 step, 
+		const timeInfo& ti, 
+		bool updateIter, 
+		bool iterBeforeUpdate , 
+		bool& callAgain
+	)final;
 
-	bool iterate(uint32 iterNum, real t, real dt) final;
-
-	bool afterIteration(uint32 iterNum, real t, real dt) final;
+	bool iterate(const timeInfo& ti) final;
 
+	bool afterIteration(const timeInfo& ti) final;
 
 };
 
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryPeriodic/boundaryPeriodic.cpp b/src/phasicFlow/structuredData/boundaries/boundaryPeriodic/boundaryPeriodic.cpp
index cf111eb5..0abf337d 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryPeriodic/boundaryPeriodic.cpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryPeriodic/boundaryPeriodic.cpp
@@ -51,79 +51,83 @@ pFlow::realx3 pFlow::boundaryPeriodic::boundaryExtensionLength() const
 
 
 bool pFlow::boundaryPeriodic::beforeIteration(
-	uint32 step,
-    uint32 iterNum,
-    real t,
-    real dt)
+	uint32 step, 
+	const timeInfo& ti, 
+	bool updateIter, 
+	bool iterBeforeUpdate , 
+	bool& callAgain)
 {
-	if(step!=2)return true;
-	// nothing have to be done
-	if(empty())
+	if(step==1)
 	{
-		return true;
+		callAgain = true;
 	}
-
-	if( !boundaryListUpdate(iterNum))return true;
-	
-	uint32 s = size();
-	uint32Vector_D transferFlags("transferFlags",s+1, s+1, RESERVE()); 
-	transferFlags.fill(0u);
-	
-	auto points = thisPoints();
-	auto p = boundaryPlane().infPlane();
-	const auto & transferD = transferFlags.deviceViewAll();
-	
-	uint32 numTransfered = 0;
-
-	Kokkos::parallel_reduce
-	(
-		"boundaryPeriodic::beforeIteration",
-		deviceRPolicyStatic(0u,s),
-		LAMBDA_HD(uint32 i, uint32& trnasToUpdate)
+	else
+	{
+		callAgain = false;
+		// nothing have to be done
+		if(empty())
 		{
-			if(p.pointInNegativeSide(points(i)))
+			return true;
+		}
+
+		if(!performBoundarytUpdate())
+		{
+			return true;
+		}
+
+		uint32 s = size();
+		uint32Vector_D transferFlags("transferFlags",s+1, s+1, RESERVE()); 
+		transferFlags.fill(0u);
+		
+		auto points = thisPoints();
+		auto p = boundaryPlane().infPlane();
+		const auto & transferD = transferFlags.deviceViewAll();
+		
+		uint32 numTransfered = 0;
+
+		Kokkos::parallel_reduce
+		(
+			"boundaryPeriodic::beforeIteration",
+			deviceRPolicyStatic(0u,s),
+			LAMBDA_HD(uint32 i, uint32& trnasToUpdate)
 			{
-				transferD(i)=1;
-				trnasToUpdate++;
-			}
-		}, 
-		numTransfered
-	);
-	
-	// no point to be transfered 
-	if(numTransfered == 0 )
-	{
-		return true;
+				if(p.pointInNegativeSide(points(i)))
+				{
+					transferD(i)=1;
+					trnasToUpdate++;
+				}
+			}, 
+			numTransfered
+		);
+
+		// no point to be transfered 
+		if(numTransfered == 0 )
+		{
+			return true;
+		}
+		
+		// to obtain the transfer vector 
+		realx3 transferVec = displacementVectroToMirror();
+		
+		return transferPointsToMirror
+		(
+			numTransfered,
+			transferFlags, 
+			mirrorBoundaryIndex(), 
+			transferVec
+		);
 	}
 	
-	// to obtain the transfer vector 
-	realx3 transferVec = displacementVectroToMirror();
+	return true;
 	
-	return transferPointsToMirror
-	(
-		numTransfered,
-		transferFlags, 
-		mirrorBoundaryIndex(), 
-		transferVec
-	);
 }
 
-bool pFlow::boundaryPeriodic::iterate
-(
-	uint32 iterNum, 
-	real t,
-	real dt
-)
+bool pFlow::boundaryPeriodic::iterate(const timeInfo& ti)
 {
 	return true;
 }
 
-bool pFlow::boundaryPeriodic::afterIteration
-(
-	uint32 iterNum, 
-	real t,
-	real dt
-)
+bool pFlow::boundaryPeriodic::afterIteration(const timeInfo& ti)
 {
 	return true;
 }
\ No newline at end of file
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryPeriodic/boundaryPeriodic.hpp b/src/phasicFlow/structuredData/boundaries/boundaryPeriodic/boundaryPeriodic.hpp
index 69b0413a..87f86033 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryPeriodic/boundaryPeriodic.hpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryPeriodic/boundaryPeriodic.hpp
@@ -62,14 +62,17 @@ public:
 
 	realx3 boundaryExtensionLength()const override;
 
-	//const plane& boundaryPlane()const override;*/
-
-	bool beforeIteration(uint32 step, uint32 iterNum, real t, real dt) override;
-
-	bool iterate(uint32 iterNum, real t, real dt) override;
-
-	bool afterIteration(uint32 iterNum, real t, real dt) override;
+	bool beforeIteration(
+		uint32 step, 
+		const timeInfo& ti, 
+		bool updateIter, 
+		bool iterBeforeUpdate , 
+		bool& callAgain
+	) final ;
 
+	bool iterate(const timeInfo& ti) final;
+	 
+	bool afterIteration(const timeInfo& ti)final;
 
 };
 
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryReflective/boundaryReflective.cpp b/src/phasicFlow/structuredData/boundaries/boundaryReflective/boundaryReflective.cpp
index 8de9b74f..3d4296e7 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryReflective/boundaryReflective.cpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryReflective/boundaryReflective.cpp
@@ -46,19 +46,20 @@ pFlow::boundaryReflective::boundaryReflective
 }
 
 bool pFlow::boundaryReflective::beforeIteration(
-    uint32 step,
-    uint32 iterNum,
-    real t,
-    real dt)
+    uint32 step, 
+	const timeInfo& ti, 
+	bool updateIter, 
+	bool iterBeforeUpdate , 
+	bool& callAgain)
 {
+    boundaryBase::beforeIteration(step, ti, updateIter, iterBeforeUpdate, callAgain);
+    callAgain = false;
     return true;
 }
 
 bool pFlow::boundaryReflective::iterate
 (
-    uint32 iterNum, 
-    real t, 
-    real dt
+    const timeInfo& ti
 )
 {
     return true;
@@ -66,9 +67,7 @@ bool pFlow::boundaryReflective::iterate
 
 bool pFlow::boundaryReflective::afterIteration
 (
-    uint32 iterNum, 
-    real t, 
-    real dt
+    const timeInfo& ti
 )
 {
     if(empty())return true;
diff --git a/src/phasicFlow/structuredData/boundaries/boundaryReflective/boundaryReflective.hpp b/src/phasicFlow/structuredData/boundaries/boundaryReflective/boundaryReflective.hpp
index 3f3bc64c..161b2004 100644
--- a/src/phasicFlow/structuredData/boundaries/boundaryReflective/boundaryReflective.hpp
+++ b/src/phasicFlow/structuredData/boundaries/boundaryReflective/boundaryReflective.hpp
@@ -59,11 +59,17 @@ public:
 		dictionary
 	);
 
-	bool beforeIteration(uint32 step, uint32 iterNum, real t, real dt) override;
+	bool beforeIteration(
+		uint32 step, 
+		const timeInfo& ti, 
+		bool updateIter, 
+		bool iterBeforeUpdate , 
+		bool& callAgain
+	) final ;
 
-	bool iterate(uint32 iterNum, real t, real dt) override;
-
-	bool afterIteration(uint32 iterNum, real t, real dt) override;
+	bool iterate(const timeInfo& ti) final;
+	 
+	bool afterIteration(const timeInfo& ti)final;
 
 
 };
diff --git a/src/phasicFlow/structuredData/domain/regularSimulationDomain.cpp b/src/phasicFlow/structuredData/domain/regularSimulationDomain.cpp
index aef3c126..7bda6142 100644
--- a/src/phasicFlow/structuredData/domain/regularSimulationDomain.cpp
+++ b/src/phasicFlow/structuredData/domain/regularSimulationDomain.cpp
@@ -18,61 +18,30 @@ Licence:
 
 -----------------------------------------------------------------------------*/
 
-#include <cstring>
-
 #include "regularSimulationDomain.hpp"
 #include "processors.hpp"
 #include "streams.hpp"
 
 bool pFlow::regularSimulationDomain::createBoundaryDicts()
 {
-    auto& boundaries = this->subDict("boundaries");
-    
-    this->addDict("regularBoundaries", boundaries);
-    auto& rbBoundaries = this->subDict("regularBoundaries");
-    
-	auto neighborLength = boundaries.getVal<real>("neighborLength");
-	auto boundaryExtntionLengthRatio = max(
-		boundaries.getValOrSet<real>("boundaryExtntionLengthRatio", 0.1),
-        0.0);
-	auto updateIntercal = max( 
-        boundaries.getValOrSet<uint32>("updateInterval", 1u),
-        1u); 
+
+	dictionary& thisBoundaries = this->subDict(thisBoundariesDictName());
 
 	for(uint32 i=0; i<sizeOfBoundaries(); i++)
 	{
 		word bName = bundaryName(i);
-		if( !boundaries.containsDictionay(bName) )
-		{
-			fatalErrorInFunction<<"dictionary "<< bName<<
-			"does not exist in "<< boundaries.globalName()<<endl;
-			return false;
-		}
-		auto& bDict = rbBoundaries.subDict(bName);
-
-		if(!bDict.addOrKeep("neighborLength", neighborLength))
-		{
-			fatalErrorInFunction<<"error in adding neighborLength to "<< bName <<
-			"in dictionary "<< boundaries.globalName()<<endl;
-			return false;
-		}
-
-		if(!bDict.addOrReplace("updateInterval", updateIntercal))
-		{
-			fatalErrorInFunction<<"error in adding updateIntercal to "<< bName <<
-			"in dictionary "<< boundaries.globalName()<<endl;
-		}
-
-		bDict.addOrReplace("boundaryExtntionLengthRatio", boundaryExtntionLengthRatio);
+		dictionary& bDict = thisBoundaries.subDict(bName);
 
 		if(!bDict.add("neighborProcessorNo",(uint32) processors::globalRank()))
 		{
 			fatalErrorInFunction<<"error in adding neighborProcessorNo to "<< bName <<
-			" in dictionary "<< boundaries.globalName()<<endl;
+			" in dictionary "<< thisBoundaries.globalName()<<endl;
 			return false;
 		}
+
 		auto bType = bDict.getVal<word>("type");
 		uint32 mirrorIndex = 0;
+
 		if(bType == "periodic")
 		{
 			if(bName == bundaryName(0)) mirrorIndex = 1;
@@ -92,7 +61,6 @@ bool pFlow::regularSimulationDomain::createBoundaryDicts()
 		}
 	}
     
-    
     return true;
 }
 
@@ -229,9 +197,3 @@ bool pFlow::regularSimulationDomain::initialTransferBlockData
         charSpan(dst), 
         sizeof(int32)); 
 }
-
-const pFlow::dictionary &pFlow::regularSimulationDomain::thisBoundaryDict() const
-{
-    return this->subDict("regularBoundaries");
-}
-
diff --git a/src/phasicFlow/structuredData/domain/regularSimulationDomain.hpp b/src/phasicFlow/structuredData/domain/regularSimulationDomain.hpp
index 74bea6bc..5eb23619 100644
--- a/src/phasicFlow/structuredData/domain/regularSimulationDomain.hpp
+++ b/src/phasicFlow/structuredData/domain/regularSimulationDomain.hpp
@@ -88,8 +88,6 @@ public:
 	bool initialTransferBlockData(span<int32> src, span<int32> dst)
 	  const final;
 
-	const dictionary& thisBoundaryDict() const final;
-
 };
 
 }
diff --git a/src/phasicFlow/structuredData/domain/simulationDomain.cpp b/src/phasicFlow/structuredData/domain/simulationDomain.cpp
index 07a3a479..eaf55965 100644
--- a/src/phasicFlow/structuredData/domain/simulationDomain.cpp
+++ b/src/phasicFlow/structuredData/domain/simulationDomain.cpp
@@ -23,22 +23,81 @@ Licence:
 #include "systemControl.hpp"
 #include "vocabs.hpp"
 
-pFlow::simulationDomain::simulationDomain(systemControl& control)
-:
-	fileDictionary
-	(
-		objectFile
-		(
-			domainFile__,
-			"",
-			objectFile::READ_ALWAYS,
-			objectFile::WRITE_NEVER
-		),
-		&control.settings()
-	),
-    globalBox_(subDict("globalBox"))
+bool pFlow::simulationDomain::prepareBoundaryDicts()
 {
-    
+	
+    dictionary& boundaries = this->subDict("boundaries");
+
+    real neighborLength = boundaries.getVal<real>("neighborLength");
+
+	real boundaryExtntionLengthRatio = 
+        boundaries.getValOrSetMax("boundaryExtntionLengthRatio", 0.1);
+	
+    uint32 updateInterval = 
+        boundaries.getValOrSetMax<uint32>("updateInterval", 1u);
+
+    uint32 neighborListUpdateInterval = 
+        boundaries.getValMax("neighborListUpdateInterval", updateInterval);
+
+    boundaries.addOrReplace("neighborListUpdateInterval", neighborListUpdateInterval);
+
+	// create this boundaries dictionary 
+	this->addDict(thisBoundariesDictName(), boundaries);
+    dictionary& thisBDict = this->subDict(thisBoundariesDictName());
+	thisBDict.addOrReplace("neighborLength", neighborLength);
+	thisBDict.addOrReplace("boundaryExtntionLengthRatio", boundaryExtntionLengthRatio);
+	thisBDict.addOrReplace("updateInterval", updateInterval);
+	thisBDict.addOrReplace("neighborListUpdateInterval", neighborListUpdateInterval);
+
+
+    for(uint32 i=0; i<sizeOfBoundaries(); i++)
+	{
+		word bName = bundaryName(i);
+		if( !boundaries.containsDictionay(bName) )
+		{
+			fatalErrorInFunction<<"dictionary "<< bName<<
+			"does not exist in "<< boundaries.globalName()<<endl;
+			return false;
+		}
+		auto& bDict = thisBDict.subDict(bName);
+
+		if(!bDict.addOrKeep("neighborLength", neighborLength))
+		{
+			fatalErrorInFunction<<"error in adding neighborLength to "<< bName <<
+			"in dictionary "<< boundaries.globalName()<<endl;
+			return false;
+		}
+
+		if(!bDict.addOrReplace("updateInterval", updateInterval))
+		{
+			fatalErrorInFunction<<"error in adding updateInterval to "<< bName <<
+			"in dictionary "<< boundaries.globalName()<<endl;
+            return false;
+		}
+
+		bDict.addOrReplace("boundaryExtntionLengthRatio", boundaryExtntionLengthRatio);
+
+	}
+
+    return true;
+}
+
+pFlow::simulationDomain::simulationDomain(systemControl &control)
+    : fileDictionary(
+          objectFile(
+              domainFile__,
+              "",
+              objectFile::READ_ALWAYS,
+              objectFile::WRITE_NEVER),
+          &control.settings()),
+      globalBox_(subDict("globalBox"))
+{
+    if( !prepareBoundaryDicts() )
+    {
+        fatalErrorInFunction<<
+            "Error in preparing dictionaries for boundaries"<<endl;
+        fatalExit;
+    }
 }
 
 pFlow::domain pFlow::simulationDomain::extendThisDomain
diff --git a/src/phasicFlow/structuredData/domain/simulationDomain.hpp b/src/phasicFlow/structuredData/domain/simulationDomain.hpp
index 071e1326..dd4d42c9 100644
--- a/src/phasicFlow/structuredData/domain/simulationDomain.hpp
+++ b/src/phasicFlow/structuredData/domain/simulationDomain.hpp
@@ -44,7 +44,6 @@ private:
 	/// @brief acutal limits of the global box of  simulation
 	box 			globalBox_;
 
-
 	static constexpr uint32 sizeOfBoundaries_ = 6;
 
 	static 
@@ -55,6 +54,10 @@ private:
 		"rear", "front"
 	};
 	
+protected:
+
+	bool prepareBoundaryDicts();
+	
 	virtual 
 	bool createBoundaryDicts() = 0;
 
@@ -86,8 +89,30 @@ public:
 		return globalBox_;
 	}
 
-	virtual 
-	const dictionary& thisBoundaryDict()const = 0;
+	/// @brief The original dictionary supplied by the user as input 
+	inline 
+	const auto& globalBoundariesDict()const
+	{
+		return static_cast<const fileDictionary&>(*this);
+	}
+
+	/// @brief The generated dictionary generated by code which is used
+	const dictionary& thisBoundariesDict()const
+	{
+		return this->subDict(thisBoundariesDictName());
+	}
+	
+	word thisBoundariesDictName()const
+	{
+		return "thsiDomainBoundaries";
+	}
+
+	/// @brief return a const ref to dicrionary of boundary i of this processor 
+	inline
+	const dictionary& boundaryDict(uint32 i)const
+	{
+		return thisBoundariesDict().subDict(bundaryName(i));
+	}
 	
     virtual 
     bool initialUpdateDomains(span<realx3> pointPos) = 0;
@@ -159,25 +184,10 @@ public:
 	domain extendThisDomain(
 		const realx3& lowerPointExtension, 
 		const realx3& upperPointExtension)const;
-
-	/// @brief The original dictionary supplied by the user as input 
-	inline 
-	const auto& globalBoundaryDict()const
-	{
-		return static_cast<const fileDictionary&>(*this);
-	}
-
-	/// @brief return a const ref to dicrionary of boundary i of this processor 
-	inline
-	const dictionary& boundaryDict(uint32 i)const
-	{
-		return thisBoundaryDict().subDict(bundaryName(i));
-	}
 	
 	/// @brief return a const ref to the plane of boundary i of this processor 
 	const plane& boundaryPlane(uint32 i)const;
 	
-
 	static
 	uniquePtr<simulationDomain> create(systemControl& control);
 
diff --git a/src/phasicFlow/structuredData/pointStructure/pointStructure/pointStructure.cpp b/src/phasicFlow/structuredData/pointStructure/pointStructure/pointStructure.cpp
index bc0e7976..3f94ea59 100644
--- a/src/phasicFlow/structuredData/pointStructure/pointStructure/pointStructure.cpp
+++ b/src/phasicFlow/structuredData/pointStructure/pointStructure/pointStructure.cpp
@@ -171,11 +171,9 @@ pFlow::pointStructure::pointStructure(
 
 bool pFlow::pointStructure::beforeIteration()
 {
-    uint32 iter = currentIter();
-    real t = currentTime();
-    real deltat = dt();
+    const timeInfo ti = TimeInfo();
 
-    if(pointSorting_.sortTime(iter, t, deltat))
+    if(pointSorting_.sortTime(ti.iter(), ti.t(), ti.dt()))
     {
         auto sortedIndices = pointSorting_.getSortedIndices(
             simulationDomain_().globalBox(),
@@ -190,11 +188,13 @@ bool pFlow::pointStructure::beforeIteration()
         }
         
         boundaryUpdateTimer_.start();
-        boundaries_.beforeIteration(iter, t, deltat, true); 
+        boundaries_.beforeIteration(ti, true); 
         boundaryUpdateTimer_.end();
 
         INFORMATION<<"Reordering of particles has been done. New active range for particles is "<<
         activeRange()<<END_INFO; 
+
+
         message msg;
         anyList varList;
 
@@ -202,7 +202,7 @@ bool pFlow::pointStructure::beforeIteration()
             msg.addAndName(message::ITEM_REARRANGE),
             sortedIndices);
 
-        if(!notify(iter, t, deltat, msg, varList))
+        if(!notify(ti, msg, varList))
         {
             fatalErrorInFunction<<
             "cannot notify for reordering items."<<endl;
@@ -214,7 +214,7 @@ bool pFlow::pointStructure::beforeIteration()
     else
     {
         boundaryUpdateTimer_.start();
-        if( !boundaries_.beforeIteration(iter, t, deltat) )
+        if( !boundaries_.beforeIteration(ti) )
         {
             fatalErrorInFunction<<
             "Unable to perform beforeIteration for boundaries"<<endl;
@@ -228,7 +228,7 @@ bool pFlow::pointStructure::beforeIteration()
 
 bool pFlow::pointStructure::iterate()
 {
-    if( !boundaries_.iterate(currentIter(), currentTime(), dt()) )
+    if( !boundaries_.iterate(TimeInfo()) )
     {
         fatalErrorInFunction<<
         "Unable to perform iterate for boundaries"<<endl;
@@ -241,7 +241,7 @@ bool pFlow::pointStructure::iterate()
 bool pFlow::pointStructure::afterIteration()
 {
     boundaryDataTransferTimer_.start();
-    if( !boundaries_.afterIteration(currentIter(), currentTime(), dt()) )
+    if( !boundaries_.afterIteration(TimeInfo()) )
     {
         fatalErrorInFunction<<
         "Unable to perform afterIteration for boundaries"<<endl;