diff --git a/src/phasicFlow/CMakeLists.txt b/src/phasicFlow/CMakeLists.txt index 4f138123..eb52ef39 100644 --- a/src/phasicFlow/CMakeLists.txt +++ b/src/phasicFlow/CMakeLists.txt @@ -20,7 +20,8 @@ streams/TStream/oTstream.cpp streams/Fstream/iFstream.cpp streams/Fstream/oFstream.cpp streams/Fstream/fileStream.cpp -streams/dataIO/dataIO.cpp +streams/dataIO/dataIO.cpp +streams/dataIO/dataIONoMPI.cpp streams/streams.cpp fileSystem/fileSystem.cpp @@ -34,15 +35,22 @@ dictionary/twoPartEntry/twoPartEntry.cpp containers/Vector/Vectors.cpp containers/Field/Fields.cpp +containers/List/anyList/anyList.cpp repository/IOobject/objectFile.cpp repository/IOobject/IOfileHeader.cpp repository/IOobject/IOobject.cpp repository/IOobject/IOPattern.cpp +eventManagement/subscriber.cpp +eventManagement/observer.cpp + structuredData/line/line.cpp structuredData/infinitePlane/infinitePlane.cpp structuredData/plane/plane.cpp +structuredData/domain/domain.cpp +structuredData/pointStructure/internalPoints.cpp +structuredData/boundaries/boundaryBase/boundaryBase.cpp ) diff --git a/src/phasicFlow/containers/Field/Field.cpp b/src/phasicFlow/containers/Field/Field.cpp index 70e33dfd..4f895a98 100644 --- a/src/phasicFlow/containers/Field/Field.cpp +++ b/src/phasicFlow/containers/Field/Field.cpp @@ -216,10 +216,14 @@ bool pFlow::Field::write( IOPattern::IOType iotype)const { - os.writeWordKeyword(fieldKey_)< + bool write( + iOstream& os, + IOPattern::IOType iotype, + const HostMask& mask)const + { + + os.writeWordKeyword(fieldKey_)< class VectorField, class T, class PropType> inline iIstream& operator >> (iIstream & is, Field & ifld ) { - if( !ifld.read(is, IOPattern::MasterProcessor) ) + if( !ifld.read(is, IOPattern::MasterProcessorOnly) ) { ioErrorInFile (is.name(), is.lineNumber()); fatalExit; diff --git a/src/phasicFlow/containers/Field/Fields.hpp b/src/phasicFlow/containers/Field/Fields.hpp index 2a4b0ca0..411bedf7 100644 --- a/src/phasicFlow/containers/Field/Fields.hpp +++ b/src/phasicFlow/containers/Field/Fields.hpp @@ -34,7 +34,7 @@ using int8Field_D = Field; using int8Field_H = Field; -/*using int32Field_D = Field; +using int32Field_D = Field; using int32Field_H = Field; @@ -42,13 +42,17 @@ using int64Field_D = Field; using int64Field_H = Field; +using uint8Field_D = Field; + +using uint8Field_H = Field; + using uint32Field_D = Field; using uint32Field_H = Field; -using labelField_D = Field; +using uint64Field_D = Field; -using labelField_H = Field ; +using uint64Field_H = Field ; using realField_D = Field; @@ -58,25 +62,9 @@ using realx3Field_D = Field; using realx3Field_H = Field; -using uint16x3Field_D = Field; - -using uint16x3Field_H = Field; - -using uint32x3Field_D = Field; - -using uint32x3Field_H = Field; - -using int32x3Field_D = Field; - -using int32x3Field_H = Field; - -using int64x3Field_D = Field; - -using int64x3Field_H = Field; - using realx3x3Field_D = Field; -using realx3x3Field_H = Field;*/ +using realx3x3Field_H = Field; // - no typedef on device (since word does not compile on CUDA) using wordField_H = Field; diff --git a/src/phasicFlow/containers/List/List/List.hpp b/src/phasicFlow/containers/List/List/List.hpp index f20bfaff..a11d34fd 100644 --- a/src/phasicFlow/containers/List/List/List.hpp +++ b/src/phasicFlow/containers/List/List/List.hpp @@ -49,11 +49,11 @@ public: using iterator = typename listType::iterator; - using constIterator = typename listType::const_iterator; + using const_iterator = typename listType::const_iterator; using reference = typename listType::reference; - using constReference= typename listType::const_reference; + using const_reference= typename listType::const_reference; using initList = typename std::initializer_list; @@ -62,12 +62,7 @@ public: protected: - // position of ith element - auto pos(size_t i); - - // position of ith element - const auto pos(size_t i)const; - + static inline size_t getListStride(const size_t& len) { size_t stride = 1; @@ -114,30 +109,19 @@ public: // - copy construct - List(const List& src): - listType(src) - {} + List(const List& src) = default; + // - move construct - List( List && mv) - : - listType(std::move(mv)) - {} - + List( List && mv) = default; + // - copy assignment - ListType& operator=(const ListType& rhs) - { - listType::operator=(rhs); - return *this; - } + ListType& operator=(const ListType& rhs) = default; + // - move assignment - ListType& operator=(ListType&& rhs) - { - listType::operator=(std::move(rhs)); - return *this; - } - + ListType& operator=(ListType&& rhs) = default; + uniquePtr clone()const{ return makeUnique(*this); @@ -162,6 +146,12 @@ public: // - size of container size_t size()const; + // position of ith element + auto pos(size_t i, bool noError = false); + + // position of ith element + const auto pos(size_t i, bool noError = false)const; + // - access to ith element // fatal exit if out of range T& operator[](size_t i); @@ -172,7 +162,7 @@ public: // - find the position of the first element with value val // cend() if not found - constIterator find(const T& val) const; + const_iterator find(const T& val) const; // - find the position of the first element with value val // end() if not found diff --git a/src/phasicFlow/containers/List/List/ListI.hpp b/src/phasicFlow/containers/List/List/ListI.hpp index 60caf3b2..c46d3efa 100644 --- a/src/phasicFlow/containers/List/List/ListI.hpp +++ b/src/phasicFlow/containers/List/List/ListI.hpp @@ -21,14 +21,22 @@ Licence: template auto pFlow::List::pos ( - size_t i + size_t i, + bool noError ) { if( i >= size() ) { - fatalErrorInFunction<< - "our of range access to list element. \n"; - fatalExit; + if(noError) + { + return std::end(*this); + } + else + { + fatalErrorInFunction<< + "out of range access to list element. \n"; + fatalExit; + } } auto iter = listType::begin(); std::advance(iter, i); @@ -38,14 +46,22 @@ auto pFlow::List::pos template const auto pFlow::List::pos ( - size_t i + size_t i, + bool noError )const { if( i >= size() ) { - fatalErrorInFunction<< - "our of range access to list element. \n"; - fatalExit; + if(noError) + { + return std::end(*this); + } + else + { + fatalErrorInFunction<< + "out of range access to list element. \n"; + fatalExit; + } } auto iter = listType::cbegin(); std::advance(iter, i); @@ -88,7 +104,7 @@ inline const T& pFlow::List::operator[] } template -inline typename pFlow::List::constIterator pFlow::List::find +inline typename pFlow::List::const_iterator pFlow::List::find ( const T& val ) const diff --git a/src/phasicFlow/containers/List/anyList/anyList.cpp b/src/phasicFlow/containers/List/anyList/anyList.cpp new file mode 100644 index 00000000..c66ad975 --- /dev/null +++ b/src/phasicFlow/containers/List/anyList/anyList.cpp @@ -0,0 +1,43 @@ +/*------------------------------- 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. + +-----------------------------------------------------------------------------*/ + + +#include "anyList.hpp" + + +size_t pFlow::anyList::size()const +{ + return anyList_.size(); +} + +bool pFlow::anyList::empty()const +{ + return size()==0; +} + +bool pFlow::anyList::contains(const word& name)const +{ + return names_.search(name); +} + +const pFlow::wordList& pFlow::anyList::names()const +{ + return names_; +} diff --git a/src/phasicFlow/containers/List/anyList/anyList.hpp b/src/phasicFlow/containers/List/anyList/anyList.hpp new file mode 100644 index 00000000..9ed114b1 --- /dev/null +++ b/src/phasicFlow/containers/List/anyList/anyList.hpp @@ -0,0 +1,243 @@ +/*------------------------------- 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 __anyList_hpp__ +#define __anyList_hpp__ + +#include + +#include "types.hpp" +#include "List.hpp" + + +namespace pFlow +{ + + +class anyList +{ + +public: + + using anyListType = List; + + using reference = typename anyListType::reference; + + using iterator = typename anyListType::iterator; + + using const_iterator= typename anyListType::const_iterator; + + +protected: + + /// Contains a list of variables with any type + anyListType anyList_; + + /// List of variable names in anyList_ + wordList names_; + +public: + + // - Type info + TypeInfoNV("anyList"); + + //// - Constructors + + // All five constructors are created by compiler + + + //// - Methods + + /// Size of container + size_t size()const; + + /// Is container empty + bool empty()const; + + /// Does container contain this variable name? + bool contains(const word& name)const; + + /// List of varibales names + const wordList& names()const; + + /// Create variable using constructor in-place + template + reference emplaceBack(const word& name, Args&&... args) + { + if( contains(name)) + { + fatalErrorInFunction<< + "variable name "<< name << " already exists in the anyList."<, + std::forward(args)...); + } + + /// Create variable using copy constructor + template + reference emplaceBack(const word& name, const T & other) + { + if( contains(name) ) + { + fatalErrorInFunction<< + "variable name "<< name << " already exists in the anyList."<, other); + } + + /// Create variable using move constructor + template + reference emplaceBack(const word& name, T&& other) + { + if( contains(name) ) + { + fatalErrorInFunction<< + "variable name "<< name << " already exists in the anyList."<, std::move(other)); + } + + /// Get the reference to variable by index + template + T& getObject(size_t i) + { + std::any *a = &(*anyList_.pos(i)); + if(!a->has_value()) + { + fatalErrorInFunction<< + "any does not have a value for dereferencing. "<< + "index in anyList is "<(a); + } + + /// Get the reference to variable by name + template + T& getObject(const word& name) + { + int32 i = names_.findi(name); + if(i == -1 ) + { + fatalErrorInFunction<< + "variable name "<< name << " does not exist in the anyList."<has_value()) + { + fatalErrorInFunction<< + "any does not have a value for dereferencing. "<< + "index in anyList is "<(a); + } + + /// Get the const reference to variable by name + template + const T& getObject(const word& name)const + { + int32 i = names_.findi(name); + if(i == -1 ) + { + fatalErrorInFunction<< + "variable name "<< name << " does not exist in the anyList."<has_value()) + { + fatalErrorInFunction<< + "any does not have a value for dereferencing. "<< + "index in anyList is "<(a); + } + + /// Get the const reference to object by index + template + const T& getObject(size_t i)const + { + const std::any *a = &(*anyList_.pos(i)); + if(!a->has_value()) + { + fatalErrorInFunction<< + "any does not have a value for dereferencing. "<< + "index in anyList is "<(a); + } + + /// Get the pointer to variable by index + template + T* getObjectPtr(size_t i) + { + if(i>= size())return nullptr; + + std::any *a = &(*anyList_.pos(i)); + if( a->has_value()) + { + return std::any_cast(a); + } + else + { + return nullptr; + } + } + + /// Get the const pointer to variable by index + template + const T* getObjectPtr(size_t i)const + { + if(i>=size())return nullptr; + const std::any *a = &(*anyList_.pos(i)); + if( a->has_value()) + { + return std::any_cast(a); + } + else + { + return nullptr; + } + } + +}; + + + +} // pFlow + + +#endif //__anyList_hpp__ diff --git a/src/phasicFlow/containers/Vector/Vector.hpp b/src/phasicFlow/containers/Vector/Vector.hpp index 3377efdc..b025a148 100644 --- a/src/phasicFlow/containers/Vector/Vector.hpp +++ b/src/phasicFlow/containers/Vector/Vector.hpp @@ -364,7 +364,7 @@ public: template inline iIstream& operator >> (iIstream & is, Vector & ivec ) { - if( !ivec.readVector(is, IOPattern::MasterProcessor) ) + if( !ivec.readVector(is, IOPattern::MasterProcessorOnly) ) { ioErrorInFile (is.name(), is.lineNumber()); fatalExit; diff --git a/src/phasicFlow/containers/Vector/stdVectorHelper.hpp b/src/phasicFlow/containers/Vector/stdVectorHelper.hpp index 7ffbfaf8..9c67a4ce 100644 --- a/src/phasicFlow/containers/Vector/stdVectorHelper.hpp +++ b/src/phasicFlow/containers/Vector/stdVectorHelper.hpp @@ -57,9 +57,15 @@ bool writeSpan( IOPattern::IOType iotype) { - dataIO io(iotype); + auto ioPtr = dataIO::create(iotype, IOPattern::exeMode()); - if(!io.writeData(os, sp)) + if(!ioPtr) + { + fatalErrorInFunction; + return false; + } + + if(!ioPtr().writeData(os, sp)) { fatalErrorInFunction; return false; @@ -92,9 +98,15 @@ bool readStdVector IOPattern::IOType iotype ) { - dataIO io(iotype); + auto ioPtr = dataIO::create(iotype, IOPattern::exeMode()); - if(!io.readData(is, vec)) + if(!ioPtr) + { + fatalErrorInFunction; + return false; + } + + if(!ioPtr().readData(is, vec)) { fatalErrorInFunction; return false; @@ -118,7 +130,7 @@ iOstream& operator<<( iOstream& os, const std::vector& vec) template iIstream& operator>>(iIstream& is, std::vector& vec) { - if( !readStdVector(is,vec, IOPattern::MasterProcessor)) + if( !readStdVector(is,vec, IOPattern::MasterProcessorOnly)) { fatalErrorInFunction; fatalExit; diff --git a/src/phasicFlow/containers/VectorHD/VectorSingle.hpp b/src/phasicFlow/containers/VectorHD/VectorSingle.hpp index 2fa36459..46b461b3 100644 --- a/src/phasicFlow/containers/VectorHD/VectorSingle.hpp +++ b/src/phasicFlow/containers/VectorHD/VectorSingle.hpp @@ -599,12 +599,38 @@ public: } + template + FUNCTION_H + bool write(iOstream& os, IOPattern::IOType iotype, const HostMask& mask)const + { + auto hVec = hostVector(); + + auto numActive = mask.numActive(); + std::vector finalField; + finalField.clear(); + finalField.reserve(numActive); + + uint32 start = mask.activeRange().start(); + uint32 end = mask.activeRange().end(); + + for(uint32 i=start; i( finalField.data(), finalField.size()); + + return writeSpan(os, sp, iotype); + + } + }; // class VectorSingle template inline iIstream& operator >> (iIstream & is, VectorSingle & ivec ) { - if( !ivec.read(is, IOPattern::MasterProcessor ) ) + if( !ivec.read(is, IOPattern::MasterProcessorOnly ) ) { ioErrorInFile (is.name(), is.lineNumber()); fatalExit; diff --git a/src/phasicFlow/containers/span/span.hpp b/src/phasicFlow/containers/span/span.hpp index 094ffe1d..8947c039 100644 --- a/src/phasicFlow/containers/span/span.hpp +++ b/src/phasicFlow/containers/span/span.hpp @@ -77,11 +77,11 @@ public: /// move INLINE_FUNCTION_HD - span(span&&) = delete; + span(span&&) = default; /// assignment INLINE_FUNCTION_HD - span& operator=(span&) = delete; + span& operator=(span&) = default; INLINE_FUNCTION_HD diff --git a/src/phasicFlow/eventManagement/message.hpp b/src/phasicFlow/eventManagement/message.hpp new file mode 100644 index 00000000..bf2d2f9a --- /dev/null +++ b/src/phasicFlow/eventManagement/message.hpp @@ -0,0 +1,159 @@ +/*------------------------------- 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 __message_hpp__ +#define __message_hpp__ + +#include + +#include "types.hpp" +#include "iOstream.hpp" + + +namespace pFlow +{ + +class message +{ +public: + enum EVENT : size_t + { + DEFAULT = 0, + CAP_CHANGED = 1, + SIZE_CHANGED = 2, + ITEM_DELETE = 3, + ITEM_INSERT = 4, + RANGE_CHANGED = 5, + ITEM_REARRANGE = 6 + }; + +protected: + + std::bitset<16> events_{0x0000}; + + +public: + + message()=default; + + message(EVENT evnt) + { + add(evnt); + } + + message(size_t i ) + { + if(i<16) + { + events_.set(i); + } + } + + message(const message&) = default; + + message(message&&) = default; + + message& operator=(const message&) = default; + + message& operator=(message&&) = default; + + ~message()=default; + + inline message& add( EVENT evnt) + { + events_.set(static_cast(evnt)); + return *this; + } + + inline message& remove(EVENT evnt) + { + events_.set(static_cast(evnt), false); + return *this; + } + + inline bool equivalentTo( EVENT evnt )const + { + return equivalentTo(static_cast(evnt)); + } + + inline bool equivalentTo(size_t i)const + { + return events_.test(i); + } + + inline bool isNull()const + { + return events_.none(); + } + + inline auto size()const + { + return events_.size(); + } + + inline + message& operator+(EVENT evnt) + { + return add(evnt); + } + + inline + message& operator-(EVENT evnt) + { + return remove(evnt); + } + + static + message Default() + { + message msg; + return msg+DEFAULT; + } + + static + message Empty() + { + message msg; + return msg; + } + +}; + +inline +iOstream& operator<<(iOstream& os, const message& msg) +{ + for(size_t i=msg.size(); i>0; i--) + { + os<< msg.equivalentTo(i-1)? '1':0; + } + os<subscribe(msg, this)) + { + fatalErrorInFunction<< + "error in subscribing an observer"<unsubscribe(this); + invalidateSubscriber(); +} + +bool pFlow::observer::addToSubscriber(const subscriber& subscrbr) +{ + subscriber_ = &subscrbr; + return subscriber_->subscribe(message_, this); +} \ No newline at end of file diff --git a/src/phasicFlow/eventManagement/observer.hpp b/src/phasicFlow/eventManagement/observer.hpp new file mode 100644 index 00000000..c5433f3b --- /dev/null +++ b/src/phasicFlow/eventManagement/observer.hpp @@ -0,0 +1,76 @@ +/*------------------------------- 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 __observer_hpp__ +#define __observer_hpp__ + +#include "message.hpp" + +namespace pFlow +{ + +class subscriber; +class anyList; + +class observer +{ +protected: + + + /// pointer to subscriber + const subscriber* subscriber_ = nullptr; + + /// list of events in the message + const message message_; + + +public: + + observer(); + + observer( + const subscriber* subscrbr, + message msg); + + virtual + ~observer(); + + inline + bool subscribed()const + { + return subscriber_!=nullptr; + } + + bool addToSubscriber(const subscriber& subscriber); + + inline void invalidateSubscriber() + { + subscriber_ = nullptr; + } + + + virtual bool update(const message& msg, const anyList& varList)=0; +}; + +} // pFlow + + +#endif // __observer_hpp__ diff --git a/src/phasicFlow/eventManagement/subscriber.cpp b/src/phasicFlow/eventManagement/subscriber.cpp new file mode 100644 index 00000000..9cb2dfcc --- /dev/null +++ b/src/phasicFlow/eventManagement/subscriber.cpp @@ -0,0 +1,147 @@ +/*------------------------------- 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. + +-----------------------------------------------------------------------------*/ + + +#include "subscriber.hpp" +#include "anyList.hpp" +#include "observer.hpp" +#include "message.hpp" + + +pFlow::subscriber::~subscriber() +{ + for(size_t i=0; iinvalidateSubscriber(); + } + } + } +} + +bool pFlow::subscriber::subscribe +( + message msg, + observer* obsevr +)const +{ + if( msg.size()>16 ) + { + fatalErrorInFunction<< + "message size is greater than 16!"<invalidateSubscriber(); + observerList_[i].erase(iter); + } + } + } + return true; +} + +bool pFlow::subscriber::notify +( + const message msg, + const anyList& varList +) +{ + if( msg.size()>16 ) + { + fatalErrorInFunction<< + "message size is greater than 16!"<update(message(i), varList); + } + } + } + + return true; +} + +/*bool pFlow::subscriber::notify +( + const eventMessage &msg +) +{ + for ( auto& observer:observerList_ ) + { + if(observer) + if( !observer->update(msg) ) return false; + } + + return true; +} + +bool pFlow::eventSubscriber::notify +( + const eventMessage& msg, + const List& exclutionList +) +{ + Set 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 new file mode 100644 index 00000000..3c424a3a --- /dev/null +++ b/src/phasicFlow/eventManagement/subscriber.hpp @@ -0,0 +1,68 @@ +/*------------------------------- 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 __subscriber_hpp__ +#define __subscriber_hpp__ + + + +#include + +#include "List.hpp" + +namespace pFlow +{ + +class observer; +class message; +class anyList; + +class subscriber +{ +protected: + + // - list of subsribed objectd that recieve updage messages + mutable std::array,16> observerList_; + +public: + + subscriber() + {} + + virtual ~subscriber(); + + virtual bool subscribe(message msg, observer* obsevr)const; + + virtual bool unsubscribe(observer* obsevr)const; + + //bool notify(const eventMessage& msg); + + //bool notify(const eventMessage& msg, const List& exclutionList ); + + + bool notify(const message msg, const anyList& varList); + + +}; + +} // pFlow + + + +#endif // __eventSubscriber_hpp__ diff --git a/src/phasicFlow/repository/IOobject/IOPattern.cpp b/src/phasicFlow/repository/IOobject/IOPattern.cpp index ffb0eb78..e5264175 100644 --- a/src/phasicFlow/repository/IOobject/IOPattern.cpp +++ b/src/phasicFlow/repository/IOobject/IOPattern.cpp @@ -29,3 +29,10 @@ pFlow::IOPattern::IOPattern( IOType iotype) isParallel_(processors::isParallel()) {} +pFlow::word pFlow::IOPattern::exeMode() +{ + if(processors::isParallel()) + return word("MPI"); + else + return word("NoMPI"); +} \ No newline at end of file diff --git a/src/phasicFlow/repository/IOobject/IOPattern.hpp b/src/phasicFlow/repository/IOobject/IOPattern.hpp index c539aabb..092aae0f 100644 --- a/src/phasicFlow/repository/IOobject/IOPattern.hpp +++ b/src/phasicFlow/repository/IOobject/IOPattern.hpp @@ -22,7 +22,8 @@ Licence: #define __IOPattern_hpp__ -#include "processors.hpp" + +#include "types.hpp" namespace pFlow { @@ -52,7 +53,9 @@ public: { MasterProcessorOnly = 0, AllProcessorsSimilar = 1, - MasterProcessorDistribute = 4 + MasterProcessorDistribute = 4, + AllProcessorsDifferent = 8 // this is used for << and >> operators for + // standard input and output streams }; protected: @@ -95,6 +98,12 @@ public: return ioType_ == MasterProcessorDistribute; } + inline + bool isAllProcessorsDifferent()const + { + return ioType_ == AllProcessorsDifferent; + } + inline bool isMaster()const { @@ -110,7 +119,7 @@ public: inline bool thisProcReadData()const { - if(isMasterProcessor() && !isMaster())return false; + if(isMasterProcessorOnly() && !isMaster())return false; if(isMasterProcessorDistribute() && !isMaster()) return false; return true; } @@ -118,6 +127,7 @@ public: inline bool thisProcWriteData()const { + if(isAllProcessorsDifferent()) return true; return isMaster(); } @@ -145,6 +155,10 @@ public: return globalRank_; } + static + word exeMode(); + + }; } diff --git a/src/phasicFlow/repository/IOobject/objectFile.hpp b/src/phasicFlow/repository/IOobject/objectFile.hpp index 39f9adf8..d6a50eac 100644 --- a/src/phasicFlow/repository/IOobject/objectFile.hpp +++ b/src/phasicFlow/repository/IOobject/objectFile.hpp @@ -66,7 +66,7 @@ protected: /// Number of bytes used for writing/reading real variable (used for binray) int numBytesForReal_ = numBytesForReal__; - IOPattern ioPattern_ = {IOPattern::MasterProcessor}; + IOPattern ioPattern_ = {IOPattern::MasterProcessorOnly}; /// Does the objectFile write the header or not bool readWriteHeader_ = true; @@ -88,7 +88,7 @@ public: const fileSystem& localPath, const readFlag& rf = READ_NEVER, const writeFlag& wf = WRITE_NEVER, - IOPattern::IOType ioType = IOPattern::MasterProcessor, + IOPattern::IOType ioType = IOPattern::MasterProcessorOnly, bool rwHdr = true ); diff --git a/src/phasicFlow/smartPointers/uniquePtr.hpp b/src/phasicFlow/smartPointers/uniquePtr.hpp index 9375d15c..6789e027 100644 --- a/src/phasicFlow/smartPointers/uniquePtr.hpp +++ b/src/phasicFlow/smartPointers/uniquePtr.hpp @@ -54,24 +54,20 @@ public: template - inline static uniquePtr makeUnique(Args&&... args) - { - return uniquePtr(new T(std::forward(args)...)); - } + inline static uniquePtr makeUnique(Args&&... args) + { + return uniquePtr(new T(std::forward(args)...)); + } - void clear() - { - if( ! (*this) ) - { - auto p = this->release(); - delete p; - } - } + void clear() + { + this->reset(nullptr); + } - // ref to the object of type T + // ref to the object of type T T& operator ()() { - if(!this->get()) + if(!*this) { fatalErrorInFunction << "uniquePtr is empty, and you are trying to get its reference. \n" << @@ -84,14 +80,19 @@ public: // const ref to the object of type T const T& operator() () const { - if(!this->get()) + if(!*this) { fatalErrorInFunction << "uniquePtr is empty, and you are trying to get its reference. \n" << "Type name is "<< typeid(T).name()<<"\n"; fatalExit; } - return const_cast(*this->get()); + return static_cast(*this->get()); + } + + explicit operator bool() const + { + return this->get()!= nullptr; } }; diff --git a/src/phasicFlow/streams/dataIO/dataIO.cpp b/src/phasicFlow/streams/dataIO/dataIO.cpp index 4f44f21e..d64fbe59 100644 --- a/src/phasicFlow/streams/dataIO/dataIO.cpp +++ b/src/phasicFlow/streams/dataIO/dataIO.cpp @@ -1,717 +1,34 @@ -#include "phasicFlowConfig.H" -#ifdef pFlow_Build_MPI - #include -#endif - -#include -#include - #include "dataIO.hpp" - -static const size_t numcharFlag = 8; - -static inline unsigned char binaryFlag__[numcharFlag] = {255, 255, 255, 255, 255, 255, 255 ,0}; - -inline -pFlow::uint64 chunkSizeOffeset(pFlow::uint64 procNo) -{ - // 1 is added for number of processors - return (1+procNo)*sizeof(pFlow::uint64); -} - -bool writeBinaryBlockFlagSTD(std::FILE* fh) -{ - - std::size_t nw = std::fwrite( binaryFlag__ , sizeof(unsigned char), numcharFlag, fh ); - - if(nw < numcharFlag) - return false; - else - return true; -} - -pFlow::uint64 findBindaryBlockFlagSTD(std::FILE* fh) -{ - // get the current postion - long fpos; - if( fpos = std::ftell( fh) ; fpos == -1L ) - { - fatalErrorInFunction; - return pFlow::dataIO::ErrorReturn; - } - - pFlow::uint64 filePos = static_cast(fpos); - - // start reading char by char - unsigned char ch; - int currPos = 0; - while ( std::fread(&ch, sizeof(ch), 1, fh) == 1 ) - { - if(std::ferror(fh)) return pFlow::dataIO::ErrorReturn; - if(std::feof(fh))return pFlow::dataIO::ErrorReturn; - - filePos++; - - if(ch == binaryFlag__[currPos] ) - { - currPos++; - - if(currPos == numcharFlag) return filePos; - } - else - { - currPos = 0; - } - } - - return pFlow::dataIO::ErrorReturn; -} - - -#ifdef pFlow_Build_MPI -pFlow::uint64 findBindaryBlockFlagMPI(MPI_File fh, pFlow::uint64 startPosSearch) -{ - - - pFlow::uint64 filePos = static_cast(startPosSearch); - - // start reading char by char - unsigned char ch; - int currPos = 0; - - while( MPI_File_read( - fh, - &ch, - 1, - MPI_UNSIGNED_CHAR, - MPI_STATUS_IGNORE) == MPI_SUCCESS ) - { - - filePos++; - - if(ch == binaryFlag__[currPos] ) - { - currPos++; - - if(currPos == numcharFlag) return filePos; - } - else - { - currPos = 0; - } - } - - return pFlow::dataIO::ErrorReturn; -} - -#endif - - -bool pFlow::dataIO::writeDataToFileEndSTD +pFlow::uniquePtr pFlow::dataIO::create ( - const word& wordPath, - const span& data + IOPattern::IOType iotype, + word exeMode ) { + auto ioMode = angleBracketsNames("dataIO", exeMode); - // openfile - auto fh = std::fopen(wordPath.c_str(), "ab"); - - if(!fh) + if( wordvCtorSelector_.search(ioMode) ) { - fatalErrorInFunction<< - "Error in Opening file "<< wordPath <0 ) - { - // write data chunk to file - wc = std::fwrite(data.data(), sizeof(unsigned char), sizeOfData, fh); - if(wc < sizeOfData ) - { - fatalErrorInFunction<< - "Error in writing size of data to file "<< wordPath <(std::ftell(fh)); - - // close the file - std::fclose(fh); - - return true; -} - -bool pFlow::dataIO::writeDataToFileEndMPI -( - const word& wordPath, - const span& data -) -{ - -#ifdef pFlow_Build_MPI - - // collect information from other processes - uint64 numProc = processors::globalSize(); - uint64 thisSize = data.size(); - uint64 offset; - - CheckMPI - ( - MPI_Scan(&thisSize, &offset, 1, MPI_UINT64_T, MPI_SUM, MPI_COMM_WORLD), - true - ); - - - MPI_File fh; - - if( MPI_File_open( - MPI_COMM_WORLD, - wordPath.c_str(), - MPI_MODE_WRONLY+MPI_MODE_APPEND, - MPI_INFO_NULL, - &fh) != MPI_SUCCESS) - { - fatalErrorInFunction<< - "Cannot open file "<< wordPath<(posOfBlock); - } - - - if( MPI_Bcast( - &startPos, - 1, - MPI_UINT64_T, - processors::masterNo(), - MPI_COMM_WORLD) != MPI_SUCCESS) - { - fatalErrorInFunction; - return false; - } - - - if( processors::isMaster()) - { - uint64 numProc = processors::globalSize(); - if(MPI_File_write( - fh, - &numProc, - 1, - MPI_UINT64_T, - MPI_STATUS_IGNORE) != MPI_SUCCESS) - { - fatalErrorInFunction<< - "Cannot write number of chunks into "< chunkSizes, - span& data, - uint64 binaryBlockStart -) -{ - - - // sum of all chuncks - uint64 toRecv = std::accumulate( - chunkSizes.begin(), - chunkSizes.end(), - static_cast(0)); - - if( data.size() != toRecv ) - { - fatalErrorInFunction; - return false; - } - - - auto fh = std::fopen(wordPath.c_str(), "rb"); - - if(!fh) - { - fatalErrorInFunction<< - "Error in Opening file "<< wordPath<(std::ftell(fh)); - - std::fclose(fh); - return true; -} - - -bool pFlow::dataIO::readDataMPI -( - const word& wordPath, - const std::vector chunkSizes, - span& data, - uint64 binaryBlockStart -) -{ - -#ifdef pFlow_Build_MPI - - - MPI_File fh; - - if( MPI_File_open( - MPI_COMM_WORLD, - wordPath.c_str(), - MPI_MODE_RDONLY, - MPI_INFO_NULL, - &fh)) - { - fatalErrorInFunction; - return false; - } - - - auto procNo = processors::globalRank(); - - uint64 toRecv = chunkSizes[procNo]; - - // start of data chunks - uint64 offset = binaryBlockStart + chunkSizeOffeset(processors::globalSize()); - - for(auto i=0; i& chunkSizes, - uint64 startPosSearch, - uint64 &startPosBinaryBlock -) -{ - -#ifdef pFlow_Build_MPI - MPI_File fh; - - if(MPI_File_open( - MPI_COMM_WORLD, - wordPath.c_str(), - MPI_MODE_RDONLY, - MPI_INFO_NULL, - &fh) != MPI_SUCCESS) - { - fatalErrorInFunction; - return false; - } - - - uint64 startPos = findBindaryBlockFlagMPI(fh, startPosSearch); - if( startPos == pFlow::dataIO::ErrorReturn ) - { - fatalErrorInFunction; - return false; - } - - startPosBinaryBlock = startPos; - - uint64 numProcInFile; - - if( MPI_File_read_at_all( - fh, - startPos, - &numProcInFile, - 1, - MPI_UINT64_T, - MPI_STATUS_IGNORE) != MPI_SUCCESS) - { - fatalErrorInFunction; - return false; - } - - - chunkSizes.resize(numProcInFile); - - if(MPI_File_read_at_all( - fh, - startPos + sizeof(numProcInFile), - chunkSizes.data(), - chunkSizes.size(), - MPI_UINT64_T, - MPI_STATUS_IGNORE) != MPI_SUCCESS) - { - fatalErrorInFunction; - return false; - } - MPI_File_close(&fh); - - uint64 lastPos = startPos + sizeof(numProcInFile) + chunkSizes.size(); - return maxReduction(lastPos, lastPosRead_); - - /*if( MPI_Allreduce( - &lastPos, - &lastPosRead_, - 1, - MPI_UINT64_T, - MPI_MAX, - MPI_COMM_WORLD) != MPI_SUCCESS) - { - fatalErrorInFunction<< - "Error in max_reduction for lastPosRead_"<& chunkSizes, - uint64 startPosSearch, - uint64 &startPosBinaryBlock -) -{ - - std::FILE *fh = std::fopen(wordPath.c_str(), "rb"); - - if(!fh) - { - fatalErrorInFunction<< - "Error in Opening file "<< wordPath<(std::ftell(fh)); - - std::fclose(fh); - return true; -} - -bool pFlow::dataIO::waitForAllMPI() -{ -#ifdef pFlow_Build_MPI - MPI_Barrier(MPI_COMM_WORLD); -#endif - - return true; -} - - -bool pFlow::dataIO::maxReduction( uint64& src, uint64& dst) -{ - -#ifdef pFlow_Build_MPI - if(processors::isParallel()) - { - if(MPI_Allreduce( - &src, - &dst, - 1, - MPI_UINT64_T, - MPI_MAX, - MPI_COMM_WORLD) != MPI_SUCCESS ) - { - fatalErrorInFunction<< - "Error in max_reduction for write operation"< buffer_; + template + span createSpan( span sp ) + { + return span( reinterpret_cast(sp.data()), sp.size()*sizeof(T) ); + } + +public: + + /// Type info + TypeInfo("dataIO"); + + dataIO(IOPattern::IOType iotype, word exeMode) + : + ioPattern_(iotype), + executionMode_(exeMode) + {} + + + dataIO(const dataIO&) = default; + + dataIO(dataIO &&) = default; + + dataIO& operator = (const dataIO&) = default; + + dataIO& operator = (dataIO&&) = default; + + virtual ~dataIO() = default; + + create_vCtor + ( + dataIO, + word, + ( + IOPattern::IOType iotype, + word exeMode + ), + (iotype, exeMode) + ); + + /// Gather data from all processors and put the results in + /// buffer_ + virtual bool gatherData(span sp ) = 0; + + /// Write data to the end of file from all processors. + /// This method should be called from all processors. + template + bool writeData(iOstream& os, span data); + + template + bool readData(iIstream& is, std::vector& data); + + template + bool readAscii( + iIstream& is, + std::vector& vec ); + + static + uniquePtr create(IOPattern::IOType iotype, word exeMode); + + +}; - bool writeDataToFileEndSTD( + +template<> +inline +bool dataIO::writeData(iOstream& os, span data) +{ + /*std::ostringstream ist(); + + for(auto i=0; i sp(ist.str().data(), ist.str().size()); + + if(!gatherData( sp) ) + { + fatalErrorInFunction<< + "Error in gathering data for out stream "<< os.name()<& data); @@ -143,14 +257,4 @@ bool pFlow::dataIO::readData( return false; } return true; -} - - -} - -#include "dataIOTemplate.cpp" - -#endif - - - +}*/ \ No newline at end of file diff --git a/src/phasicFlow/streams/dataIO/dataIONoMPI.cpp b/src/phasicFlow/streams/dataIO/dataIONoMPI.cpp new file mode 100644 index 00000000..a2dfd6be --- /dev/null +++ b/src/phasicFlow/streams/dataIO/dataIONoMPI.cpp @@ -0,0 +1,20 @@ + +#include "dataIONoMPI.hpp" + + +pFlow::dataIONoMPI::dataIONoMPI +( + IOPattern::IOType iotype, + word exeMode +) +: + dataIO(iotype, exeMode) +{} + + +bool pFlow::dataIONoMPI::gatherData( span sp ) +{ + /// in serial mode, no gathering is required. + buffer_ = sp; + return true; +} \ No newline at end of file diff --git a/src/phasicFlow/streams/dataIO/dataIONoMPI.hpp b/src/phasicFlow/streams/dataIO/dataIONoMPI.hpp new file mode 100644 index 00000000..64878fe2 --- /dev/null +++ b/src/phasicFlow/streams/dataIO/dataIONoMPI.hpp @@ -0,0 +1,48 @@ +#ifndef __datIONoMPI_hpp__ +#define __datIONoMPI_hpp__ + +#include "dataIO.hpp" + +namespace pFlow +{ + + +class dataIONoMPI +: + public dataIO +{ +protected: + +public: + + TypeInfo("dataIO"); + + dataIONoMPI(IOPattern::IOType iotype, word exeMode); + + dataIONoMPI(const dataIONoMPI&) = default; + + dataIONoMPI(dataIONoMPI&&) = default; + + + dataIONoMPI& operator=(const dataIONoMPI&) = default; + + dataIONoMPI& operator=(dataIONoMPI&&) = default; + + ~dataIONoMPI() = default; + + add_vCtor + ( + dataIO, + dataIONoMPI, + word + ); + + bool gatherData(span sp ) override; + +}; + + +} + + +#endif \ No newline at end of file diff --git a/src/phasicFlow/streams/dataIO/dataIOTemplate.cpp b/src/phasicFlow/streams/dataIO/dataIOTemplate.cpp index 54b1452f..a485d2b1 100644 --- a/src/phasicFlow/streams/dataIO/dataIOTemplate.cpp +++ b/src/phasicFlow/streams/dataIO/dataIOTemplate.cpp @@ -1,4 +1,175 @@ + template +bool pFlow::dataIO::writeData(iOstream& os, span data) +{ + /// first gather data from all processors (if any) + if(!gatherData( createSpan(data) ) ) + { + fatalErrorInFunction<< + "Error in gathering data for out stream "<< os.name()< allData( + reinterpret_cast(buffer_.data()), + buffer_.size()/sizeof(T)); + + if( !allData.writeASCII(os) ) + { + fatalErrorInFunction<< + "error in writing ASCII data to "< +bool pFlow::dataIO::readData +( + iIstream& is, + std::vector& data +) +{ + + data.clear(); + + if(ioPattern_.thisProcReadData()) + { + if(is.isBinary()) + { + // read length of data + token firstToken(is); + + size_t len = 0; + if( firstToken.isInt64()) + { + len = firstToken.int64Token(); + data.resize(len); + } + else + { + fatalErrorInFunction<< + "expected length of vector in the stream "<(data.data()), len*sizeof(T)); + + return is.check(FUNCTION_NAME); + } + else + { + + return readAscii(is, data); + } + } + else + { + return true; + } +} + +template +bool pFlow::dataIO::readAscii +( + iIstream& is, + std::vector& vec +) +{ + + if( !ioPattern_.thisProcReadData() ) return true; + + + is.fatalCheck(FUNCTION_NAME); + + vec.clear(); + + token firstToken(is); + + size_t len = 0; + if( firstToken.isInt64()) + { + len = firstToken.int64Token(); + vec.reserve(len); + firstToken = token(is); + } + + T val{}; + if( firstToken.isPunctuation() ) // start of vector + { + if(firstToken != token::BEGIN_LIST) + { + warningInFunction + << "expected token "<< token::BEGIN_LIST + << " but found "<< firstToken ; + return false; + + } + + token lastToken(is); + + is.fatalCheck(FUNCTION_NAME); + + while(!(lastToken.isPunctuation() + && lastToken == token::END_LIST )) + { + + is.putBack(lastToken); + + is >> val; + vec.push_back(val); + + is >> lastToken; + is.fatalCheck(FUNCTION_NAME); + } + + } else + { + warningInFunction + << "expected token "<< token::BEGIN_LIST + << " but found "<< firstToken<0&& len != vec.size()) + { + warningInFunction<<"vector lendth specified "<< len << + " is different from number of elements "<< vec.size()< bool pFlow::dataIO::writeDataEnd( const word& wordPath, const span& data) @@ -314,7 +485,7 @@ bool pFlow::dataIO::writeData } return true; -} +}*/ diff --git a/src/phasicFlow/streams/iStream/iOstream.hpp b/src/phasicFlow/streams/iStream/iOstream.hpp index ceaa2edd..11b73674 100644 --- a/src/phasicFlow/streams/iStream/iOstream.hpp +++ b/src/phasicFlow/streams/iStream/iOstream.hpp @@ -36,6 +36,13 @@ const inline char* whiteColor = "\033[37m"; const inline char* boldChar = "\033[1m"; +#define Red_Text(text) redColor< INFO: "< +class scatterFieldAccess +{ +public: + + using execution_space = ExecutionSpace; + + using memory_space = typename execution_space::memory_space; + +protected: + + uint32 size_ = 0; + + ViewType1D indices_; + + ViewType1D fieldVals_; + +public: + + scatterFieldAccess( + uint32 sz + ViewType1D ind, + ViewType1D fVals) + : + size_(sz), + indices_(ind), + fieldVals_(fVals) + {} + + scatterFieldAccess(const scatterFieldAccess&) = default; + + scatterFieldAccess(scatterFieldAccess&&) = default; + + scatterFieldAccess& operator=(const scatterFieldAccess&) = default; + + scatterFieldAccess& operator=(scatterFieldAccess&&) = default; + + ~scatterFieldAccess() = default; + + // - Methods + + T& operator()(uint32 i) + { + return fieldVals_(indices_(i)); + } + + const T& operator()(uint32 i)const + { + return fieldVals_(indices_(i)); + } + + T& operator[](uint32 i) + { + return fieldVals_(indices_(i)); + } + + const T& operator[](uint32 i)const + { + return fieldVals_(indices_(i)); + } + + uint32 size()const + { + return size_; + } + + bool empty()const + { + return size_ == 0; + } + +}; + +} + + +#endif //__scatterFieldAccess_hpp__ + diff --git a/src/phasicFlow/structuredData/box/box.hpp b/src/phasicFlow/structuredData/box/box.hpp index 428e0534..5ad65de9 100644 --- a/src/phasicFlow/structuredData/box/box.hpp +++ b/src/phasicFlow/structuredData/box/box.hpp @@ -62,18 +62,19 @@ public: FUNCTION_H box(iIstream& is); - FUNCTION_HD + INLINE_FUNCTION_HD box(const box&) = default; - FUNCTION_HD + INLINE_FUNCTION_HD box(box&&) = default; - FUNCTION_HD + INLINE_FUNCTION_HD box& operator=(const box&) = default; - FUNCTION_HD + INLINE_FUNCTION_HD box& operator=(box&&) = default; + INLINE_FUNCTION_HD ~box()=default; //// - Methods @@ -85,13 +86,13 @@ public: } INLINE_FUNCTION_HD - realx3 minPoint()const + const realx3& minPoint()const { return min_; } INLINE_FUNCTION_HD - realx3 maxPoint()const + const realx3& maxPoint()const { return max_; } diff --git a/src/phasicFlow/structuredData/domain/domain.cpp b/src/phasicFlow/structuredData/domain/domain.cpp new file mode 100644 index 00000000..8a6b9939 --- /dev/null +++ b/src/phasicFlow/structuredData/domain/domain.cpp @@ -0,0 +1,59 @@ +/*------------------------------- 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. + +-----------------------------------------------------------------------------*/ + +#include "domain.hpp" + +FUNCTION_H +pFlow::domain::domain(const box& db) +: + domainBox_(db), + left_( + db.minPoint(), + realx3(db.minPoint().x(), db.maxPoint().y(), db.minPoint().z()), + realx3(db.minPoint().x(), db.maxPoint().y(), db.maxPoint().z()), + realx3(db.minPoint().x(), db.minPoint().y(), db.maxPoint().z())), + right_( + db.maxPoint(), + realx3(db.maxPoint().x(), db.maxPoint().y(), db.minPoint().z()), + realx3(db.maxPoint().x(), db.minPoint().y(), db.minPoint().z()), + realx3(db.maxPoint().x(), db.minPoint().y(), db.maxPoint().z())), + bottom_( + db.minPoint(), + realx3(db.minPoint().x(), db.minPoint().y(), db.maxPoint().z()), + realx3(db.maxPoint().x(), db.minPoint().y(), db.maxPoint().z()), + realx3(db.maxPoint().x(), db.minPoint().y(), db.minPoint().z())), + top_( + db.maxPoint(), + realx3(db.minPoint().x(), db.maxPoint().y(), db.maxPoint().z()), + realx3(db.minPoint().x(), db.maxPoint().y(), db.minPoint().z()), + realx3(db.maxPoint().x(), db.maxPoint().y(), db.minPoint().z())), + rear_( + db.minPoint(), + realx3(db.maxPoint().x(), db.minPoint().y(), db.minPoint().z()), + realx3(db.maxPoint().x(), db.maxPoint().y(), db.minPoint().z()), + realx3(db.minPoint().x(), db.maxPoint().y(), db.minPoint().z())), + front_( + db.maxPoint(), + realx3(db.maxPoint().x(), db.minPoint().y(), db.maxPoint().z()), + realx3(db.minPoint().x(), db.minPoint().y(), db.maxPoint().z()), + realx3(db.minPoint().x(), db.maxPoint().y(), db.maxPoint().z())) +{ + +} \ No newline at end of file diff --git a/src/phasicFlow/structuredData/domain/domain.hpp b/src/phasicFlow/structuredData/domain/domain.hpp new file mode 100644 index 00000000..220eda2f --- /dev/null +++ b/src/phasicFlow/structuredData/domain/domain.hpp @@ -0,0 +1,163 @@ +/*------------------------------- 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 __domain_hpp__ +#define __domain_hpp__ + + +#include "box.hpp" +#include "plane.hpp" + +namespace pFlow +{ + +class domain +{ +protected: + + box domainBox_; + + /// -x + plane left_; + + /// +x + plane right_; + + /// -y + plane bottom_; + + /// +y + plane top_; + + /// -z + plane rear_; + + /// +z + plane front_; + + +public: + + // - type info + TypeInfoNV("domain"); + + //// - Constructors + INLINE_FUNCTION_HD + domain(){} + + FUNCTION_H + domain(const box& db); + + INLINE_FUNCTION_HD + domain(const domain&) = default; + + INLINE_FUNCTION_HD + domain(domain&&) = default; + + INLINE_FUNCTION_HD + domain& operator=(const domain&) = default; + + INLINE_FUNCTION_HD + domain& operator=(domain&&) = default; + + INLINE_FUNCTION_HD + ~domain()=default; + + //// - Methods + + INLINE_FUNCTION_HD + const auto& domainBox()const + { + return domainBox_; + } + + INLINE_FUNCTION_HD + const auto& left()const + { + return left_; + } + + INLINE_FUNCTION_HD + const auto& right()const + { + return right_; + } + + INLINE_FUNCTION_HD + const auto& bottom()const + { + return bottom_; + } + + INLINE_FUNCTION_HD + const auto& top()const + { + return top_; + } + + INLINE_FUNCTION_HD + const auto& rear()const + { + return rear_; + } + + INLINE_FUNCTION_HD + const auto& front()const + { + return front_; + } + + +}; // domain + +INLINE_FUNCTION_HD +bool equal(const domain& d1, const domain& d2) +{ + return equal(d1.domainBox(), d2.domainBox()); +} + +INLINE_FUNCTION_HD +bool equal(const domain& d1, const domain& d2, real tol) +{ + return equal(d1.domainBox(), d2.domainBox(), tol); +} + +INLINE_FUNCTION_HD +bool operator ==(const domain& d1, const domain& d2) +{ + return equal(d1, d2); +} + +/*FUNCTION_H +iIstream& operator >>(iIstream& is, box& b); + +FUNCTION_H +iOstream& operator << (iOstream& os, const box& b); + +INLINE_FUNCTION_HD +box extendBox(const box& b, const realx3& dl) +{ + return box(b.minPoint()-dl , b.maxPoint()+dl); +}*/ + +} + + +#endif diff --git a/src/phasicFlow/structuredData/infinitePlane/infinitePlane.hpp b/src/phasicFlow/structuredData/infinitePlane/infinitePlane.hpp index 3140915c..14aea880 100644 --- a/src/phasicFlow/structuredData/infinitePlane/infinitePlane.hpp +++ b/src/phasicFlow/structuredData/infinitePlane/infinitePlane.hpp @@ -103,6 +103,21 @@ public: return pointFromPlane(p)>=0; } + INLINE_FUNCTION_HD + bool inPositiveDistance(const realx3& p, real dist)const + { + real d = pointFromPlane(p); + return d >= 0.0 && d <= dist; + } + + INLINE_FUNCTION_HD + bool inNegativeDistance(const realx3& p, real dist)const + { + real d = pointFromPlane(p); + return d < 0.0 && d <= -dist; + } + + INLINE_FUNCTION_HD bool pointInNegativeSide(const realx3& p)const { diff --git a/src/phasicFlow/structuredData/pointStructure/internalPoints.cpp b/src/phasicFlow/structuredData/pointStructure/internalPoints.cpp new file mode 100644 index 00000000..d551a7ea --- /dev/null +++ b/src/phasicFlow/structuredData/pointStructure/internalPoints.cpp @@ -0,0 +1,250 @@ +/*------------------------------- 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. + +-----------------------------------------------------------------------------*/ + + +#include "internalPoints.hpp" + + +void pFlow::internalPoints::syncPFlag()const +{ + if(!pFlagSync_) + { + pFlagsH_ = pFlagsD_.clone(); + pFlagSync_ = true; + } +} + +/*#include "setFieldList.hpp" +#include "error.hpp" +#include "iOstream.hpp" + +#include "mortonIndexing.hpp"*/ + +/*FUNCTION_H +bool pFlow::internalPoints::evaluateinternalPoints() +{ + if(pointFlag_.size() != pointPosition_.size()) + { + fatalErrorInFunction<< + "number of elements in pointFlag and pointPosition is not equal \n"; + return false; + } + + setNumMaxPoints(); + + int32 minActive, maxActive; + numActivePoints_ = pFlow::internalPointsKernels::scanPointFlag( + 0, + numPoints_, + static_cast(internalPoints::ACTIVE), + pointFlag_.deviceVectorAll(), + minActive, + maxActive + ); + + activeRange_ = {minActive, maxActive}; + + return true; +} + +FUNCTION_H +void pFlow::internalPoints::setNumMaxPoints() +{ + maxPoints_ = pointFlag_.capacity(); + numPoints_ = pointFlag_.size(); +} + +FUNCTION_H +pFlow::realx3Field_D& pFlow::internalPoints::pointPosition() +{ + return pointPosition_; +} + +FUNCTION_H +pFlow::int8Field_HD& pFlow::internalPoints::pointFlag() +{ + return pointFlag_; +} + +pFlow::uniquePtr + pFlow::internalPoints::getNewPointsIndices(int32 numNewPoints)const +{ + + + if( capacity() - activeRange_.second >= numNewPoints ) + { + // fill the sequence starting from activeRange_.second-1 + return makeUnique( + activeRange_.second, + activeRange_.second+numNewPoints); + + } + + // second, check if there is space at the beginning + if( activeRange_.first >= numNewPoints) + { + return makeUnique( + 0, + numNewPoints); + } + + // otherwise scan the points from first to the end to find empty spaces + int32Vector newPoints( + numNewPoints, + RESERVE()); + + newPoints.clear(); + int32 numAdded = 0; + ForAll(i, pointFlag_) + { + if(!isActive(i)) + { + newPoints.push_back(static_cast(i)); + numAdded++; + } + + if(numAdded == numNewPoints) + { + return makeUnique( + newPoints.data(), + numNewPoints); + } + } + + // check if there is space at the end for the remaining of points + if( numAdded = numNewPoints - numAdded ) + { + int32 ind = size(); + for(int32 i=numAdded; i( + newPoints.data(), + numNewPoints); + } + else + { + fatalErrorInFunction<<"not enough capacity for inserting particles into the point structure\n"; + return nullptr; + } + + return nullptr; +}*/ + +pFlow::internalPoints::internalPoints() +: + pointPosition_("internalPoints", "internalPoints", initialCapacity_, 0, RESERVE()), + pFlagsD_(initialCapacity_, 0 , 0) +{ + syncPFlag(); +} + + +pFlow::internalPoints::internalPoints +( + const std::vector& posVec +) +: + pointPosition_("internalPoints", "internalPoints", posVec.capacity(), 0, RESERVE()), + pFlagsD_(posVec.capacity(), 0, posVec.size()) +{ + + pointPosition_.assign(posVec); + + syncPFlag(); + +} + + +const pFlow::internalPoints::pFlagTypeDevice& + pFlow::internalPoints::activePointsMaskD() const +{ + return pFlagsD_; +} + + +const pFlow::internalPoints::pFlagTypeHost& + pFlow::internalPoints::activePointsMaskH() const +{ + syncPFlag(); + return pFlagsH_; +} + +FUNCTION_H +void pFlow::internalPoints::updateFlag +( + const domain& dm, + real dist +) +{ + pFlagsD_.markDeleteInDomain + ( + dm, + pointPosition_.deviceVectorAll(), + dist + ); +} + + +FUNCTION_H +bool pFlow::internalPoints::read +( + iIstream& is, + IOPattern::IOType iotype +) +{ + + if( !pointPosition_.read(is, iotype)) + { + fatalErrorInFunction<< + "Error in reading pointPosition from stream "<< is.name()<; + + using pFlagTypeHost = pointFlag; + + +protected: + + //// - data members + + // position of points on device + realx3Field_D pointPosition_; + + // flag of points on device + mutable pFlagTypeDevice pFlagsD_; + + mutable pFlagTypeHost pFlagsH_; + + mutable bool pFlagSync_ = false; + + + void syncPFlag()const; + +public: + + friend class dynamicinternalPoints; + + // - type info + TypeInfo("internalPoints"); + + + //// - Constructors + + // - an empty internalPoints, good for reading from file + internalPoints(); + + /// Construct from components + //internalPoints(const int8Vector& flgVec, const realx3Vector& posVec); + + /// Construct from point positions, assume all points are active + internalPoints(const std::vector& posVec); + + /// Copy construct + internalPoints(const internalPoints&) = default; + + /// Move construct + internalPoints(internalPoints&&) = default; + + /// Copy assignment + internalPoints& operator=(const internalPoints&) = default; + + /// Move assignment + internalPoints& operator=(internalPoints&&) = delete; + + /// Destructor + virtual ~internalPoints() = default; + + + //// - Methods + FUNCTION_H + const pFlagTypeDevice& activePointsMaskD()const; + + + FUNCTION_H + const pFlagTypeHost& activePointsMaskH()const; + + // - Const access pointPosition + FUNCTION_H + const realx3Field_D& pointPosition()const; + + + + /*INLINE_FUNCTION_H + auto pointPositionHostAll() + { + return pointPosition_.hostVectorAll(); + }*/ + + // - size of data structure + INLINE_FUNCTION_H + uint32 size()const + { + return pointPosition_.size(); + } + + // - maximum capacity of data structure + INLINE_FUNCTION_H + uint32 capacity()const + { + return pointPosition_.capacity(); + } + + // - number of active points + INLINE_FUNCTION_H + uint32 numActive() const + { + return pFlagsD_.numActive(); + } + + // - if all points are active + INLINE_FUNCTION_H + bool isAllActive()const + { + return pFlagsD_.isAllActive(); + } + + INLINE_FUNCTION_H + auto activeRange()const + { + return pFlagsD_.activeRange(); + } + + + FUNCTION_H + void updateFlag(const domain& dm, real dist); + + /*FUNCTION_H + size_t markDeleteOutOfBox(const box& domain);*/ + + + /////////////////////////////////////////////////////////////////////////////////////////////////// + + // - const access to points to be newly inserted + /*FUNCTION_H + auto insertedPointIndex()const + { + return tobeInsertedIndex_; + } + + FUNCTION_H + auto insertedPointIndexH()const + { + return tobeInsertedIndex_.hostView(); + } + + FUNCTION_H + auto insertedPointIndexD()const + { + return tobeInsertedIndex_.deviceView(); + } + + + FUNCTION_H + auto mortonSortedIndex()const + { + return mortonSortedIndex_; + } + + + // - update data structure by inserting/setting new points + // Notifies all the fields in the registered list of data structure + // and exclude the fields that re in the exclusionList + // retrun nullptr if it fails + /*FUNCTION_H + virtual uniquePtr insertPoints( + const realx3Vector& pos, + const setFieldList& setField, + repository& owner, + const List& exclusionList={nullptr} + );*/ + + + //// - IO operations + + /// Read + FUNCTION_H + bool read(iIstream& is, IOPattern::IOType iotype); + + + /// Write + FUNCTION_H + bool write(iOstream& os, IOPattern::IOType iotype)const; + +}; + +iOstream& operator<<(iOstream& os, const internalPoints& ip) +{ + if( !ip.write(os, IOPattern::AllProcessorsDifferent) ) + { + ioErrorInFile(os.name(), os.lineNumber()); + fatalExit; + } + + return os; +} + +} // pFlow + + + + +#endif //__internalPoints_hpp__ + + +/*class activePointsDevice + { + protected: + ViewType1D flag_; + + bool allActive_; + + range activeRange_; + + public: + + INLINE_FUNCTION_H + activePointsDevice(bool allActive, range active, const ViewType1D& flag) + : + flag_(flag), + allActive_(allActive), + activeRange_(active) + {} + + INLINE_FUNCTION_HD + activePointsDevice(const activePointsDevice&) = default; + + INLINE_FUNCTION_HD + activePointsDevice& operator=(const activePointsDevice&) = default; + + INLINE_FUNCTION_HD + bool operator()(int32 i)const { + if(i flag_; + + bool allActive_; + + range activeRange_; + + public: + + INLINE_FUNCTION_H + activePointsHost(bool allActive, range active, const ViewType1D& flag) + : + flag_(flag), + allActive_(allActive), + activeRange_(active){} + + INLINE_FUNCTION_H + activePointsHost(const activePointsHost&) = default; + + INLINE_FUNCTION_H + activePointsHost& operator=(const activePointsHost&) = default; + + INLINE_FUNCTION_H + bool operator()(int32 i)const { + if(i +class pointFlag +{ + enum Flag: uint8 + { + DELETED = 1, //10000000 + INTERNAL = 2, //00000001 + LEFT = 4, //00000010 + RIGHT = 8, //00000100 + BOTTOM = 16, //00001000 + TOP = 32, //00010000 + REAR = 64, //00100000 + FRONT = 128 //01000000 + }; + + using execution_space = ExecutionSpace; + + using memory_space = typename execution_space::memory_space; + + using viewType = ViewType1D; + + using device_type = typename viewType::device_type; + +protected: + + viewType flags_; + + uint32 numActive_ = 0; + + rangeU32 activeRange_ = {0,0}; + + bool isAllActive_ = false; + + uint32 nLeft_ = 0; + + uint32 nRight_ = 0; + + uint32 nBottom_= 0; + + uint32 nTop_ = 0; + + uint32 nRear_ = 0; + + uint32 nFront_ = 0; + + //- Protected methods + + + +public: + + friend class internalPoints; + + pointFlag() + {} + + pointFlag(uint32 capacity, uint32 start, uint32 end ) + : + flags_("pointFlag", capacity ), + numActive_(end-start), + activeRange_(start, end), + isAllActive_(true) + { + fill(flags_, 0, capacity, static_cast(Flag::DELETED)); + fill(flags_, activeRange_, static_cast(Flag::INTERNAL)); + } + + pointFlag( + viewType flags, + uint32 numActive, + rangeU32 activeRange, + bool isAllActive) + : + flags_(flags), + numActive_(numActive), + activeRange_(activeRange), + isAllActive_(isAllActive) + {} + + pointFlag(const pointFlag&) = default; + + pointFlag& operator=(const pointFlag&) = default; + + pointFlag(pointFlag&&) = default; + + pointFlag& operator=(pointFlag&&) = default; + + ~pointFlag() = default; + + INLINE_FUNCTION_HD + bool isAllActive()const + { + return isAllActive_; + } + + INLINE_FUNCTION_HD + const auto& activeRange()const + { + return activeRange_; + } + + INLINE_FUNCTION_HD + auto numActive()const + { + return numActive_; + } + + INLINE_FUNCTION_HD + bool operator()(uint32 i) + { + return isActive(i); + } + + INLINE_FUNCTION_HD + bool isActive(uint32 i)const + { + return flags_[i] > DELETED; + } + + INLINE_FUNCTION_HD + bool isBoundary(uint32 i)const + { + return flags_[i] > INTERNAL; + } + + INLINE_FUNCTION_HD + bool isBoundary(uint8 flg)const + { + return flg > INTERNAL; + } + + INLINE_FUNCTION_HD + bool isLeft(uint32 i)const + { + return (flags_[i]&LEFT) == LEFT; + } + + INLINE_FUNCTION_HD + bool isLeft(uint8 flg)const + { + return (flg&LEFT) == LEFT; + } + + INLINE_FUNCTION_HD + bool isRight(uint32 i)const + { + return (flags_[i]&&RIGHT) == RIGHT; + } + + INLINE_FUNCTION_HD + bool isRight(uint8 flg)const + { + return (flg&&RIGHT) == RIGHT; + } + + INLINE_FUNCTION_HD + bool isBottom(uint32 i)const + { + return (flags_[i]&&BOTTOM) == BOTTOM; + } + + INLINE_FUNCTION_HD + bool isBottom(uint8 flg)const + { + return (flg&&BOTTOM) == BOTTOM; + } + + INLINE_FUNCTION_HD + bool isTop(uint32 i)const + { + return (flags_[i]&&TOP) == TOP; + } + + INLINE_FUNCTION_HD + bool isTop(uint8 flg)const + { + return (flg&&TOP) == TOP; + } + + INLINE_FUNCTION_HD + bool isRear(uint32 i)const + { + return (flags_[i]&&REAR) == REAR; + } + + INLINE_FUNCTION_HD + bool isRear(uint8 flg)const + { + return (flg&&REAR) == REAR; + } + + INLINE_FUNCTION_HD + bool isFront(uint32 i)const + { + return (flags_[i]&&FRONT) == FRONT; + } + + INLINE_FUNCTION_HD + bool isFront(uint8 flg)const + { + return (flg&&FRONT) == FRONT; + } + + + template + pointFlag clone()const + { + using newViewType = ViewType1D; + newViewType newFlags( + "pointFlag", + flags_.size()); + + copy(newFlags, flags_); + + return pointFlag( + newFlags, + numActive_, + activeRange_, + isAllActive_); + } + + + uint32 scanPointFlag(); + + uint32 markDeleteInDomain( + domain dm, + ViewType1D points, + real dist); + + void fillNeighborsLists( + ViewType1D leftList, + ViewType1D rightList, + ViewType1D bottomList, + ViewType1D topList, + ViewType1D rearList, + ViewType1D frontList); + + + +}; + + +} + +#include "pointFlagKernels.hpp" + +#endif // __pointFlag_hpp__ diff --git a/src/phasicFlow/structuredData/pointStructure/pointFlagKernels.hpp b/src/phasicFlow/structuredData/pointStructure/pointFlagKernels.hpp new file mode 100644 index 00000000..107ac2e9 --- /dev/null +++ b/src/phasicFlow/structuredData/pointStructure/pointFlagKernels.hpp @@ -0,0 +1,260 @@ +/*------------------------------- 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 __pointFlagKernels_hpp__ +#define __pointFlagKernels_hpp__ + + + +template +pFlow::uint32 pFlow::pointFlag::scanPointFlag() +{ + + using rpScanFlag = Kokkos::RangePolicy>; + + uint32 numActive = 0; + + + uint32 start = activeRange().start(); + uint32 end = activeRange().end(); + + uint32 minRange = end; + uint32 maxRange = start; + + if(startisActive(i)) + { + sumToUpdate++; + minUpdate = min(minUpdate,i); + maxUpdate = max(maxUpdate,i); + } + }, + Kokkos::Min(minRange), + Kokkos::Max(maxRange), + numActive); + } + + if(numActive==0) + { + minRange = 0; + maxRange = 0; + } + else + { + // add one to maxRange to make it half-open + maxRange ++; + } + + activeRange_ = {minRange, maxRange}; + numActive_ = numActive; + isAllActive_ = activeRange_.numElements() == numActive_; + + return numActive; +} + + +template +pFlow::uint32 pFlow::pointFlag::markDeleteInDomain +( + domain dm, + ViewType1D points, + real dist) +{ + + using rpMark = Kokkos::RangePolicy>; + + uint32 start = activeRange().start(); + uint32 end = activeRange().end(); + + uint32 minRange = end; + uint32 maxRange = start; + + uint32 numMarked = 0; + uint32 nLeft = 0, nRight = 0; + uint32 nBottom = 0, nTop = 0; + uint32 nRear = 0, nFront = 0; + + if(startisActive(i)) + { + realx3 p = points[i]; + if( !dm.domainBox().isInside(p) ) + { + flags_[i] = DELETED; + valDelete++; + } + else + { + + uint8 flg = 0; + minUpdate = min(minUpdate,i); + maxUpdate = max(maxUpdate,i); + + if(dm.left().inPositiveDistance(p, dist)) + { + flg += LEFT; + valLeft++; + } + + if(dm.right().inPositiveDistance(p, dist)) + { + flg += RIGHT; + valRight++; + } + + if(dm.bottom().inPositiveDistance(p, dist)) + { + flg += BOTTOM; + valBottom++; + } + + if(dm.top().inPositiveDistance(p, dist)) + { + flg += TOP; + valTop++; + } + + if(dm.rear().inPositiveDistance(p, dist)) + { + flg += REAR; + valRear++; + } + + if(dm.front().inPositiveDistance(p, dist)) + { + flg += FRONT; + valFront++; + } + + flags_[i] = flg>static_cast(0)? flg: INTERNAL; + } + } + }, + Kokkos::Min(minRange), + Kokkos::Max(maxRange), + numMarked, + nLeft, + nRight, + nBottom, + nTop, + nRear, + nFront); + + } + + // means either range was empty or all points have been deleted. + if(minRangeend) + { + minRange = 0; + maxRange = 0; + } + else + { + maxRange++; // add one to make it half + } + + activeRange_ = {minRange, maxRange}; + isAllActive_ = isAllActive_ && numMarked == 0; + numActive_ -= numMarked; + + nLeft_ = nLeft; + nRight_ = nRight; + nBottom_= nBottom; + nTop_ = nTop; + nRear_ = nRear; + nFront_ = nFront; + + return numMarked; +} + +template +void pFlow::pointFlag::fillNeighborsLists +( + ViewType1D leftList, + ViewType1D rightList, + ViewType1D bottomList, + ViewType1D topList, + ViewType1D rearList, + ViewType1D frontList +) +{ + using rpMark = Kokkos::RangePolicy>; + + uint32 start = activeRange().start(); + uint32 end = activeRange().end(); + + ViewType1D nElems("nElems",6); + + fill(nElems, 0, 6, 0); + + if(startisBoundary(flg)) + { + if(this->isLeft(flg)) leftList[Kokkos::atomic_fetch_add(&nElems[0],1)] = i; + if(this->isRight(flg)) rightList[Kokkos::atomic_fetch_add(&nElems[1],1)] = i; + if(this->isBottom(flg)) bottomList[Kokkos::atomic_fetch_add(&nElems[2],1)] = i; + if(this->isTop(flg)) topList[Kokkos::atomic_fetch_add(&nElems[3],1)] = i; + if(this->isRear(flg)) rearList[Kokkos::atomic_fetch_add(&nElems[4],1)] = i; + if(this->isFront(flg)) frontList[Kokkos::atomic_fetch_add(&nElems[5],1)] = i; + } + }); + Kokkos::fence(); + } + + +} + +#endif // __pointFlagKernels_hpp__ diff --git a/src/phasicFlow/structuredData/pointStructure/pointStructure.hpp b/src/phasicFlow/structuredData/pointStructure/pointStructure.hpp index be70072d..09afa2af 100644 --- a/src/phasicFlow/structuredData/pointStructure/pointStructure.hpp +++ b/src/phasicFlow/structuredData/pointStructure/pointStructure.hpp @@ -23,6 +23,8 @@ Licence: #define __pointStructure_hpp__ +#include "Lists.hpp" +#include "internalPoints.hpp" #include "Vectors.hpp" #include "VectorSingles.hpp" @@ -37,9 +39,8 @@ namespace pFlow { //forward -class box; -class setFieldList; -class repository; +class boundaryBase; + class pointStructure : @@ -47,152 +48,24 @@ class pointStructure { public: - enum PointFlag: int8 - { - DELETED = -1, - ACTIVE = 1 - }; - - - inline static const size_t maxSizeDefault_ = 10000; - - class activePointsDevice - { - protected: - ViewType1D flag_; - - bool allActive_; - - range activeRange_; - - public: - - INLINE_FUNCTION_H - activePointsDevice(bool allActive, range active, const ViewType1D& flag) - : - flag_(flag), - allActive_(allActive), - activeRange_(active) - {} - - INLINE_FUNCTION_HD - activePointsDevice(const activePointsDevice&) = default; - - INLINE_FUNCTION_HD - activePointsDevice& operator=(const activePointsDevice&) = default; - - INLINE_FUNCTION_HD - bool operator()(int32 i)const { - if(i flag_; - - bool allActive_; - - range activeRange_; - - public: - - INLINE_FUNCTION_H - activePointsHost(bool allActive, range active, const ViewType1D& flag) - : - flag_(flag), - allActive_(allActive), - activeRange_(active){} - - INLINE_FUNCTION_H - activePointsHost(const activePointsHost&) = default; - - INLINE_FUNCTION_H - activePointsHost& operator=(const activePointsHost&) = default; - - INLINE_FUNCTION_H - bool operator()(int32 i)const { - if(i ; protected: //// - data members + domain globalDomain_; - // number of points / size of structure - size_t numPoints_ = 0; + domain thisDomain_; - // maximum number of points - size_t maxPoints_ = maxSizeDefault_; + internalPoints internal_; - // flag of points on device - int8Field_HD pointFlag_; + boundaryListType boundaries_; - // position of points on device - realx3Field_D pointPosition_; - - // number of active points - size_t numActivePoints_ = 0; - - // index range of active points (half-open range) - range activeRange_; - - /// Index vector for points to be inserted - int32IndexContainer tobeInsertedIndex_; - - /// Sorted index of particles based on morton code - int32IndexContainer mortonSortedIndex_; - - - //// - protected methods - FUNCTION_H - bool evaluatePointStructure(); - - FUNCTION_H - void setNumMaxPoints(); - - // - access to pointPosition - FUNCTION_H - realx3Field_D& pointPosition(); - - // - access to pointFlag - FUNCTION_H - int8Field_HD& pointFlag(); - - FUNCTION_H - uniquePtr - getNewPointsIndices(int32 numNewPoints)const; + wordList boundaryTypes_; public: - friend class dynamicPointStructure; - + // - type info TypeInfo("pointStructure"); @@ -228,41 +101,7 @@ public: pointStructure& operator=(pointStructure&&) = delete; // - destructor - virtual ~pointStructure() = default; - - - //// - Methods - activePointsDevice activePointsMaskD()const - { - return activePointsDevice( - this->allActive(), - activeRange(), - pointFlag_.deviceVectorAll() - ); - } - - activePointsHost activePointsMaskH()const - { - return activePointsHost( - this->allActive(), - activeRange(), - pointFlag_.hostVectorAll() - ); - } - - // - const access pointPosition - FUNCTION_H - const realx3Field_D& pointPosition()const; - - // - const access to pointFlag - FUNCTION_H - const int8Field_HD& pointFlag()const; - - INLINE_FUNCTION_H - auto pointPositionHostAll() - { - return pointPosition_.hostVectorAll(); - } + virtual ~pointStructure() = default // - size of data structure FUNCTION_H @@ -272,103 +111,37 @@ public: FUNCTION_H label capacity()const; - // - number of active points - FUNCTION_H - label numActive() const; - - // - if all points are active - FUNCTION_H - bool allActive()const; - - INLINE_FUNCTION_H - range activeRange()const - { - return activeRange_; - } - - INLINE_FUNCTION_H - bool isActive(label i)const - { - return pointFlag_[i] == ACTIVE; - } - - FUNCTION_H - size_t markDeleteOutOfBox(const box& domain); - - // - update data structure by removing the marked points - // Notifies all the fields that are built based on this data structure - // and then apply removing to the pointPosition_ and pointFlag_ - FUNCTION_H - virtual bool updateForDelete(); - - - FUNCTION_H - virtual bool mortonSortPoints(const box& domain, real dx); - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // - const access to points to be newly inserted - FUNCTION_H - auto insertedPointIndex()const - { - return tobeInsertedIndex_; - } - - FUNCTION_H - auto insertedPointIndexH()const - { - return tobeInsertedIndex_.hostView(); - } - - FUNCTION_H - auto insertedPointIndexD()const - { - return tobeInsertedIndex_.deviceView(); - } - - - FUNCTION_H - auto mortonSortedIndex()const - { - return mortonSortedIndex_; - } - - // - update data structure by inserting/setting new points // Notifies all the fields in the registered list of data structure // and exclude the fields that re in the exclusionList // retrun nullptr if it fails FUNCTION_H - virtual uniquePtr insertPoints( + /*virtual uniquePtr insertPoints( const realx3Vector& pos, const setFieldList& setField, repository& owner, const List& exclusionList={nullptr} - ); + );*/ + + boundaryBase& boundary(size_t i) + { + return boundaries_[i]; + } + + + const boundaryBase& boundary(size_t i)const + { + return boundaries_[i]; + } + //// - IO operations - // - read pointStructure from is - FUNCTION_H - bool readPointStructure(iIstream& is); + + - // - write pointStructure to os - FUNCTION_H - bool writePointStructure(iOstream& os)const; - // - read - FUNCTION_H - bool read(iIstream& is) - { - return readPointStructure(is); - } - - // - write - FUNCTION_H - bool write(iOstream& os)const - { - return writePointStructure(os); - } }; diff --git a/src/phasicFlow/types/basicTypes/bTypesFunctions.hpp b/src/phasicFlow/types/basicTypes/bTypesFunctions.hpp index 84a4542f..77cd983a 100755 --- a/src/phasicFlow/types/basicTypes/bTypesFunctions.hpp +++ b/src/phasicFlow/types/basicTypes/bTypesFunctions.hpp @@ -190,9 +190,9 @@ bool readValue(const word& w, bool& val) INLINE_FUNCTION_HD -bool equal(const real& s1, const real& s2) +bool equal(const real& s1, const real& s2, real tol = smallValue) { - return abs(s1 - s2) <= smallValue; + return abs(s1 - s2) <= tol; } INLINE_FUNCTION_HD diff --git a/src/phasicFlow/types/triple/triple.hpp b/src/phasicFlow/types/triple/triple.hpp index 616c1e36..356e5a00 100644 --- a/src/phasicFlow/types/triple/triple.hpp +++ b/src/phasicFlow/types/triple/triple.hpp @@ -231,7 +231,17 @@ struct triple }; template -bool INLINE_FUNCTION_HD equal( const triple& opr1, const triple& opr2 ); +bool INLINE_FUNCTION_HD equal( const triple& opr1, const triple& opr2); + + +bool +INLINE_FUNCTION_HD +equal(const triple& opr1, const triple& opr2, real tol) +{ + return equal( opr1.x(), opr2.x(), tol ) && + equal( opr1.y(), opr2.y(), tol ) && + equal( opr1.z(), opr2.z(), tol ); +} } /// end of pFlow