Merge pull request #93 from PhasicFlow/develop

Periodic boundary condition implementation
This commit is contained in:
PhasicFlow 2024-03-26 20:39:43 +03:30 committed by GitHub
commit 7be70caa82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 510 additions and 157 deletions

View File

@ -6,6 +6,7 @@ contactSearch/methods/cellBased/NBS/NBSLevel0.cpp
contactSearch/methods/cellBased/NBS/NBS.cpp
contactSearch/methods/cellBased/NBS/cellsWallLevel0.cpp
contactSearch/contactSearch/contactSearch.cpp
contactSearch/boundaries/searchBoundary.cpp
contactSearch/ContactSearch/ContactSearchs.cpp
interaction/interaction.cpp
sphereInteraction/sphereInteractions.cpp

View File

@ -0,0 +1,36 @@
#include "searchBoundary.hpp"
#include "contactSearch.hpp"
pFlow::searchBoundary::searchBoundary
(
const dictionary& dict,
const boundaryBase& boundary,
const contactSearch& cSearch
)
:
generalBoundary
(
boundary,
cSearch.pStruct(),
"",
""
),
contactSearch_(cSearch),
updateInterval_(dict.getVal<uint32>("updateInterval"))
{
}
pFlow::uniquePtr<pFlow::searchBoundary>
pFlow::searchBoundary::create
(
const dictionary &dict,
const boundaryBase &boundary,
const contactSearch &cSearch
)
{
return nullptr;
}

View File

@ -0,0 +1,113 @@
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#ifndef __searchBoundary_hpp__
#define __searchBoundary_hpp__
#include "generalBoundary.hpp"
#include "virtualConstructor.hpp"
namespace pFlow
{
class contactSearch;
class searchBoundary
:
public generalBoundary
{
private:
const contactSearch& contactSearch_;
/// @brief update interval in terms of iteration numebr
uint32 updateInterval_;
/// @brief last iteration number which contact search has been performed
uint32 lastUpdated_ = 0;
/// @brief performed search?
bool performedSearch_ = false;
public:
// type info
TypeInfo("searchBoundary<regular,none>");
searchBoundary(
const dictionary& dict,
const boundaryBase& boundary,
const contactSearch& cSearch);
create_vCtor
(
searchBoundary,
boundaryBase,
(
const dictionary& dict,
const boundaryBase& boundary,
const contactSearch& cSearch
),
(dict, boundary, cSearch)
);
add_vCtor
(
searchBoundary,
searchBoundary,
boundaryBase
);
void fill(const std::any& val)override
{
return;
}
bool hearChanges
(
real t,
real dt,
uint32 iter,
const message& msg,
const anyList& varList
) override
{
if(msg.equivalentTo(message::BNDR_RESET))
{
//do nothing
}
return true;
}
static
uniquePtr<searchBoundary> create(
const dictionary& dict,
const boundaryBase& boundary,
const contactSearch& cSearch);
};
}
#endif //__searchBoundary_hpp__

View File

