From d65aa02cbbdf8d75ebf1b24c29b1814778d6bc69 Mon Sep 17 00:00:00 2001 From: Hamidreza Norouzi Date: Sat, 28 Oct 2023 12:09:40 +0330 Subject: [PATCH] Parallel IO before round 2 --- src/phasicFlow/CMakeLists.txt | 8 +- src/phasicFlow/containers/Field/Field.cpp | 50 ++- src/phasicFlow/containers/Field/Field.hpp | 143 +++---- src/phasicFlow/containers/Field/Fields.cpp | 4 +- src/phasicFlow/containers/Field/Fields.hpp | 19 +- src/phasicFlow/containers/Vector/Vector.cpp | 100 +---- src/phasicFlow/containers/Vector/Vector.hpp | 39 +- src/phasicFlow/containers/Vector/Vectors.cpp | 4 +- .../containers/Vector/stdVectorHelper.hpp | 132 +++++++ .../containers/VectorHD/VectorSingle.hpp | 36 +- src/phasicFlow/containers/span/span.hpp | 21 +- src/phasicFlow/fileSystem/fileSystem.cpp | 25 +- src/phasicFlow/fileSystem/fileSystem.hpp | 17 +- src/phasicFlow/processors/processors.hpp | 10 +- .../repository/IOobject/IOPattern.cpp | 31 ++ .../repository/IOobject/IOPattern.hpp | 152 ++++++++ .../repository/IOobject/IOfileHeader.cpp | 20 +- .../repository/IOobject/IOfileHeader.hpp | 10 +- .../repository/IOobject/objectFile.cpp | 12 +- .../repository/IOobject/objectFile.hpp | 25 +- src/phasicFlow/streams/Stream/Istream.cpp | 22 ++ src/phasicFlow/streams/Stream/Istream.hpp | 7 +- src/phasicFlow/streams/Stream/Ostream.cpp | 16 + src/phasicFlow/streams/Stream/Ostream.hpp | 8 + src/phasicFlow/streams/TStream/iTstream.cpp | 10 + src/phasicFlow/streams/TStream/iTstream.hpp | 6 +- src/phasicFlow/streams/TStream/oTstream.cpp | 4 + src/phasicFlow/streams/TStream/oTstream.hpp | 10 + src/phasicFlow/streams/dataIO/dataIO.cpp | 261 +++++++++---- src/phasicFlow/streams/dataIO/dataIO.hpp | 113 ++++-- .../streams/dataIO/dataIOTemplate.cpp | 356 ++++++++++++++---- src/phasicFlow/streams/iStream/IOstream.hpp | 2 +- src/phasicFlow/streams/iStream/iIstream.hpp | 4 + src/phasicFlow/streams/iStream/iOstream.hpp | 8 +- .../infinitePlane/infinitePlane.cpp | 64 ++++ .../infinitePlane/infinitePlane.hpp | 165 ++++++++ src/phasicFlow/structuredData/line/line.hpp | 16 +- src/phasicFlow/structuredData/plane/plane.cpp | 68 ++++ src/phasicFlow/structuredData/plane/plane.hpp | 136 +++++++ 39 files changed, 1618 insertions(+), 516 deletions(-) create mode 100644 src/phasicFlow/containers/Vector/stdVectorHelper.hpp create mode 100644 src/phasicFlow/repository/IOobject/IOPattern.cpp create mode 100644 src/phasicFlow/repository/IOobject/IOPattern.hpp create mode 100644 src/phasicFlow/structuredData/infinitePlane/infinitePlane.cpp create mode 100644 src/phasicFlow/structuredData/infinitePlane/infinitePlane.hpp create mode 100644 src/phasicFlow/structuredData/plane/plane.cpp create mode 100644 src/phasicFlow/structuredData/plane/plane.hpp diff --git a/src/phasicFlow/CMakeLists.txt b/src/phasicFlow/CMakeLists.txt index d9d701eb..4f138123 100644 --- a/src/phasicFlow/CMakeLists.txt +++ b/src/phasicFlow/CMakeLists.txt @@ -4,8 +4,6 @@ types/basicTypes/bTypesFunctions.cpp types/basicTypes/Logical.cpp types/types.cpp - - globals/error.cpp streams/token/tokenIO.cpp @@ -35,10 +33,16 @@ dictionary/entry/dataEntry.cpp dictionary/twoPartEntry/twoPartEntry.cpp containers/Vector/Vectors.cpp +containers/Field/Fields.cpp repository/IOobject/objectFile.cpp repository/IOobject/IOfileHeader.cpp repository/IOobject/IOobject.cpp +repository/IOobject/IOPattern.cpp + +structuredData/line/line.cpp +structuredData/infinitePlane/infinitePlane.cpp +structuredData/plane/plane.cpp ) diff --git a/src/phasicFlow/containers/Field/Field.cpp b/src/phasicFlow/containers/Field/Field.cpp index 5569ea9b..70e33dfd 100644 --- a/src/phasicFlow/containers/Field/Field.cpp +++ b/src/phasicFlow/containers/Field/Field.cpp @@ -18,7 +18,7 @@ Licence: -----------------------------------------------------------------------------*/ -template class VectorField, class T, class PropType> +/*template class VectorField, class T, class PropType> bool pFlow::Field::readUniform ( iIstream& is, @@ -94,10 +94,10 @@ bool pFlow::Field::readNonUniform return true; -} +}*/ -template class VectorField, class T, class PropType> +/*template class VectorField, class T, class PropType> bool pFlow::Field::readField ( iIstream& is, @@ -177,6 +177,50 @@ bool pFlow::Field::writeField(iOstream& os)const os.endEntry(); + return true; +}*/ + + +template class VectorField, class T, class PropType> +bool pFlow::Field::read +( + iIstream& is, + IOPattern::IOType iotype +) +{ + + bool tokenFound; + tokenFound = is.findToken(fieldKey_); + + if( !tokenFound ) + { + ioErrorInFile( is.name(), is.lineNumber() ) << + " error in searching for filedkey " << fieldKey_<name()< class VectorField, class T, class PropType> +bool pFlow::Field::write( + iOstream& os, + IOPattern::IOType iotype)const +{ + + + os.writeWordKeyword(fieldKey_)<& vec) - : - VectorType(vec) - {} - - // construct an empty Field with fieldKey + /// Construct a field with fieldKey and Vector vec Field(const word& fieldKey, const Vector& vec) : - VectorType(vec), + VectorType(vec.name(), vec.vectorField()), fieldKey_(fieldKey) {} - // construct an empty field with name and fieldKey + /// Construct a field with name, fieldKey and Vector vec Field(const word& name, const word& fieldKey, const Vector& vec) + : + VectorType(name, vec.vectorField()), + fieldKey_(fieldKey) + {} + + /// Construct a field with name and fieldKey and std::vector + Field(const word& name, const word& fieldKey, const std::vector& vec) : VectorType(name, vec), fieldKey_(fieldKey) {} - - // - copy construct with new name and fieldkey + /// Copy construct with new name and fieldkey Field(const word& name, const word& fieldKey, const FieldType& src): VectorType(name, src), fieldKey_(fieldKey) {} - // - default copy constructor + /// Default copy constructor Field(const FieldType&) = default; - // - default copy assignment - FieldType& operator = (const FieldType&) = default; + /// Copy assignment, name and fieldKey + /// on the left hand side are preserved + FieldType& operator = (const FieldType& rhs) + { + if(&rhs == this) return *this; + VectorType::operator=(rhs); + return *this; + } - // - no move constructor - Field(FieldType&&) = delete; + /// Move constructor + Field(FieldType&&) = default; - // - no move assignment - FieldType& operator = (FieldType&&) = delete; + /// Move assignment + FieldType& operator = (FieldType&&) = default; - // - clone as a uniquePtr + /// clone as a uniquePtr INLINE_FUNCTION_H uniquePtr clone() const { return makeUnique(*this); } - // - clone as a raw pointer + /// clone as a raw pointer INLINE_FUNCTION_H FieldType* clonePtr()const { @@ -208,31 +177,27 @@ public: //// - Methods + /// return field key const word& fieldKey()const { return fieldKey_; } //// - IO operations - bool readField(iIstream& is, const size_t len, bool resume, bool readLength = true); + /*bool readField(iIstream& is, const size_t len, bool resume, bool readLength = true); bool readField(iIstream& is, bool resume ); - bool writeField(iOstream& os)const; + bool writeField(iOstream& os)const;*/ - bool read(iIstream& is, bool resume = false) - { - return readField(is, resume); - } + bool read(iIstream& is, IOPattern::IOType iotype); + - bool write(iOstream& os)const - { - return writeField(os); - } - + bool write(iOstream& os, IOPattern::IOType iotype )const; + }; @@ -240,7 +205,7 @@ public: template class VectorField, class T, class PropType> inline iIstream& operator >> (iIstream & is, Field & ifld ) { - if( !ifld.readField(is, false) ) + if( !ifld.read(is, IOPattern::MasterProcessor) ) { ioErrorInFile (is.name(), is.lineNumber()); fatalExit; @@ -252,7 +217,7 @@ template class VectorField, class T, class PropType> inline iOstream& operator << (iOstream& os, const Field& ofld ) { - if( !ofld.writeField(os) ) + if( !ofld.write(os, IOPattern::AllProcessorsDifferent) ) { ioErrorInFile(os.name(), os.lineNumber()); fatalExit; diff --git a/src/phasicFlow/containers/Field/Fields.cpp b/src/phasicFlow/containers/Field/Fields.cpp index 28779371..e43c4330 100644 --- a/src/phasicFlow/containers/Field/Fields.cpp +++ b/src/phasicFlow/containers/Field/Fields.cpp @@ -23,7 +23,7 @@ Licence: template class pFlow::Field; -template class pFlow::Field; +/*template class pFlow::Field; template class pFlow::Field; @@ -76,6 +76,6 @@ template class pFlow::Field; template class pFlow::Field; -template class pFlow::Field>; +template class pFlow::Field>;*/ diff --git a/src/phasicFlow/containers/Field/Fields.hpp b/src/phasicFlow/containers/Field/Fields.hpp index 8b2ff92c..2a4b0ca0 100644 --- a/src/phasicFlow/containers/Field/Fields.hpp +++ b/src/phasicFlow/containers/Field/Fields.hpp @@ -24,22 +24,17 @@ Licence: #include "types.hpp" #include "Field.hpp" #include "VectorSingle.hpp" -#include "VectorDual.hpp" +//#include "VectorDual.hpp" namespace pFlow { - using int8Field_D = Field; using int8Field_H = Field; -using int16Field_D = Field; - -using int16Field_H = Field; - -using int32Field_D = Field; +/*using int32Field_D = Field; using int32Field_H = Field; @@ -81,16 +76,14 @@ 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; // host device fields -using int8Field_HD = Field; - -using int16Field_HD = Field; +/*using int8Field_HD = Field; using int32Field_HD = Field; @@ -104,15 +97,13 @@ using realField_HD = Field; using realx3Field_HD = Field; -using uint16x3Field_HD = Field; - using uint32x3Field_HD = Field; using int32x3Field_HD = Field; using int64x3Field_HD = Field; -using realx3x3Field_HD = Field; +using realx3x3Field_HD = Field;*/ using wordField = Field>; diff --git a/src/phasicFlow/containers/Vector/Vector.cpp b/src/phasicFlow/containers/Vector/Vector.cpp index 71dc312a..9904d4a3 100644 --- a/src/phasicFlow/containers/Vector/Vector.cpp +++ b/src/phasicFlow/containers/Vector/Vector.cpp @@ -23,111 +23,21 @@ template bool pFlow::Vector::readVector ( iIstream& is, - size_t len + IOPattern::IOType iotype ) { - - if(is.isBinary() && !std::is_same_v) - { - this->resize(len); - is.read(reinterpret_cast(this->data()), this->size()*sizeof(T)); - } - else - { - this->clear(); - is.fatalCheck(FUNCTION_NAME); - - token firstToken(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; - this->push_back(val); - - is >> lastToken; - is.fatalCheck(FUNCTION_NAME); - } - - } else - { - warningInFunction - << "expected token "<< token::BEGIN_LIST - << " but found "<< firstToken ; - return false; - } - } - - return true; + return readStdVector(is, vectorField(), iotype); } template bool pFlow::Vector::writeVector ( - iOstream& os + iOstream& os, + IOPattern::IOType iotype ) const { - - span s( const_cast(this->data()), this->size()); - os<) - { - os.write(reinterpret_cast(this->data()), this->size()*sizeof(T)); - } - else - { - - auto len = size(); - auto stride = getVectorStride(len); - os << token::BEGIN_LIST; - size_t i = 0; - while( ioperator[](i++); - for(size_t j=0; joperator[](i++); - } - - if(i diff --git a/src/phasicFlow/containers/Vector/Vector.hpp b/src/phasicFlow/containers/Vector/Vector.hpp index 44e3beb3..3377efdc 100644 --- a/src/phasicFlow/containers/Vector/Vector.hpp +++ b/src/phasicFlow/containers/Vector/Vector.hpp @@ -33,6 +33,8 @@ Licence: #include "iOstream.hpp" #include "iIstream.hpp" +#include "stdVectorHelper.hpp" + #ifndef __RESERVE__ #define __RESERVE__ struct RESERVE{}; @@ -40,7 +42,7 @@ Licence: namespace pFlow { - + template class Vector; @@ -48,18 +50,7 @@ class Vector; #include "VectorFwd.hpp" -template -class noConstructAllocator - : public std::allocator -{ -public: - using std::allocator::allocator; - template void construct(U*, Args&&...) {} -}; - -template -using vecAllocator = std::allocator; template > class Vector @@ -351,19 +342,20 @@ public: inline VectorType operator -()const; - - bool readVector(iIstream& is, size_t len=0); + /// Read vector (assume ASCII in input) + bool readVector(iIstream& is, IOPattern::IOType iotype); - bool writeVector(iOstream& os) const; + /// write vector + bool writeVector(iOstream& os, IOPattern::IOType iotype) const; - bool read(iIstream& is) + bool read(iIstream& is, IOPattern::IOType iotype) { - return readVector(is); + return readVector(is, iotype); } - bool write(iOstream& os)const + bool write(iOstream& os, IOPattern::IOType iotype)const { - return writeVector(os); + return writeVector(os, iotype); } }; @@ -372,7 +364,7 @@ public: template inline iIstream& operator >> (iIstream & is, Vector & ivec ) { - if( !ivec.readVector(is) ) + if( !ivec.readVector(is, IOPattern::MasterProcessor) ) { ioErrorInFile (is.name(), is.lineNumber()); fatalExit; @@ -382,19 +374,16 @@ inline iIstream& operator >> (iIstream & is, Vector & ivec ) template inline iOstream& operator << (iOstream& os, const Vector& ovec ) -{ - - if( !ovec.writeVector(os) ) +{ + if( !ovec.writeVector(os, IOPattern::AllProcessorsDifferent) ) { ioErrorInFile(os.name(), os.lineNumber()); fatalExit; } - return os; } - } // pFlow diff --git a/src/phasicFlow/containers/Vector/Vectors.cpp b/src/phasicFlow/containers/Vector/Vectors.cpp index 43d2952f..8db0fb40 100644 --- a/src/phasicFlow/containers/Vector/Vectors.cpp +++ b/src/phasicFlow/containers/Vector/Vectors.cpp @@ -22,7 +22,7 @@ Licence: // instantiation just for numeral types -template class pFlow::Vector; +/*template class pFlow::Vector; template class pFlow::Vector; @@ -32,7 +32,7 @@ template class pFlow::Vector; template class pFlow::Vector; -template class pFlow::Vector; +template class pFlow::Vector;*/ diff --git a/src/phasicFlow/containers/Vector/stdVectorHelper.hpp b/src/phasicFlow/containers/Vector/stdVectorHelper.hpp new file mode 100644 index 00000000..7ffbfaf8 --- /dev/null +++ b/src/phasicFlow/containers/Vector/stdVectorHelper.hpp @@ -0,0 +1,132 @@ +/*------------------------------- 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 __stdVectorHelper_hpp__ +#define __stdVectorHelper_hpp__ + +#include +#include + +#include "span.hpp" +#include "iOstream.hpp" +#include "iIstream.hpp" +#include "dataIO.hpp" + + +namespace pFlow +{ + + +template +class noConstructAllocator + : public std::allocator +{ +public: + using std::allocator::allocator; + + template void construct(U*, Args&&...) {} +}; + +template +using vecAllocator = std::allocator; + + +template +inline +bool writeSpan( + iOstream& os, + const span& sp, + IOPattern::IOType iotype) +{ + + dataIO io(iotype); + + if(!io.writeData(os, sp)) + { + fatalErrorInFunction; + return false; + } + return true; +} + + +template +bool writeStdVector +( + iOstream& os, + const std::vector& vec, + IOPattern::IOType iotype +) +{ + span sp( const_cast(vec.data()), vec.size()); + + return writeSpan(os, sp, iotype); +} + + + + +template +bool readStdVector +( + iIstream& is, + std::vector& vec, + IOPattern::IOType iotype +) +{ + dataIO io(iotype); + + if(!io.readData(is, vec)) + { + fatalErrorInFunction; + return false; + } + return true; + +} + +template +iOstream& operator<<( iOstream& os, const std::vector& vec) +{ + if(!writeStdVector(os, vec, IOPattern::AllProcessorsDifferent)) + { + fatalErrorInFunction; + fatalExit; + } + return os; +} + +/// Always assume ASCII is in the input stream +template +iIstream& operator>>(iIstream& is, std::vector& vec) +{ + if( !readStdVector(is,vec, IOPattern::MasterProcessor)) + { + fatalErrorInFunction; + fatalExit; + } + return is; +} + +} // pFlow + + +#endif \ No newline at end of file diff --git a/src/phasicFlow/containers/VectorHD/VectorSingle.hpp b/src/phasicFlow/containers/VectorHD/VectorSingle.hpp index cf1069fd..2fa36459 100644 --- a/src/phasicFlow/containers/VectorHD/VectorSingle.hpp +++ b/src/phasicFlow/containers/VectorHD/VectorSingle.hpp @@ -26,7 +26,6 @@ Licence: #include "globalSettings.hpp" -#include "typeInfo.hpp" #include "types.hpp" #include "error.hpp" #include "indexContainer.hpp" @@ -35,7 +34,7 @@ Licence: #include "span.hpp" #include "Vector.hpp" #include "phasicFlowKokkos.hpp" - +#include "dataIO.hpp" #ifndef __RESERVE__ @@ -240,7 +239,7 @@ public: : VectorSingle(src.name(), src) { - copy(deviceVector(), src.deviceVector()); + //copy(deviceVector(), src.deviceVector()); } /// Copy construct with a new name (perform deep copy) @@ -577,34 +576,27 @@ public: //// - IO operations - /// Read vector from is stream (ASCII or Binary) - /// For binary read, len should be provided + /// Read vector from stream (ASCII) FUNCTION_H - bool readVector(iIstream& is, size_t len=0) + bool read(iIstream& is, IOPattern::IOType iotype) { - Vector vecFromFile; - if( !vecFromFile.readVector(is,len) ) return false; + std::vector vecFromFile; + if(! readStdVector(is, vecFromFile, iotype)) return false; this->assign(vecFromFile); return true; } - /// Read vector from stream (ASCII) + /// Write the vector to os FUNCTION_H - bool read(iIstream& is) - { - return readVector(is); - } - - /// Write the vector to os (ASCII or Binary) - FUNCTION_H - bool write(iOstream& os)const + bool write(iOstream& os, IOPattern::IOType iotype)const { auto hVec = hostVector(); auto sp = span( const_cast(hVec.data()), hVec.size()); - os< inline iIstream& operator >> (iIstream & is, VectorSingle & ivec ) { - if( !ivec.read(is) ) + if( !ivec.read(is, IOPattern::MasterProcessor ) ) { ioErrorInFile (is.name(), is.lineNumber()); fatalExit; @@ -624,7 +616,7 @@ template inline iOstream& operator << (iOstream& os, const VectorSingle& ovec ) { - if( !ovec.write(os) ) + if( !ovec.write(os, IOPattern::AllProcessorsDifferent) ) { ioErrorInFile(os.name(), os.lineNumber()); fatalExit; @@ -634,8 +626,6 @@ inline iOstream& operator << (iOstream& os, const VectorSingle& } - - } // - pFlow #include "VectorSingleAlgorithms.hpp" diff --git a/src/phasicFlow/containers/span/span.hpp b/src/phasicFlow/containers/span/span.hpp index 0ee41e71..094ffe1d 100644 --- a/src/phasicFlow/containers/span/span.hpp +++ b/src/phasicFlow/containers/span/span.hpp @@ -159,6 +159,7 @@ public: INLINE_FUNCTION_H bool writeASCII(iOstream& os) const { + os<< size()<0) { @@ -177,34 +178,22 @@ public: return true; } - /// Write in Binray format, can be used for numeral types (Not word or similar ones) - INLINE_FUNCTION_H - bool writeBinary(iOstream& os) const - { - os.write(reinterpret_cast(data_), this->size()*sizeof(T)); - os.check(FUNCTION_NAME); - return true; - } }; + template inline iOstream& operator<<(iOstream& os, const span& s) { - if( os.isBinary() && !std::is_same_v) - { - s.writeBinary(os); - } - else - { - s.writeASCII(os); - } + s.writeASCII(os); return os; } + + } // pFlow #endif //__span_hpp__ diff --git a/src/phasicFlow/fileSystem/fileSystem.cpp b/src/phasicFlow/fileSystem/fileSystem.cpp index 79065498..c5c5317b 100644 --- a/src/phasicFlow/fileSystem/fileSystem.cpp +++ b/src/phasicFlow/fileSystem/fileSystem.cpp @@ -41,6 +41,18 @@ bool pFlow::fileSystem::checkFileName(const word& name) } +/// From full path +pFlow::fileSystem::fileSystem(const word & wPath) +: + path_(wPath), + isDir_(std::filesystem::is_directory(path_)) +{ + std::cout<<"file name is " << fileName()<\"?\'"); + inline static word notPermittedCharsFile = word(" ") + word("&\t\n;:?*/<>\"?\'"); /// Is name is valid for a file? bool static validFileName(const word& name) { - return name.find_first_of(notPermittedCharsFile); + return name.find_first_of(notPermittedCharsFile)==word::npos; } /// Is a valid file name? @@ -107,13 +107,18 @@ public: isDir_(true) {} + /// From full path + explicit + fileSystem(const word & wPath); + /// From dir and file name - fileSystem( const word& dir, const word& file = ""); + fileSystem( const word& dir, const word& file); /// From dir and file name - fileSystem( const char* dir, const char* file = ""); + fileSystem( const char* dir, const char* file=""); /// Copy + explicit fileSystem( const pathType& path ); /// Copy diff --git a/src/phasicFlow/processors/processors.hpp b/src/phasicFlow/processors/processors.hpp index 49fe3d1f..494787a6 100644 --- a/src/phasicFlow/processors/processors.hpp +++ b/src/phasicFlow/processors/processors.hpp @@ -82,14 +82,14 @@ public: ~processors(); /// Master processors number (globaly in MPI). - static + static inline int masterNo() { return 0; } /// Is this a parallel MPI run. - static + static inline bool isParallel() { return processors::globalSize()>1; @@ -104,21 +104,21 @@ public: bool isFinalized(); /// Is this processor the master processor? - static + static inline bool isMaster() { return processors::globalRank() == processors::masterNo(); } /// Global size of processors - static + static inline int globalSize() { return globalSize_; } /// Rank of the processor in the global MPI - static + static inline int globalRank() { return globalRank_; diff --git a/src/phasicFlow/repository/IOobject/IOPattern.cpp b/src/phasicFlow/repository/IOobject/IOPattern.cpp new file mode 100644 index 00000000..ffb0eb78 --- /dev/null +++ b/src/phasicFlow/repository/IOobject/IOPattern.cpp @@ -0,0 +1,31 @@ +/*------------------------------- 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 "processors.hpp" +#include "IOPattern.hpp" + +pFlow::IOPattern::IOPattern( IOType iotype) +: + ioType_(iotype), + globalSize_(processors::globalSize()), + globalRank_(processors::globalRank()), + isMaster_(processors::isMaster()), + isParallel_(processors::isParallel()) +{} + diff --git a/src/phasicFlow/repository/IOobject/IOPattern.hpp b/src/phasicFlow/repository/IOobject/IOPattern.hpp new file mode 100644 index 00000000..c539aabb --- /dev/null +++ b/src/phasicFlow/repository/IOobject/IOPattern.hpp @@ -0,0 +1,152 @@ +/*------------------------------- 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 __IOPattern_hpp__ +#define __IOPattern_hpp__ + + +#include "processors.hpp" + +namespace pFlow +{ + + +class IOPattern +{ +public: + + /** + * Type of input/output + * + * MasterProcessorOnly: Read or write is done on master processor + * and the data on master processor is affected. + * + * MasterProcessorDistribute: Read is done on master processor, but + * the data should be distributed between processors based on an externally + * specified pattern. Write is done on master processors and the data is + * collected from all processors (collection is done based on the externally + * specified pattern). + * + * AllProcessorsSimilar: Read is done on all processors and processors + * read the same data. Write is done on master processor, since + * all processors have the same copy of data. + */ + enum IOType : int + { + MasterProcessorOnly = 0, + AllProcessorsSimilar = 1, + MasterProcessorDistribute = 4 + }; + +protected: + + IOType ioType_; + + int globalSize_ = 1; + + int globalRank_ = 0; + + bool isMaster_ = true; + + bool isParallel_ = false; + +public: + + IOPattern( IOType iotype); + + IOPattern(const IOPattern&)=default; + + IOPattern& operator=(const IOPattern&)=default; + + ~IOPattern() = default; + + inline + bool isMasterProcessorOnly()const + { + return ioType_ == MasterProcessorOnly; + } + + inline + bool isAllProcessorSimilar()const + { + return ioType_ == AllProcessorsSimilar; + } + + inline + bool isMasterProcessorDistribute()const + { + return ioType_ == MasterProcessorDistribute; + } + + inline + bool isMaster()const + { + return isMaster_; + } + + inline + bool isParallel()const + { + return isParallel_; + } + + inline + bool thisProcReadData()const + { + if(isMasterProcessor() && !isMaster())return false; + if(isMasterProcessorDistribute() && !isMaster()) return false; + return true; + } + + inline + bool thisProcWriteData()const + { + return isMaster(); + } + + inline + bool thisProcReadHeader()const + { + return thisProcReadData(); + } + + inline + bool thisProcWriteHeader()const + { + return isMaster(); + } + + inline + auto globalSize()const + { + return globalSize_; + } + + inline + auto globalRank()const + { + return globalRank_; + } + +}; + +} + +#endif //__IOPattern_hpp__ \ No newline at end of file diff --git a/src/phasicFlow/repository/IOobject/IOfileHeader.cpp b/src/phasicFlow/repository/IOobject/IOfileHeader.cpp index 8c92c944..3015dc2a 100644 --- a/src/phasicFlow/repository/IOobject/IOfileHeader.cpp +++ b/src/phasicFlow/repository/IOobject/IOfileHeader.cpp @@ -135,6 +135,7 @@ bool pFlow::IOfileHeader::readIfPresent()const bool pFlow::IOfileHeader::writeHeader()const { + if( !this->readWriteHeader() ) return false; if( !processors::isMaster() ) return false; if( !implyWrite() ) return false; @@ -150,7 +151,10 @@ bool pFlow::IOfileHeader::writeHeader ) const { - if(!forceWrite && !writeHeader()) return true; + if(!forceWrite) + { + if(!writeHeader()) return true; + } writeBanner(os); @@ -180,8 +184,9 @@ bool pFlow::IOfileHeader::writeHeader(iOstream& os, bool forceWrite) const bool pFlow::IOfileHeader::readHeader()const { - if( !this->readWriteHeader() ) return false; - return true; + if( !implyRead())return false; + if( !this->readWriteHeader() ) return false; + return ioPattern().thisProcReadHeader(); } bool pFlow::IOfileHeader::readHeader(iIstream& is, bool silent) @@ -228,15 +233,14 @@ bool pFlow::IOfileHeader::readHeader(iIstream& is, bool silent) bool pFlow::IOfileHeader::writeData()const { - if( processors::isMaster() || this->differentDataOnProcessors()) - return true; - else - return false; + if(!implyWrite())return false; + return ioPattern().thisProcWriteData(); } bool pFlow::IOfileHeader::readData()const { - return true; + if(!implyRead())return false; + return ioPattern().thisProcReadData(); } bool pFlow::IOfileHeader::writeBanner(iOstream& os)const diff --git a/src/phasicFlow/repository/IOobject/IOfileHeader.hpp b/src/phasicFlow/repository/IOobject/IOfileHeader.hpp index e019a79e..569e6ab6 100644 --- a/src/phasicFlow/repository/IOobject/IOfileHeader.hpp +++ b/src/phasicFlow/repository/IOobject/IOfileHeader.hpp @@ -109,7 +109,7 @@ public: /// Check if the header should be written to file /// True: on master + implyWrite + readWriteHeader = true - /// False: slave or NOT implyWrite + /// False: otherwise bool writeHeader()const; /// Write the header to the file , typeName comes from caller @@ -119,13 +119,9 @@ public: bool writeHeader(iOstream& os, bool forceWrite = false) const; /// Check if the data should be written to file - /// True: on master or differentDataOnProcessor is true - /// False: otherwise bool writeData()const; /// Check if header should be read from file - /// True: All processors, read the file header - /// False: readWriteHeader = false bool readHeader()const; /// Read the header in the file @@ -135,10 +131,10 @@ public: /// Always return true bool readData()const; - // - write the banner + /// write the banner bool writeBanner(iOstream& os)const; - // - wirte a separator line + /// wirte a separator line bool writeSeparator(iOstream& os)const; }; diff --git a/src/phasicFlow/repository/IOobject/objectFile.cpp b/src/phasicFlow/repository/IOobject/objectFile.cpp index c9957daf..a0b41f0c 100644 --- a/src/phasicFlow/repository/IOobject/objectFile.cpp +++ b/src/phasicFlow/repository/IOobject/objectFile.cpp @@ -30,11 +30,11 @@ pFlow::objectFile::objectFile pFlow::objectFile::objectFile ( - const word& name, - const fileSystem& localPath, - const readFlag& rf, - const writeFlag& wf, - bool diffDataOnProcessors, + const word& name, + const fileSystem& localPath, + const readFlag& rf, + const writeFlag& wf, + IOPattern::IOType ioType, bool rwHdr ) : @@ -42,7 +42,7 @@ pFlow::objectFile::objectFile rFlag_(rf), wFlag_(wf), localPath_(localPath), - differentDataOnProcessors_(diffDataOnProcessors), + ioPattern_(ioType), readWriteHeader_(rwHdr) { } \ No newline at end of file diff --git a/src/phasicFlow/repository/IOobject/objectFile.hpp b/src/phasicFlow/repository/IOobject/objectFile.hpp index 6dd70ca2..39f9adf8 100644 --- a/src/phasicFlow/repository/IOobject/objectFile.hpp +++ b/src/phasicFlow/repository/IOobject/objectFile.hpp @@ -23,6 +23,7 @@ Licence: #include "types.hpp" #include "fileSystem.hpp" +#include "IOPattern.hpp" namespace pFlow @@ -47,6 +48,7 @@ public: WRITE_NEVER }; + protected: /// Name of the entity @@ -61,16 +63,10 @@ protected: /// Local path of entity fileSystem localPath_ = ""; - /// Number of bytes used for writing/reading real variable (mostly used for binray) + /// Number of bytes used for writing/reading real variable (used for binray) int numBytesForReal_ = numBytesForReal__; - /// All processors have the different set of data or not? - /// True: Each processor should read its own part of data from file and should write - /// its own part of data to the file. - /// Flase: All processors read the same data from file and in writing, only master data - /// write the data to the file. - - bool differentDataOnProcessors_ = true; + IOPattern ioPattern_ = {IOPattern::MasterProcessor}; /// Does the objectFile write the header or not bool readWriteHeader_ = true; @@ -89,10 +85,10 @@ public: objectFile ( const word& name, - const fileSystem& localPath, - const readFlag& rf = READ_NEVER, - const writeFlag& wf = WRITE_NEVER, - bool diffDataOnProcessors = true, + const fileSystem& localPath, + const readFlag& rf = READ_NEVER, + const writeFlag& wf = WRITE_NEVER, + IOPattern::IOType ioType = IOPattern::MasterProcessor, bool rwHdr = true ); @@ -160,10 +156,9 @@ public: return wFlag_ == WRITE_NEVER; } - inline - bool differentDataOnProcessors()const + const IOPattern& ioPattern()const { - return differentDataOnProcessors_; + return ioPattern_; } inline diff --git a/src/phasicFlow/streams/Stream/Istream.cpp b/src/phasicFlow/streams/Stream/Istream.cpp index be2ea9cb..3786448a 100755 --- a/src/phasicFlow/streams/Stream/Istream.cpp +++ b/src/phasicFlow/streams/Stream/Istream.cpp @@ -899,6 +899,28 @@ void pFlow::Istream::rewind() stdStream().rdbuf()->pubseekpos(0, std::ios_base::in); } +void pFlow::Istream::seek(size_t pos) +{ + stdStream().clear(); // Clear the iostate error state flags + setGood(); // Sync local copy of iostate + resetPutBack(); + // pubseekpos() rather than seekg() so that it works with gzstream + stdStream().rdbuf()->pubseekpos(pos, std::ios_base::in); +} + +size_t pFlow::Istream::tell() +{ + + auto pos = static_cast(stdStream().tellg()); + if(stdStream().fail()) + { + fatalErrorInFunction<< + "Error in getting current position from stream "<< + this->name()<endl(); + this->flush(); +} + +void pFlow::Ostream::endOfBinaryStreaming() +{ + os_.seekp(0, std::ios_base::end); + this->endl(); + this->flush(); +} void pFlow::Ostream::flush() { diff --git a/src/phasicFlow/streams/Stream/Ostream.hpp b/src/phasicFlow/streams/Stream/Ostream.hpp index 4d5f3205..256270b5 100755 --- a/src/phasicFlow/streams/Stream/Ostream.hpp +++ b/src/phasicFlow/streams/Stream/Ostream.hpp @@ -132,12 +132,20 @@ public: iOstream& writeBinaryBlockFlag() override; + void seek(size_t pos) override; + /// Add indentation characters void indent() override; /// Set stream flags ios_base::fmtflags flags(const ios_base::fmtflags f) override; + /// Add a new line and flush stream + void startOfBinaryStreaming() override; + + /// Reach end of file add a new line and flush stream + void endOfBinaryStreaming() override ; + /// Flush stream void flush() override; diff --git a/src/phasicFlow/streams/TStream/iTstream.cpp b/src/phasicFlow/streams/TStream/iTstream.cpp index a786561a..49b80cee 100755 --- a/src/phasicFlow/streams/TStream/iTstream.cpp +++ b/src/phasicFlow/streams/TStream/iTstream.cpp @@ -309,6 +309,10 @@ void pFlow::iTstream::rewind() setGood(); } +void pFlow::iTstream::seek(size_t pos) +{ + notImplementedFunction; +} void pFlow::iTstream::reset() { @@ -318,6 +322,12 @@ void pFlow::iTstream::reset() setGood(); } +size_t pFlow::iTstream::tell() +{ + notImplementedFunction; + return -1; +} + const pFlow::tokenList& pFlow::iTstream::tokens()const { return tokenList_; diff --git a/src/phasicFlow/streams/TStream/iTstream.hpp b/src/phasicFlow/streams/TStream/iTstream.hpp index 8bb2e824..2f7e0786 100755 --- a/src/phasicFlow/streams/TStream/iTstream.hpp +++ b/src/phasicFlow/streams/TStream/iTstream.hpp @@ -130,7 +130,11 @@ public: iIstream& read(char* buffer, std::streamsize count) override; /// Rewind the stream so that it may be read again - virtual void rewind(); + virtual void rewind()override; + + void seek(size_t pos) override; + + size_t tell() override; /// reset the iTstream and make the stream empty virtual void reset(); diff --git a/src/phasicFlow/streams/TStream/oTstream.cpp b/src/phasicFlow/streams/TStream/oTstream.cpp index 381dfaa1..35c9d0c8 100755 --- a/src/phasicFlow/streams/TStream/oTstream.cpp +++ b/src/phasicFlow/streams/TStream/oTstream.cpp @@ -173,6 +173,10 @@ pFlow::iOstream& pFlow::oTstream::write return *this; } +void pFlow::oTstream::seek(size_t pos) +{ + notImplementedFunction; +} void pFlow::oTstream::append(const token& tok) { diff --git a/src/phasicFlow/streams/TStream/oTstream.hpp b/src/phasicFlow/streams/TStream/oTstream.hpp index 23752a5d..110e9410 100755 --- a/src/phasicFlow/streams/TStream/oTstream.hpp +++ b/src/phasicFlow/streams/TStream/oTstream.hpp @@ -132,6 +132,8 @@ public: /// Write double virtual iOstream& write(const size_t val) override; + void seek(size_t pos) override; + /// Write a block of binray data iOstream& write( const char* binaryData, @@ -157,6 +159,14 @@ public: virtual void indent() {} + /// Add a new line and flush stream + virtual void startOfBinaryStreaming() + {} + + /// Reach end of file add a new line and flush stream + virtual void endOfBinaryStreaming() + {} + /// Flush stream virtual void flush() {} diff --git a/src/phasicFlow/streams/dataIO/dataIO.cpp b/src/phasicFlow/streams/dataIO/dataIO.cpp index 9789c56e..4f44f21e 100644 --- a/src/phasicFlow/streams/dataIO/dataIO.cpp +++ b/src/phasicFlow/streams/dataIO/dataIO.cpp @@ -7,12 +7,9 @@ #include #include - #include "dataIO.hpp" -#include "fileSystem.hpp" -#include "streams.hpp" static const size_t numcharFlag = 8; @@ -43,19 +40,18 @@ pFlow::uint64 findBindaryBlockFlagSTD(std::FILE* fh) if( fpos = std::ftell( fh) ; fpos == -1L ) { fatalErrorInFunction; - return -1; + return pFlow::dataIO::ErrorReturn; } pFlow::uint64 filePos = static_cast(fpos); // start reading char by char - int c; unsigned char ch; int currPos = 0; while ( std::fread(&ch, sizeof(ch), 1, fh) == 1 ) { - if(std::ferror(fh)) return -1; - if(std::feof(fh))return -1; + if(std::ferror(fh)) return pFlow::dataIO::ErrorReturn; + if(std::feof(fh))return pFlow::dataIO::ErrorReturn; filePos++; @@ -71,22 +67,16 @@ pFlow::uint64 findBindaryBlockFlagSTD(std::FILE* fh) } } - return -1; + return pFlow::dataIO::ErrorReturn; } #ifdef pFlow_Build_MPI -pFlow::uint64 findBindaryBlockFlagMPI(MPI_File fh) +pFlow::uint64 findBindaryBlockFlagMPI(MPI_File fh, pFlow::uint64 startPosSearch) { - // get the current postion - MPI_Offset fpos; - if( MPI_File_get_position( fh, &fpos) != MPI_SUCCESS ) - { - fatalErrorInFunction; - return false; - } + - pFlow::uint64 filePos = static_cast(fpos); + pFlow::uint64 filePos = static_cast(startPosSearch); // start reading char by char unsigned char ch; @@ -114,7 +104,7 @@ pFlow::uint64 findBindaryBlockFlagMPI(MPI_File fh) } } - return -1; + return pFlow::dataIO::ErrorReturn; } #endif @@ -122,21 +112,18 @@ pFlow::uint64 findBindaryBlockFlagMPI(MPI_File fh) bool pFlow::dataIO::writeDataToFileEndSTD ( - const fileSystem& filePath, + const word& wordPath, const span& data ) { - if(!processors::isMaster()) return true; - // openfile - word wFile = filePath.wordPath(); - auto fh = std::fopen(wFile.c_str(), "ab"); + auto fh = std::fopen(wordPath.c_str(), "ab"); if(!fh) { fatalErrorInFunction<< - "Error in Opening file "<< filePath <(std::ftell(fh)); + // close the file std::fclose(fh); @@ -205,7 +196,7 @@ bool pFlow::dataIO::writeDataToFileEndSTD bool pFlow::dataIO::writeDataToFileEndMPI ( - const fileSystem& filePath, + const word& wordPath, const span& data ) { @@ -223,19 +214,18 @@ bool pFlow::dataIO::writeDataToFileEndMPI true ); - word wFile = filePath.wordPath(); MPI_File fh; if( MPI_File_open( MPI_COMM_WORLD, - wFile.c_str(), + wordPath.c_str(), MPI_MODE_WRONLY+MPI_MODE_APPEND, MPI_INFO_NULL, &fh) != MPI_SUCCESS) { fatalErrorInFunction<< - "Cannot open file "<< filePath< chunkSizes, span& data, uint64 binaryBlockStart ) { + + // sum of all chuncks uint64 toRecv = std::accumulate( chunkSizes.begin(), @@ -366,27 +376,29 @@ bool pFlow::dataIO::readDataSTD return false; } - word wFile = filePath.wordPath(); - auto fh = std::fopen(wFile.c_str(), "rb"); + + auto fh = std::fopen(wordPath.c_str(), "rb"); if(!fh) { fatalErrorInFunction<< - "Error in Opening file "<< filePath<(std::ftell(fh)); + std::fclose(fh); return true; } @@ -407,7 +421,7 @@ bool pFlow::dataIO::readDataSTD bool pFlow::dataIO::readDataMPI ( - const fileSystem& filePath, + const word& wordPath, const std::vector chunkSizes, span& data, uint64 binaryBlockStart @@ -416,19 +430,12 @@ bool pFlow::dataIO::readDataMPI #ifdef pFlow_Build_MPI - if(chunkSizes.size() != processors::globalSize() ) - { - fatalErrorInFunction; - return false; - } - - word wFile = filePath.wordPath(); MPI_File fh; if( MPI_File_open( MPI_COMM_WORLD, - wFile.c_str(), + wordPath.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &fh)) @@ -470,29 +477,47 @@ bool pFlow::dataIO::readDataMPI fatalErrorInFunction; return false; } -#else + + MPI_File_close(&fh); + uint64 lastPos = offset + data.size(); + /*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 ) { - word wFile = filePath.wordPath(); #ifdef pFlow_Build_MPI MPI_File fh; if(MPI_File_open( MPI_COMM_WORLD, - wFile.c_str(), + wordPath.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &fh) != MPI_SUCCESS) @@ -502,8 +527,8 @@ bool pFlow::dataIO::readMetaMPI } - uint64 startPos = findBindaryBlockFlagMPI(fh); - if( startPos == -1 ) + uint64 startPos = findBindaryBlockFlagMPI(fh, startPosSearch); + if( startPos == pFlow::dataIO::ErrorReturn ) { fatalErrorInFunction; return false; @@ -539,36 +564,53 @@ bool pFlow::dataIO::readMetaMPI fatalErrorInFunction; return false; } - MPI_File_close(&fh); -#endif + uint64 lastPos = startPos + sizeof(numProcInFile) + chunkSizes.size(); + return maxReduction(lastPos, lastPosRead_); - return true; + /*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 ) { - // only on master - if( !processors::isMaster()) return true; - word wFile = filePath.wordPath(); - std::FILE *fh = std::fopen(wFile.c_str(), "rb"); + std::FILE *fh = std::fopen(wordPath.c_str(), "rb"); if(!fh) { fatalErrorInFunction<< - "Error in Opening file "<< filePath<(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"<(-1); + protected: - IOType IOType_; + IOPattern ioPattern_; + + uint64 lastPosWrite_ = 0; + + uint64 lastPosRead_ = 0; bool writeDataToFileEndSTD( - const fileSystem& filePath, + const word& wordPath, const span& data); bool writeDataToFileEndMPI( - const fileSystem& filePath, + const word& wordPath, const span& data); bool readDataSTD( - const fileSystem& filePath, + const word& wordPath, const std::vector chunkSizes, span& data, uint64 binaryBlockStart); bool readDataMPI( - const fileSystem& filePath, + const word& wordPath, const std::vector chunkSizes, span& data, uint64 binaryBlockStart); bool readMetaMPI( - const fileSystem& filePath, + const word& wordPath, std::vector& chunkSizes, + uint64 startPosSearch, uint64 &startPosBinaryBlock); bool readMetaSTD( - const fileSystem& filePath, + const word& wordPath, std::vector& chunkSizes, + uint64 startPosSearch, uint64 &startPosBinaryBlock); + bool waitForAllMPI(); + + bool maxReduction( uint64& src, uint64& dst); + + bool BcastPos(uint64 & pos); + public: - dataIO(IOType ioT) + dataIO(IOPattern::IOType iotype) : - IOType_(ioT) + ioPattern_(iotype) {} ~dataIO()=default; template bool writeDataEnd( - const fileSystem& filePath, + const word& wordPath, const span& data); + template + bool writeAsciiEnd( + iOstream& os, + const span& data); + + template + bool readDataBinary( + const word& wordPath, + std::vector& data, + uint64 startPos = 0); + + template + bool readAscii( + iIstream& is, + std::vector& vec ); + template bool readData( - const fileSystem& filePath, - std::vector& data); + iIstream& is, + std::vector& vec, + bool resume = false); // resume only works for binary + // for ascii, by default it starts from the current position + + + template + bool writeData(iOstream& os, + const span& data); - }; +template<> +inline +bool pFlow::dataIO::writeData +( + iOstream& os, + const span& data +) +{ + if( !writeAsciiEnd(os, data) ) + { + fatalErrorInFunction; + return false; + } + return true; +} + +template<> +inline +bool pFlow::dataIO::readData( + iIstream& is, + std::vector& vec, + bool resume) +{ + if(!readAscii(is, vec)) + { + fatalErrorInFunction; + return false; + } + return true; +} + + } #include "dataIOTemplate.cpp" diff --git a/src/phasicFlow/streams/dataIO/dataIOTemplate.cpp b/src/phasicFlow/streams/dataIO/dataIOTemplate.cpp index b8450f97..54b1452f 100644 --- a/src/phasicFlow/streams/dataIO/dataIOTemplate.cpp +++ b/src/phasicFlow/streams/dataIO/dataIOTemplate.cpp @@ -1,112 +1,320 @@ - template bool pFlow::dataIO::writeDataEnd( - const fileSystem& filePath, + const word& wordPath, const span& data) { - span charSpan( + if( ioPattern_.thisProcWriteData() ) + { + span charSpan( reinterpret_cast (const_cast(data.data())), data.size()*sizeof(T)); - switch (IOType_) + if( ioPattern_.isParallel() ) + { + return writeDataToFileEndMPI(wordPath, charSpan); + } + else + { + return writeDataToFileEndSTD(wordPath, charSpan); + } + } + else { - case MasterProcessor: - case AllProcessorsSimilar: - { - // This means that only master processor should write - // in this case we perform write on master processor only - // this means that the data - if(processors::isMaster()) - { - return writeDataToFileEndSTD(filePath, charSpan); - } - else - { - return true; - } - break; - } - case AllProcessorsDifferent: - { - // This means that all processors should write their own - // copy of data - return writeDataToFileEndMPI(filePath, charSpan); - break; - } + return true; } return false; } template -bool pFlow::dataIO::readData +bool pFlow::dataIO::writeAsciiEnd ( - const fileSystem& filePath, - std::vector& data + iOstream& os, + const span& data ) { + if(ioPattern_.thisProcWriteData()) + { + return data.writeASCII(os); + } + else + return true; +} + + + +template +bool pFlow::dataIO::readDataBinary +( + const word& wordPath, + std::vector& data, + uint64 startPos +) +{ + std::vector chunkSizes; uint64 startPosBinaryBlock; - // read meta data - switch (IOType_) - { - case MasterProcessor: - { - if(!readMetaSTD( - filePath, - chunkSizes, - startPosBinaryBlock)) - { - return false; - } - break; - } - case AllProcessorsDifferent: - case AllProcessorsSimilar: - { - if(!readMetaMPI( - filePath, - chunkSizes, - startPosBinaryBlock)) - { - return false; - } - break; - } - } - data.clear(); - if(IOType_ == MasterProcessor) + + if( ioPattern_.thisProcReadData()) { - auto sizeOfData = std::accumulate( + + // read meta + if(!readMetaSTD( + wordPath, + chunkSizes, + startPos, + startPosBinaryBlock)) + { + fatalErrorInFunction; + return false; + } + + + if( ioPattern_.isMasterProcessor() || + ioPattern_.isAllProcessorSimilar() + ) + { + + auto sizeOfData = std::accumulate( chunkSizes.begin(), chunkSizes.end(), static_cast(0)); + + + data.resize(sizeOfData/sizeof(T)); - data.resize(sizeOfData/sizeof(T)); + span charSpan( + reinterpret_cast(data.data()), + data.size()*sizeof(T)); - span charSpan( - reinterpret_cast(data.data()), - data.size()*sizeof(T)); + if(!readDataSTD(wordPath, chunkSizes, charSpan, startPosBinaryBlock)) + { + fatalErrorInFunction; + return false; + } - readDataSTD(filePath, chunkSizes, charSpan, startPosBinaryBlock); + return true; + + } + else if( ioPattern_.isAllProcessorDifferent() ) + { + + if(chunkSizes.size() != ioPattern_.globalSize()) + { + if( ioPattern_.isMaster()) + { + auto sizeOfData = std::accumulate( + chunkSizes.begin(), + chunkSizes.end(), + static_cast(0)); + + + data.resize(sizeOfData/sizeof(T)); + + span charSpan( + reinterpret_cast(data.data()), + data.size()*sizeof(T)); + + if(!readDataSTD(wordPath, chunkSizes, charSpan, startPosBinaryBlock)) + { + fatalErrorInFunction; + return false; + } + return true; + + } + else + { + return true; + } + } + else + { + auto thisProc = ioPattern_.globalRank(); + + data.resize(chunkSizes[thisProc]/sizeof(T)); + + span charSpan( + reinterpret_cast(data.data()), + data.size()*sizeof(T)); + + + if( !readDataMPI(wordPath, chunkSizes, charSpan, startPosBinaryBlock) ) + { + fatalErrorInFunction; + return false; + } + return true; + } + + + } + else + { + fatalErrorInFunction; + return false; + } } - if( IOType_ == AllProcessorsDifferent ) + else { - auto thisProc = processors::globalRank(); + return true; + } - data.resize(chunkSizes[thisProc]/sizeof(T)); + return false; + + +} - span charSpan( - reinterpret_cast(data.data()), - data.size()*sizeof(T)); +template +bool pFlow::dataIO::readAscii +( + iIstream& is, + std::vector& vec +) +{ - std::cout<<"MPI part"<> 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::readData +( + iIstream& is, + std::vector& vec, + bool resume +) +{ + if(is.isBinary()) + { + uint64 currPos = 0; + if( resume ) + { + currPos = is.tell(); + } + + if(! BcastPos(currPos) ) return false; + + if(!this->readDataBinary(is.name(), vec, currPos)) + { + fatalErrorInFunction; + return false; + } + + auto lastPos = lastPosRead_; + maxReduction( lastPos, lastPosRead_); + //std::cout<<"last post read "<< lastPosRead_< +bool pFlow::dataIO::writeData +( + iOstream& os, + const span& sp +) +{ + if( os.isBinary() ) + { + os.startOfBinaryStreaming(); + + if(!writeDataEnd(os.name(), sp)) + { + fatalErrorInFunction; + return false; + } + + os.endOfBinaryStreaming(); + + } + else + { + if( !writeAsciiEnd(os, sp) ) + { + fatalErrorInFunction; + return false; + } + } + return true; + +} + + + diff --git a/src/phasicFlow/streams/iStream/IOstream.hpp b/src/phasicFlow/streams/iStream/IOstream.hpp index a0f037de..3a6982cf 100644 --- a/src/phasicFlow/streams/iStream/IOstream.hpp +++ b/src/phasicFlow/streams/iStream/IOstream.hpp @@ -180,7 +180,7 @@ public: bool isBinary()const { return writeFormat_ == BINARY; - } + } /// Return true if next operation might succeed bool good() const diff --git a/src/phasicFlow/streams/iStream/iIstream.hpp b/src/phasicFlow/streams/iStream/iIstream.hpp index 7f0ddb43..2dbf0fa9 100755 --- a/src/phasicFlow/streams/iStream/iIstream.hpp +++ b/src/phasicFlow/streams/iStream/iIstream.hpp @@ -134,6 +134,10 @@ public: /// Rewind the stream so that it may be read again virtual void rewind() = 0; + virtual void seek(size_t pos) = 0; + + /// Return current position indicator + virtual size_t tell() = 0; ////- find and lookups diff --git a/src/phasicFlow/streams/iStream/iOstream.hpp b/src/phasicFlow/streams/iStream/iOstream.hpp index 1a82f8b1..ceaa2edd 100644 --- a/src/phasicFlow/streams/iStream/iOstream.hpp +++ b/src/phasicFlow/streams/iStream/iOstream.hpp @@ -144,7 +144,7 @@ public: /// Write the flag to indicate the start of a binary block virtual iOstream& writeBinaryBlockFlag(); - + virtual void seek(size_t pos) = 0; //// - Indent /// Add indentation characters @@ -238,6 +238,12 @@ public: ////- Stream state functions + /// Add a new line and flush stream + virtual void startOfBinaryStreaming() =0; + + /// Reach end of file add a new line and flush stream + virtual void endOfBinaryStreaming() = 0 ; + /// Flush stream virtual void flush() = 0; diff --git a/src/phasicFlow/structuredData/infinitePlane/infinitePlane.cpp b/src/phasicFlow/structuredData/infinitePlane/infinitePlane.cpp new file mode 100644 index 00000000..d9f41a38 --- /dev/null +++ b/src/phasicFlow/structuredData/infinitePlane/infinitePlane.cpp @@ -0,0 +1,64 @@ +/*------------------------------- 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 "infinitePlane.hpp" + +pFlow::infinitePlane::infinitePlane +( + const realx3& p1, + const realx3& p2, + const realx3& p3 +) +{ + auto ln = cross(p2-p1, p3-p1); + + if( equal(ln.length(),0.0) ) + { + fatalErrorInFunction<< + "invalid input to form a infinte wall "<< realx3x3(p1,p2,p3)<("normal", normal_)) return false; + if(!is.nextData("d", d_)) return false; + return true; +} + +bool pFlow::infinitePlane::validPlane3 +( + const realx3& p1, + const realx3& p2, + const realx3& p3 +) +{ + return !equal(cross(p2-p1, p3-p1).length(), 0.0); +} \ No newline at end of file diff --git a/src/phasicFlow/structuredData/infinitePlane/infinitePlane.hpp b/src/phasicFlow/structuredData/infinitePlane/infinitePlane.hpp new file mode 100644 index 00000000..3140915c --- /dev/null +++ b/src/phasicFlow/structuredData/infinitePlane/infinitePlane.hpp @@ -0,0 +1,165 @@ +/*------------------------------- 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 __infinitePlane_hpp__ +#define __infinitePlane_hpp__ + +#include "types.hpp" +//#include "dictionary.hpp" +#include "iIstream.hpp" +#include "iOstream.hpp" + +namespace pFlow +{ + +class infinitePlane +{ +protected: + + /// normal vector + realx3 normal_{1,0,0}; + + /// distance value + real d_ = 0; + +public: + + // - type info + TypeInfoNV("infinitePlane"); + + //// - Constructors + + /// Default + INLINE_FUNCTION_HD + infinitePlane(){} + + /// From components + INLINE_FUNCTION_HD + infinitePlane(const realx3& normal, const real& d) + : + normal_(normal), + d_(d) + {} + + INLINE_FUNCTION_HD + infinitePlane(const realx3& normal, const realx3& p) + : + normal_(normal), + d_(-dot(normal,p)) + {} + + /// From 3 points + infinitePlane(const realx3& p1, const realx3& p2, const realx3& p3); + + FUNCTION_HD + infinitePlane(const infinitePlane&) = default; + + FUNCTION_HD + infinitePlane(infinitePlane&&) = default; + + FUNCTION_HD + infinitePlane& operator=(const infinitePlane&) = default; + + FUNCTION_HD + infinitePlane& operator=(infinitePlane&&) = default; + + ~infinitePlane()=default; + + /*FUNCTION_H + infinitePlane(const dictionary& dict); + + FUNCTION_H + infinitePlane(iIstream& is);*/ + + + //// - Methods + + INLINE_FUNCTION_HD + real pointFromPlane(const realx3& p)const + { + return dot(normal_, p) + d_; + } + + INLINE_FUNCTION_HD + bool pointInPositiveSide(const realx3& p)const + { + return pointFromPlane(p)>=0; + } + + INLINE_FUNCTION_HD + bool pointInNegativeSide(const realx3& p)const + { + return pointFromPlane(p)<0; + } + + INLINE_FUNCTION_HD + bool pointOnPlane(const realx3& p)const + { + return equal(pointFromPlane(p),0.0); + } + + INLINE_FUNCTION_HD + realx3 projectPoint(const realx3& p)const + { + real t = -(dot(normal_, p) + d_); + return t*normal_ + p; + } + + //// - IO operation + + FUNCTION_H + bool write(iOstream& os)const; + + bool read(iIstream & is); + + /*FUNCTION_H + bool read(iIstream & is); + + FUNCTION_H + bool write(iOstream& os)const; + + FUNCTION_H + bool read(const dictionary& dict); + + FUNCTION_H + bool write(dictionary& dict)const;*/ + + static bool validPlane3( + const realx3& p1, + const realx3& p2, + const realx3& p3); +}; + +/*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 // __infinitePlane_hpp__ diff --git a/src/phasicFlow/structuredData/line/line.hpp b/src/phasicFlow/structuredData/line/line.hpp index a8a302e2..375588a4 100755 --- a/src/phasicFlow/structuredData/line/line.hpp +++ b/src/phasicFlow/structuredData/line/line.hpp @@ -55,19 +55,27 @@ public: FUNCTION_HD line(const realx3 &lp1, const realx3 &lp2); + INLINE_FUNCTION_HD + line(const realx3 &v21, const realx3 &p1, bool) + : + v21_(v21), + p1_(p1) + {} + + FUNCTION_H line(const dictionary& dict); - FUNCTION_HD + INLINE_FUNCTION_HD line(const line& src) = default; - FUNCTION_HD + INLINE_FUNCTION_HD line(line&& src) = default; - FUNCTION_HD + INLINE_FUNCTION_HD line& operator = (const line&) = default; - FUNCTION_HD + INLINE_FUNCTION_HD line& operator = (line&&) = default; diff --git a/src/phasicFlow/structuredData/plane/plane.cpp b/src/phasicFlow/structuredData/plane/plane.cpp new file mode 100644 index 00000000..fbac188c --- /dev/null +++ b/src/phasicFlow/structuredData/plane/plane.cpp @@ -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. + +-----------------------------------------------------------------------------*/ + +#include "plane.hpp" + +pFlow::plane::plane +( + const realx3& p1, + const realx3& p2, + const realx3& p3, + const realx3& p4 +) +: + infinitePlane(p1,p2,p3), + p1_(p1), + p2_(p2), + p3_(p3), + p4_(p4) +{ + + if(!pointOnPlane(p4)) + { + fatalErrorInFunction<< + "points "<< realx4x3(p1,p2,p3,p4)<<" do not form a planner surface"<