@ -20,6 +20,7 @@ Licence:
#include "contactSearch.hpp"
#include "streams.hpp"
#include "particles.hpp"
pFlow::contactSearch::contactSearch(
@ -39,13 +40,17 @@ pFlow::contactSearch::contactSearch(
}
const pFlow::pointStructure &pFlow::contactSearch::pStruct() const
{
return particles_.pStruct();
}
pFlow::uniquePtr<pFlow::contactSearch> pFlow::contactSearch::create(
const dictionary& dict,
const box& domain,
const particles& prtcl,
const geometry& geom,
Timers& timers)
const dictionary &dict,
const box &domain,
const particles &prtcl,
const geometry &geom,
Timers &timers)
{
word baseMethName = dict.getVal<word>("method");

View File

@ -35,6 +35,7 @@ namespace pFlow
class box;
class particles;
class geometry;
class pointStructure;
class contactSearch
@ -97,6 +98,8 @@ public:
return particles_;
}
const pointStructure& pStruct()const;
const auto& Geometry()const
{
return geometry_;

View File

@ -85,10 +85,13 @@ structuredData/pointStructure/selectors/selectBox/selectBox.cpp
structuredData/pointStructure/selectors/selectRange/selectRange.cpp
structuredData/pointStructure/selectors/selectRandom/selectRandom.cpp
triSurface/subSurface.cpp
triSurface/triSurface.cpp
triSurface/multiTriSurface.cpp
containers/pointField/boundaryField/generalBoundary.cpp
containers/pointField/pointFields.cpp
containers/triSurfaceField/triSurfaceFields.cpp

View File

@ -481,12 +481,10 @@ void pFlow::VectorSingle<T,MemorySpace>::assign
}
else if constexpr( isHostAccessible_)
{
for(auto i=0u; i<srcSize; i++)
{
view_[i] = src[i];
}
}
else
{
@ -518,7 +516,7 @@ void pFlow::VectorSingle<T,MemorySpace>::assignFromHost(const VectorTypeHost& sr
}
else
{
setSize(srcSize);
changeSize(srcSize);
}
if constexpr(isTriviallyCopyable_)

View File

@ -289,6 +289,33 @@ public:
INLINE_FUNCTION_H
void assign(const VectorType& src, bool srcCapacity = true);
/*template<typename MSpace,
std::enable_if_t<
!std::is_same_v<typename VectorSingle<T, MSpace>::memory_space, memory_space>,
bool> = true>*/
template<typename MSpace>
INLINE_FUNCTION_H
void assignFromDevice(const VectorSingle<T, MSpace>& src, bool srcCapacity = true)
{
uint32 srcSize = src.size();
uint32 srcCap = src.capacity();
if(srcCapacity && srcCap != capacity()){
reallocateCapacitySize(srcCap, srcSize);
}
else {
changeSize(srcSize);
}
if constexpr(isTriviallyCopyable_){
copy(deviceView(), src.deviceView());
}
else{
static_assert("Not a valid operation for this data type ");
}
}
INLINE_FUNCTION_H
void append(const std::vector<T>& appVec);

View File

@ -22,11 +22,17 @@ template<class T, class MemorySpace>
pFlow::boundaryField<T, MemorySpace>::boundaryField
(
const boundaryBase& boundary,
const pointStructure& pStruct,
InternalFieldType& internal
)
:
observer(&boundary, defaultMessage_),
boundary_(boundary),
generalBoundary
(
boundary,
pStruct,
getTypeName<T>(),
memory_space::name()
),
internal_(internal)
{}
@ -36,15 +42,26 @@ pFlow::uniquePtr<pFlow::boundaryField<T, MemorySpace>>
pFlow::boundaryField<T, MemorySpace>::create
(
const boundaryBase& boundary,
const pointStructure& pStruct,
InternalFieldType& internal
)
{
word bType = angleBracketsNames("boundaryField", boundary.type());
word bType = angleBracketsNames3(
"boundaryField",
boundary.type(),
getTypeName<T>(),
memory_space::name());
word bTypeAlter = angleBracketsNames3(
"boundaryField",
"none",
getTypeName<T>(),
memory_space::name());
if(boundaryBasevCtorSelector_.search(bType))
{
return boundaryBasevCtorSelector_[bType](boundary, internal);
return boundaryBasevCtorSelector_[bType](boundary, pStruct, internal);
}
else
{

View File

@ -20,8 +20,7 @@ Licence:
#ifndef __boundaryField_hpp__
#define __boundaryField_hpp__
#include "observer.hpp"
#include "boundaryBase.hpp"
#include "generalBoundary.hpp"
#include "internalField.hpp"
namespace pFlow
@ -30,7 +29,7 @@ namespace pFlow
template< class T, class MemorySpace = void>
class boundaryField
:
public observer
public generalBoundary
{
public:
@ -44,23 +43,17 @@ public:
protected:
const boundaryBase& boundary_;
/// @brief a ref to the internal field
InternalFieldType& internal_;
static inline
const message defaultMessage_ =
(
message::BNDR_RESET
);
public:
TypeInfo("boundaryField<none>");
TypeInfoTemplate211("boundaryField","none" ,T, memory_space::name());
boundaryField(
const boundaryBase& boundary,
const pointStructure& pStruct,
InternalFieldType& internal);
create_vCtor
@ -69,9 +62,10 @@ public:
boundaryBase,
(
const boundaryBase& boundary,
const pointStructure& pStruct,
InternalFieldType& internal
),
(boundary, internal)
(boundary, pStruct, internal)
);
@ -104,25 +98,21 @@ public:
return true;
}
auto size()const
void fill(const std::any& val)override
{
return boundary_.size();
}
auto capacity()const
{
return boundary_.capacity();
return;
}
virtual
void fill(const T& val)
{
return ;
return;
}
static
uniquePtr<boundaryField> create(
const boundaryBase& boundary,
const pointStructure& pStruct,
InternalFieldType& internal);
};

View File

@ -22,10 +22,11 @@ template<class T, class MemorySpace>
pFlow::exitBoundaryField<T, MemorySpace>::exitBoundaryField
(
const boundaryBase& boundary,
const pointStructure& pStruct,
InternalFieldType& internal
)
:
BoundaryFieldType(boundary, internal)
BoundaryFieldType(boundary, pStruct, internal)
{
this->addEvent(message::BNDR_DELETE);
}

View File

@ -46,10 +46,11 @@ public:
public:
TypeInfo("boundaryField<exit>");
TypeInfoTemplate211("boundaryField","exit", T, memory_space::name());
exitBoundaryField(
const boundaryBase& boundary,
const pointStructure& pStruct,
InternalFieldType& internal);

View File

@ -0,0 +1,21 @@
#include "generalBoundary.hpp"
#include "pointStructure.hpp"
pFlow::generalBoundary::generalBoundary
(
const boundaryBase& boundary,
const pointStructure& pStruct,
const word& dataType,
const word& option
)
:
observer(&boundary, defaultMessage_),
boundary_(boundary),
pStruct_(pStruct)
{}
pFlow::Time const& pFlow::generalBoundary::time() const
{
return pStruct_.time();
}

View File

@ -0,0 +1,143 @@
/*------------------------------- phasicFlow ---------------------------------
O C enter of
O O E ngineering and
O O M ultiscale modeling of
OOOOOOO F luid flow
------------------------------------------------------------------------------
Copyright (C): www.cemf.ir
email: hamid.r.norouzi AT gmail.com
------------------------------------------------------------------------------
Licence:
This file is part of phasicFlow code. It is a free software for simulating
granular and multiphase flows. You can redistribute it and/or modify it under
the terms of GNU General Public License v3 or any other later versions.
phasicFlow is distributed to help others in their research in the field of
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------------------------------------------------------------*/
#ifndef __generalBoundary_hpp__
#define __generalBoundary_hpp__
// from STL
#include <any>
// from phasicFlow
#include "types.hpp"
#include "observer.hpp"
#include "boundaryBase.hpp"
namespace pFlow
{
//- forward
class pointStructure;
class Time;
class generalBoundary
:
public observer
{
private:
const boundaryBase& boundary_;
const pointStructure& pStruct_;
static inline
const message defaultMessage_{message::BNDR_RESET};
template<typename BoundaryFieldType>
inline
bool checkForType()const
{
return typeName() == BoundaryFieldType::TYPENAME();
}
public:
TypeInfo("generalBoundary");
generalBoundary(
const boundaryBase& boundary,
const pointStructure& pStruct,
const word& dataType,
const word& option);
~generalBoundary()override = default;
inline
uint32 thisBoundaryIndex()const
{
return boundary_.thisBoundaryIndex();
}
inline
uint32 mirrorBoundaryindex()const
{
return boundary_.mirrorBoundaryIndex();
}
inline
auto size()const
{
return boundary_.size();
}
inline
auto capacity()const
{
return boundary_.capacity();
}
inline
const auto& boundary()const
{
return boundary_;
}
inline
const word& name()const
{
return boundary_.name();
}
inline
const word& type()const
{
return boundary_.type();
}
inline
const auto& pStruct()const
{
return pStruct_;
}
const Time& time()const;
virtual
void fill(const std::any& val)=0;
template<typename BoundaryFieldType>
BoundaryFieldType& thisField()
{
return static_cast<BoundaryFieldType&>(*this);
}
template<typename BoundaryFieldType>
const BoundaryFieldType& thisField()const
{
return static_cast<const BoundaryFieldType&>(*this);
}
};
} // pFlow
#endif

View File

@ -22,10 +22,11 @@ template<class T, class MemorySpace>
pFlow::periodicBoundaryField<T, MemorySpace>::periodicBoundaryField
(
const boundaryBase& boundary,
const pointStructure& pStruct,
InternalFieldType& internal
)
:
BoundaryFieldType(boundary, internal)
BoundaryFieldType(boundary, pStruct, internal)
{
this->addEvent(message::BNDR_APPEND)
.addEvent(message::BNDR_TRANSFER);

View File

@ -46,10 +46,11 @@ public:
public:
TypeInfo("boundaryField<periodic>");
TypeInfoTemplate211("boundaryField","periodic", T, memory_space::name());
periodicBoundaryField(
const boundaryBase& boundary,
const pointStructure& pStruct,
InternalFieldType& internal);

View File

@ -55,7 +55,7 @@ public:
this->set
(
i,
BoundaryFieldType::create(boundaries_[i], internal)
BoundaryFieldType::create(boundaries_[i], boundaries_.pStruct() ,internal)
);
}
}

View File

@ -26,6 +26,11 @@ Licence:
#include "Time.hpp"
#include "boundaryBaseKernels.hpp"
void pFlow::boundaryBase::setSize(uint32 newSize)
{
indexList_.resize(newSize);
unSyncLists();
}
void pFlow::boundaryBase::setNewIndices
(
@ -33,6 +38,7 @@ void pFlow::boundaryBase::setNewIndices
)
{
indexList_.assign(newIndices, false);
unSyncLists();
}
bool pFlow::boundaryBase::appendNewIndices
@ -42,6 +48,7 @@ bool pFlow::boundaryBase::appendNewIndices
{
indexList_.append(newIndices);
unSyncLists();
message msg;
@ -177,7 +184,8 @@ pFlow::boundaryBase::boundaryBase
:
subscriber(dict.name()),
boundaryPlane_(bplane),
indexList_(groupNames(dict.name(), "indexList")),
indexList_(groupNames("indexList", dict.name())),
indexListHost_(groupNames("hostIndexList",dict.name())),
neighborLength_(dict.getVal<real>("neighborLength")),
internal_(internal),
boundaries_(bndrs),
@ -186,6 +194,7 @@ pFlow::boundaryBase::boundaryBase
name_(dict.name()),
type_(dict.getVal<word>("type"))
{
unSyncLists();
}
pFlow::boundaryBase &pFlow::boundaryBase::mirrorBoundary()
@ -193,10 +202,9 @@ pFlow::boundaryBase &pFlow::boundaryBase::mirrorBoundary()
return boundaries_[mirrorBoundaryIndex()];
}
void pFlow::boundaryBase::setSize(uint32 newSize)
const pFlow::boundaryBase &pFlow::boundaryBase::mirrorBoundary() const
{
indexList_.resize(newSize);
return boundaries_[mirrorBoundaryIndex()];
}
typename pFlow::boundaryBase::pointFieldAccessType
@ -219,6 +227,15 @@ typename pFlow::boundaryBase::pointFieldAccessType
return pointFieldAccessType();
}
pFlow::realx3 pFlow::boundaryBase::displacementVectroToMirror() const
{
const plane& thisP = boundaryPlane();
const plane& mirrorP = mirrorBoundary().boundaryPlane();
return thisP.normal()*(thisP.d() + mirrorP.d());
}
pFlow::uniquePtr<pFlow::boundaryBase> pFlow::boundaryBase::create
(
const dictionary &dict,

View File

@ -49,15 +49,24 @@ public:
private:
// friend et al.
friend boundaryList;
const plane& boundaryPlane_;
/// list of particles indices on device
uint32Vector_D indexList_;
/// list of particles indieces on host
mutable uint32Vector_H indexListHost_;
/// device and host list are sync
mutable bool listsSync_ = false;
/// The length defined for creating neighbor list
real neighborLength_;
/// a reference to
/// a reference to internal points
internalPoints& internal_;
/// a reference to the list of boundaries
@ -74,6 +83,9 @@ private:
protected:
/// @brief set the size of indexList
void setSize(uint32 newSize);
void setNewIndices(const uint32Vector_D& newIndices);
bool appendNewIndices(const uint32Vector_D& newIndices);
@ -88,11 +100,25 @@ protected:
uint32 transferBoundaryIndex,
realx3 transferVector);
void unSyncLists()
{
listsSync_ = false;
}
void syncLists()const
{
if(!listsSync_)
{
indexListHost_.assignFromDevice(indexList_, true);
listsSync_ = true;
}
}
public:
TypeInfo("boundaryBase");
boundaryBase(
const dictionary &dict,
const plane &bplane,
@ -137,49 +163,36 @@ public:
return {0,0,0};
}
inline
const word& type()const
{
return type_;
}
inline
const word& name()const
{
return name_;
}
inline
bool empty()const
{
return indexList_.size()==0;
}
inline
auto size()const
{
return indexList_.size();
}
virtual
const plane& boundaryPlane()const
{
return boundaryPlane_;
}
inline
auto capacity()const
{
return indexList_.capacity();
}
const internalPoints& internal()const
{
return internal_;
}
internalPoints& internal()
{
return internal_;
}
boundaryBase& mirrorBoundary();
inline
uint32 thisBoundaryIndex()const
{
@ -192,9 +205,48 @@ public:
return thisBoundaryIndex_%2==0? thisBoundaryIndex_+1:thisBoundaryIndex_-1;
}
/// @brief set the size of indexList
/// Always make sure that size+1 <= capacity
void setSize(uint32 newSize);
inline
const internalPoints& internal()const
{
return internal_;
}
inline
internalPoints& internal()
{
return internal_;
}
inline
const auto& indexList()const
{
return indexList_;
}
inline
const auto& indexListHost()const
{
syncLists();
return indexListHost_;
}
boundaryBase& mirrorBoundary();
const boundaryBase& mirrorBoundary()const;
virtual
const plane& boundaryPlane()const
{
return boundaryPlane_;
}
/// @brief displacement vector that transfers points from
/// to a distance that is equal to the distance between
/// this plane and the mirror plane, the vector points from
/// this plane to mirror plane
virtual
realx3 displacementVectroToMirror()const;
virtual
bool beforeIteration(uint32 iterNum, real t, real dt) = 0 ;
@ -205,18 +257,12 @@ public:
virtual
bool afterIteration(uint32 iterNum, real t, real dt) = 0;
const auto& indexList()const
{
return indexList_;
}
pointFieldAccessType thisPoints();
virtual
pointFieldAccessType neighborPoints();
/// - static create
static
uniquePtr<boundaryBase> create
(

View File

@ -70,6 +70,11 @@ public:
bool setLists();
const pointStructure& pStruct()const
{
return pStruct_;
}
auto& boundary(size_t i)
{
return ListPtr<boundaryBase>::operator[](i);

View File

@ -95,9 +95,7 @@ bool pFlow::boundaryPeriodic::beforeIteration(
}
// to obtain the transfer vector
const auto& thisP = boundaryPlane();
const auto& mirrorP = mirrorBoundary().boundaryPlane();
realx3 transferVec = thisP.normal()*(thisP.d() + mirrorP.d());
realx3 transferVec = displacementVectroToMirror();
return transferPoints
(

View File

@ -64,7 +64,7 @@ namespace pFlow
{
int status;
auto& ti = typeid(T);
char* realname = abi::__cxa_demangle(ti.name(), 0, 0, &status);
char* realname = abi::__cxa_demangle(ti.name(), nullptr, nullptr, &status);
word name(realname);
free(realname);
return name;
@ -107,6 +107,7 @@ namespace pFlow
return basicTypeName<T>();
}
}
template<typename T>
word constexpr getTypeName(const T&)
{
@ -189,87 +190,12 @@ namespace pFlow
virtual word typeName() const { return TYPENAME();}
/*#define TypeInfoTemplate11(tName, Type) \
has_static_member(TYPENAME); \
#define TypeInfoTemplate211(tBase,tName1, Type, tName3) \
inline static word TYPENAME() \
{ \
if constexpr( has_static_member_TYPENAME<Type,word(void)>::value) \
{ return word(tName)+"<"+Type::TYPENAME()+">";} \
else \
return word(tName)+"<"+basicTypeName<Type>()+">"; \
return "noTYPE"; \
return word(tBase)+"<"+word(tName1)+","+getTypeName<Type>()+","+word(tName3)+">"; \
} \
virtual word typeName() const { return TYPENAME();}
#define TypeInfoTemplate12(tName, Type1, Type2) \
has_static_member(TYPENAME); \
inline static word TYPENAME() \
{ \
if constexpr( has_static_member_TYPENAME<Type1,word(void)>::value) \
{ return word(tName)+"<"+Type1::TYPENAME()+","+Type2::TYPENAME()+">";} \
else \
return word(tName)+"<"+basicTypeName<Type1>()+","+Type2::TYPENAME()+">";\
return "noTYPE"; \
} \
virtual word typeName() const { return TYPENAME();}
#define TypeInfoTemplate13(tName, Type1, Type2, Type3) \
inline static word TYPENAME() \
{ \
return word(tName)+"<"+Type1::TYPENAME()+","+Type2::TYPENAME()+","+Type3::TYPENAME()+">";\
} \
virtual word typeName() const { return TYPENAME();}
// this is the non-virtual version
#define TypeInfoTemplateNV11(tName, Type) \
has_static_member(TYPENAME); \
inline static word TYPENAME() \
{ \
if constexpr( has_static_member_TYPENAME<Type,word(void)>::value) \
{ return word(tName)+"<"+Type::TYPENAME()+">";} \
else \
return word(tName)+"<"+basicTypeName<Type>()+">"; \
return "noTYPE"; \
} \
inline word typeName() const { return TYPENAME();}
#define TypeInfoTemplateNV111(tName, Type, tName2) \
has_static_member(TYPENAME); \
inline static word TYPENAME() \
{ \
if constexpr ( has_static_member_TYPENAME<Type,word(void)>::value) \
{ return word(tName)+"<"+Type::TYPENAME()+","+word(tName2)+">";} \
else \
return word(tName)+"<"+basicTypeName<Type>()+","+word(tName2)+">"; \
return "noTYPE"; \
} \
inline word typeName() const { return TYPENAME();}
#define TypeInfoTemplate111(tName, Type, tName2) \
has_static_member(TYPENAME); \
inline static word TYPENAME() \
{ \
if constexpr ( has_static_member_TYPENAME<Type,word(void)>::value) \
{ return word(tName)+"<"+Type::TYPENAME()+","+word(tName2)+">";} \
else \
return word(tName)+"<"+basicTypeName<Type>()+","+word(tName2)+">"; \
return "noTYPE"; \
} \
virtual word typeName() const { return TYPENAME();}*/
namespace pFlow
{
} // pFlow
#endif