Parallel IO before round 2
This commit is contained in:
parent
66fc880fcd
commit
d65aa02cbb
|
@ -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
|
||||
|
||||
)
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ Licence:
|
|||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
template<template<class, class> class VectorField, class T, class PropType>
|
||||
/*template<template<class, class> class VectorField, class T, class PropType>
|
||||
bool pFlow::Field<VectorField, T, PropType>::readUniform
|
||||
(
|
||||
iIstream& is,
|
||||
|
@ -94,10 +94,10 @@ bool pFlow::Field<VectorField, T, PropType>::readNonUniform
|
|||
|
||||
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
template<template<class, class> class VectorField, class T, class PropType>
|
||||
/*template<template<class, class> class VectorField, class T, class PropType>
|
||||
bool pFlow::Field<VectorField, T, PropType>::readField
|
||||
(
|
||||
iIstream& is,
|
||||
|
@ -177,6 +177,50 @@ bool pFlow::Field<VectorField, T, PropType>::writeField(iOstream& os)const
|
|||
|
||||
os.endEntry();
|
||||
|
||||
return true;
|
||||
}*/
|
||||
|
||||
|
||||
template<template<class, class> class VectorField, class T, class PropType>
|
||||
bool pFlow::Field<VectorField, T, PropType>::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_<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !VectorType::read(is, iotype) )
|
||||
{
|
||||
ioErrorInFile(is.name(), is.lineNumber())<<
|
||||
"error in reading field data from field "<< this->name()<<endl;
|
||||
}
|
||||
is.readEndStatement("Field::read");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<template<class, class> class VectorField, class T, class PropType>
|
||||
bool pFlow::Field<VectorField, T, PropType>::write(
|
||||
iOstream& os,
|
||||
IOPattern::IOType iotype)const
|
||||
{
|
||||
|
||||
|
||||
os.writeWordKeyword(fieldKey_)<<endl;
|
||||
VectorType::write(os, iotype);
|
||||
os.endEntry();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,13 @@ Licence:
|
|||
#ifndef __Field_hpp__
|
||||
#define __Field_hpp__
|
||||
|
||||
#include "VectorSingle.hpp"
|
||||
#include "vocabs.hpp"
|
||||
//#include "VectorSingle.hpp"
|
||||
//#include "vocabs.hpp"
|
||||
|
||||
|
||||
#include "types.hpp"
|
||||
#include "Vector.hpp"
|
||||
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
|
@ -62,144 +67,108 @@ protected:
|
|||
|
||||
const word fieldKey_ = FKey;
|
||||
|
||||
bool readUniform( iIstream& is, size_t len, bool readLength = true);
|
||||
/*bool readUniform( iIstream& is, size_t len, bool readLength = true);
|
||||
|
||||
bool readNonUniform( iIstream& is, size_t len);
|
||||
bool readNonUniform( iIstream& is, size_t len);*/
|
||||
|
||||
public:
|
||||
|
||||
// - type info
|
||||
/// type info
|
||||
TypeInfoTemplateNV2("Field", T, VectorType::memoerySpaceName());
|
||||
|
||||
//// - Constructors
|
||||
|
||||
// construct an empty Filed with default fieldKey
|
||||
/// construct an empty Filed with default fieldKey
|
||||
Field()
|
||||
:
|
||||
VectorType()
|
||||
{}
|
||||
|
||||
// construct an empty Field with fieldKey
|
||||
Field(const word& fieldKey)
|
||||
:
|
||||
VectorType(),
|
||||
fieldKey_(fieldKey)
|
||||
{}
|
||||
|
||||
// construct an empty field with name and fieldKey
|
||||
|
||||
/// Construct an empty field with name and fieldKey
|
||||
Field(const word& name, const word& fieldKey)
|
||||
:
|
||||
VectorType(name),
|
||||
fieldKey_(fieldKey)
|
||||
{}
|
||||
|
||||
// construct an empty Filed with default fieldKey
|
||||
Field(size_t len)
|
||||
:
|
||||
VectorType(len)
|
||||
{}
|
||||
|
||||
// construct an empty Field with fieldKey
|
||||
Field(const word& fieldKey, size_t len)
|
||||
:
|
||||
VectorType(len),
|
||||
fieldKey_(fieldKey)
|
||||
{}
|
||||
|
||||
// construct an empty field with name and fieldKey
|
||||
|
||||
/// Construct a field with name and fieldKey and specified len
|
||||
Field(const word& name, const word& fieldKey, size_t len)
|
||||
:
|
||||
VectorType(name, len),
|
||||
fieldKey_(fieldKey)
|
||||
{}
|
||||
|
||||
// construct an empty Filed with default fieldKey and set vector to val
|
||||
Field(size_t len, const T& val)
|
||||
:
|
||||
VectorType(len, val)
|
||||
{}
|
||||
|
||||
// construct an empty Field with fieldKey and set vector to val
|
||||
Field(const word& fieldKey, size_t len, const T& val)
|
||||
:
|
||||
VectorType(len, val),
|
||||
fieldKey_(fieldKey)
|
||||
{}
|
||||
|
||||
// construct an empty field with name and fieldKey and set vector to val
|
||||
|
||||
/// Construct a field with name, fieldKey and
|
||||
/// set length to len and value to val
|
||||
Field(const word& name, const word& fieldKey, size_t len, const T& val)
|
||||
:
|
||||
VectorType(name, len, val),
|
||||
fieldKey_(fieldKey)
|
||||
{}
|
||||
|
||||
// construct a field with capacity and len and default fieldKey
|
||||
Field(size_t capacity, size_t len, RESERVE)
|
||||
:
|
||||
VectorType(capacity, len, RESERVE())
|
||||
{}
|
||||
|
||||
// construct an empty Field with fieldKey
|
||||
Field(const word& fieldKey, size_t capacity, size_t len, RESERVE)
|
||||
:
|
||||
VectorType(capacity, len, RESERVE()),
|
||||
fieldKey_(fieldKey)
|
||||
{}
|
||||
|
||||
// construct an empty field with name and fieldKey
|
||||
/// Construct a field with name, fieldKey, capacity and len
|
||||
Field(const word& name, const word& fieldKey, size_t capacity, size_t len, RESERVE)
|
||||
:
|
||||
VectorType(name, capacity, len, RESERVE()),
|
||||
fieldKey_(fieldKey)
|
||||
{}
|
||||
|
||||
// construct with vec and default fieldKey
|
||||
Field(const Vector<T>& vec)
|
||||
:
|
||||
VectorType(vec)
|
||||
{}
|
||||
|
||||
// construct an empty Field with fieldKey
|
||||
/// Construct a field with fieldKey and Vector vec
|
||||
Field(const word& fieldKey, const Vector<T>& 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<T>& 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<T>& 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<FieldType> clone() const
|
||||
{
|
||||
return makeUnique<FieldType>(*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<template<class, class> class VectorField, class T, class PropType>
|
||||
inline iIstream& operator >> (iIstream & is, Field<VectorField, T, PropType> & ifld )
|
||||
{
|
||||
if( !ifld.readField(is, false) )
|
||||
if( !ifld.read(is, IOPattern::MasterProcessor) )
|
||||
{
|
||||
ioErrorInFile (is.name(), is.lineNumber());
|
||||
fatalExit;
|
||||
|
@ -252,7 +217,7 @@ template<template<class, class> class VectorField, class T, class PropType>
|
|||
inline iOstream& operator << (iOstream& os, const Field<VectorField, T, PropType>& ofld )
|
||||
{
|
||||
|
||||
if( !ofld.writeField(os) )
|
||||
if( !ofld.write(os, IOPattern::AllProcessorsDifferent) )
|
||||
{
|
||||
ioErrorInFile(os.name(), os.lineNumber());
|
||||
fatalExit;
|
||||
|
|
|
@ -23,7 +23,7 @@ Licence:
|
|||
|
||||
template class pFlow::Field<pFlow::VectorSingle, pFlow::int8>;
|
||||
|
||||
template class pFlow::Field<pFlow::VectorSingle, pFlow::int8, pFlow::HostSpace>;
|
||||
/*template class pFlow::Field<pFlow::VectorSingle, pFlow::int8, pFlow::HostSpace>;
|
||||
|
||||
template class pFlow::Field<pFlow::VectorSingle, pFlow::int16>;
|
||||
|
||||
|
@ -76,6 +76,6 @@ template class pFlow::Field<pFlow::VectorDual, pFlow::realx3>;
|
|||
template class pFlow::Field<pFlow::VectorDual, pFlow::realx3x3>;
|
||||
|
||||
|
||||
template class pFlow::Field<pFlow::Vector, pFlow::word, pFlow::vecAllocator<pFlow::word>>;
|
||||
template class pFlow::Field<pFlow::Vector, pFlow::word, pFlow::vecAllocator<pFlow::word>>;*/
|
||||
|
||||
|
||||
|
|
|
@ -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<VectorSingle, int8>;
|
||||
|
||||
using int8Field_H = Field<VectorSingle, int8, HostSpace>;
|
||||
|
||||
using int16Field_D = Field<VectorSingle, int16>;
|
||||
|
||||
using int16Field_H = Field<VectorSingle, int16, HostSpace>;
|
||||
|
||||
using int32Field_D = Field<VectorSingle, int32>;
|
||||
/*using int32Field_D = Field<VectorSingle, int32>;
|
||||
|
||||
using int32Field_H = Field<VectorSingle, int32, HostSpace>;
|
||||
|
||||
|
@ -81,16 +76,14 @@ using int64x3Field_H = Field<VectorSingle, int64x3, HostSpace>;
|
|||
|
||||
using realx3x3Field_D = Field<VectorSingle, realx3x3>;
|
||||
|
||||
using realx3x3Field_H = Field<VectorSingle, realx3x3, HostSpace>;
|
||||
using realx3x3Field_H = Field<VectorSingle, realx3x3, HostSpace>;*/
|
||||
|
||||
// - no typedef on device (since word does not compile on CUDA)
|
||||
using wordField_H = Field<VectorSingle, word, HostSpace>;
|
||||
|
||||
|
||||
// host device fields
|
||||
using int8Field_HD = Field<VectorDual, int8>;
|
||||
|
||||
using int16Field_HD = Field<VectorDual, int16>;
|
||||
/*using int8Field_HD = Field<VectorDual, int8>;
|
||||
|
||||
using int32Field_HD = Field<VectorDual, int32>;
|
||||
|
||||
|
@ -104,15 +97,13 @@ using realField_HD = Field<VectorDual, real>;
|
|||
|
||||
using realx3Field_HD = Field<VectorDual, realx3>;
|
||||
|
||||
using uint16x3Field_HD = Field<VectorDual, uint32x3>;
|
||||
|
||||
using uint32x3Field_HD = Field<VectorDual, uint32x3>;
|
||||
|
||||
using int32x3Field_HD = Field<VectorDual, int32x3>;
|
||||
|
||||
using int64x3Field_HD = Field<VectorDual, int64x3>;
|
||||
|
||||
using realx3x3Field_HD = Field<VectorDual, realx3x3>;
|
||||
using realx3x3Field_HD = Field<VectorDual, realx3x3>;*/
|
||||
|
||||
|
||||
using wordField = Field<Vector, word , vecAllocator<word>>;
|
||||
|
|
|
@ -23,111 +23,21 @@ template<typename T, typename Allocator>
|
|||
bool pFlow::Vector<T, Allocator>::readVector
|
||||
(
|
||||
iIstream& is,
|
||||
size_t len
|
||||
IOPattern::IOType iotype
|
||||
)
|
||||
{
|
||||
|
||||
if(is.isBinary() && !std::is_same_v<T,word>)
|
||||
{
|
||||
this->resize(len);
|
||||
is.read(reinterpret_cast<char*>(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<typename T, typename Allocator>
|
||||
bool pFlow::Vector<T, Allocator>::writeVector
|
||||
(
|
||||
iOstream& os
|
||||
iOstream& os,
|
||||
IOPattern::IOType iotype
|
||||
) const
|
||||
{
|
||||
|
||||
span<T> s( const_cast<T*>(this->data()), this->size());
|
||||
os<<s;
|
||||
|
||||
// start of
|
||||
/*if( os.isBinary() && !std::is_same_v<T,word>)
|
||||
{
|
||||
os.write(reinterpret_cast<const char*>(this->data()), this->size()*sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
auto len = size();
|
||||
auto stride = getVectorStride(len);
|
||||
os << token::BEGIN_LIST;
|
||||
size_t i = 0;
|
||||
while( i<len )
|
||||
{
|
||||
|
||||
os << this->operator[](i++);
|
||||
for(size_t j=0; j<stride-1 && i<len; j++ )
|
||||
{
|
||||
os << token::SPACE << this->operator[](i++);
|
||||
}
|
||||
|
||||
if(i<len)
|
||||
os<< token::NL;
|
||||
}
|
||||
|
||||
os << token::END_LIST;
|
||||
|
||||
os.check(FUNCTION_NAME);
|
||||
}*/
|
||||
|
||||
return true;
|
||||
return writeStdVector(os, vectorField(), iotype);
|
||||
}
|
||||
|
||||
/*template<typename T, typename Allocator>
|
||||
|
|
|
@ -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<typename T, typename Allocator>
|
||||
class Vector;
|
||||
|
@ -48,18 +50,7 @@ class Vector;
|
|||
#include "VectorFwd.hpp"
|
||||
|
||||
|
||||
template <class T>
|
||||
class noConstructAllocator
|
||||
: public std::allocator<T>
|
||||
{
|
||||
public:
|
||||
using std::allocator<T>::allocator;
|
||||
|
||||
template <class U, class... Args> void construct(U*, Args&&...) {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using vecAllocator = std::allocator<T>;
|
||||
|
||||
template<typename T, typename Allocator = vecAllocator<T> >
|
||||
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<typename T, typename Allocator>
|
||||
inline iIstream& operator >> (iIstream & is, Vector<T, Allocator> & 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<T, Allocator> & ivec )
|
|||
|
||||
template<typename T, typename Allocator>
|
||||
inline iOstream& operator << (iOstream& os, const Vector<T, Allocator>& ovec )
|
||||
{
|
||||
|
||||
if( !ovec.writeVector(os) )
|
||||
{
|
||||
if( !ovec.writeVector(os, IOPattern::AllProcessorsDifferent) )
|
||||
{
|
||||
ioErrorInFile(os.name(), os.lineNumber());
|
||||
fatalExit;
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // pFlow
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ Licence:
|
|||
|
||||
// instantiation just for numeral types
|
||||
|
||||
template class pFlow::Vector<pFlow::int8>;
|
||||
/*template class pFlow::Vector<pFlow::int8>;
|
||||
|
||||
template class pFlow::Vector<pFlow::int32>;
|
||||
|
||||
|
@ -32,7 +32,7 @@ template class pFlow::Vector<pFlow::real>;
|
|||
|
||||
template class pFlow::Vector<pFlow::realx3>;
|
||||
|
||||
template class pFlow::Vector<pFlow::realx3x3>;
|
||||
template class pFlow::Vector<pFlow::realx3x3>;*/
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "span.hpp"
|
||||
#include "iOstream.hpp"
|
||||
#include "iIstream.hpp"
|
||||
#include "dataIO.hpp"
|
||||
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
|
||||
|
||||
template <class T>
|
||||
class noConstructAllocator
|
||||
: public std::allocator<T>
|
||||
{
|
||||
public:
|
||||
using std::allocator<T>::allocator;
|
||||
|
||||
template <class U, class... Args> void construct(U*, Args&&...) {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using vecAllocator = std::allocator<T>;
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool writeSpan(
|
||||
iOstream& os,
|
||||
const span<T>& sp,
|
||||
IOPattern::IOType iotype)
|
||||
{
|
||||
|
||||
dataIO io(iotype);
|
||||
|
||||
if(!io.writeData(os, sp))
|
||||
{
|
||||
fatalErrorInFunction;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename Allocator>
|
||||
bool writeStdVector
|
||||
(
|
||||
iOstream& os,
|
||||
const std::vector<T,Allocator>& vec,
|
||||
IOPattern::IOType iotype
|
||||
)
|
||||
{
|
||||
span<T> sp( const_cast<T*>(vec.data()), vec.size());
|
||||
|
||||
return writeSpan(os, sp, iotype);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename T, typename Allocator>
|
||||
bool readStdVector
|
||||
(
|
||||
iIstream& is,
|
||||
std::vector<T,Allocator>& vec,
|
||||
IOPattern::IOType iotype
|
||||
)
|
||||
{
|
||||
dataIO io(iotype);
|
||||
|
||||
if(!io.readData(is, vec))
|
||||
{
|
||||
fatalErrorInFunction;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
template<typename T, typename Allocator>
|
||||
iOstream& operator<<( iOstream& os, const std::vector<T,Allocator>& vec)
|
||||
{
|
||||
if(!writeStdVector(os, vec, IOPattern::AllProcessorsDifferent))
|
||||
{
|
||||
fatalErrorInFunction;
|
||||
fatalExit;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
/// Always assume ASCII is in the input stream
|
||||
template<typename T, typename Allocator>
|
||||
iIstream& operator>>(iIstream& is, std::vector<T,Allocator>& vec)
|
||||
{
|
||||
if( !readStdVector(is,vec, IOPattern::MasterProcessor))
|
||||
{
|
||||
fatalErrorInFunction;
|
||||
fatalExit;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
} // pFlow
|
||||
|
||||
|
||||
#endif
|
|
@ -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<T> vecFromFile;
|
||||
if( !vecFromFile.readVector(is,len) ) return false;
|
||||
std::vector<T> 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<T>( const_cast<T*>(hVec.data()), hVec.size());
|
||||
os<<sp;
|
||||
return true;
|
||||
|
||||
return writeSpan(os, sp, iotype);
|
||||
|
||||
}
|
||||
|
||||
}; // class VectorSingle
|
||||
|
@ -612,7 +604,7 @@ public:
|
|||
template<typename T, typename MemorySpace>
|
||||
inline iIstream& operator >> (iIstream & is, VectorSingle<T, MemorySpace> & ivec )
|
||||
{
|
||||
if( !ivec.read(is) )
|
||||
if( !ivec.read(is, IOPattern::MasterProcessor ) )
|
||||
{
|
||||
ioErrorInFile (is.name(), is.lineNumber());
|
||||
fatalExit;
|
||||
|
@ -624,7 +616,7 @@ template<typename T, typename MemorySpace>
|
|||
inline iOstream& operator << (iOstream& os, const VectorSingle<T, MemorySpace>& 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<T, MemorySpace>&
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // - pFlow
|
||||
|
||||
#include "VectorSingleAlgorithms.hpp"
|
||||
|
|
|
@ -159,6 +159,7 @@ public:
|
|||
INLINE_FUNCTION_H
|
||||
bool writeASCII(iOstream& os) const
|
||||
{
|
||||
os<< size()<<endl;
|
||||
os << token::BEGIN_LIST;
|
||||
if(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<const char*>(data_), this->size()*sizeof(T));
|
||||
os.check(FUNCTION_NAME);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
iOstream& operator<<(iOstream& os, const span<T>& s)
|
||||
{
|
||||
|
||||
if( os.isBinary() && !std::is_same_v<T,word>)
|
||||
{
|
||||
s.writeBinary(os);
|
||||
}
|
||||
else
|
||||
{
|
||||
s.writeASCII(os);
|
||||
}
|
||||
s.writeASCII(os);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // pFlow
|
||||
|
||||
#endif //__span_hpp__
|
||||
|
|
|
@ -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()<<std::endl;
|
||||
if( !isDir_ && !checkFileName(fileName()))
|
||||
{
|
||||
fatalExit;
|
||||
}
|
||||
}
|
||||
|
||||
pFlow::fileSystem::fileSystem( const word& dir, const word& file)
|
||||
{
|
||||
|
@ -74,10 +86,9 @@ pFlow::fileSystem::fileSystem( const char* dir, const char* file)
|
|||
|
||||
pFlow::fileSystem::fileSystem( const pathType& path )
|
||||
:
|
||||
path_(path)
|
||||
{
|
||||
isDir_ = isDirectory(*this);
|
||||
}
|
||||
path_(path),
|
||||
isDir_(std::filesystem::is_directory(path_))
|
||||
{}
|
||||
|
||||
pFlow::fileSystem pFlow::fileSystem::dirPath() const
|
||||
{
|
||||
|
@ -175,9 +186,7 @@ bool pFlow::fileSystem::dirExist
|
|||
|
||||
}
|
||||
|
||||
bool pFlow::fileSystem::exist
|
||||
(
|
||||
)const
|
||||
bool pFlow::fileSystem::exist()const
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -321,7 +330,7 @@ pFlow::fileSystemList pFlow::subDirectories
|
|||
auto dOps = std::filesystem::directory_options::skip_permission_denied;
|
||||
for( auto& subPath: std::filesystem::directory_iterator(path.path(), dOps) )
|
||||
{
|
||||
if(isDirectory( subPath.path() ) )
|
||||
if(isDirectory( fileSystem(subPath.path()) ) )
|
||||
{
|
||||
dirs.emplace_back(subPath.path());
|
||||
}
|
||||
|
|
|
@ -71,19 +71,19 @@ public:
|
|||
protected:
|
||||
|
||||
/// File path
|
||||
std::filesystem::path path_;
|
||||
pathType path_;
|
||||
|
||||
/// Is this a directory path?
|
||||
bool isDir_;
|
||||
bool isDir_;
|
||||
|
||||
|
||||
/// Not premitted chars in file name
|
||||
inline static word notPermittedCharsFile = word(" ") + word("\t\n\0;:?*/<>\"?\'");
|
||||
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
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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())
|
||||
{}
|
||||
|
|
@ -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__
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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<size_t>(stdStream().tellg());
|
||||
if(stdStream().fail())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in getting current position from stream "<<
|
||||
this->name()<<endl;
|
||||
fatalExit;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
|
|
@ -156,7 +156,12 @@ public:
|
|||
size_t findBinaryBlockStart()override;
|
||||
|
||||
/// Rewind the stream so that it may be read again
|
||||
virtual void rewind();
|
||||
void rewind() override;
|
||||
|
||||
void seek(size_t pos) override;
|
||||
|
||||
/// Return current position indicator
|
||||
size_t tell() override;
|
||||
|
||||
|
||||
/// Set stream flags
|
||||
|
|
|
@ -258,6 +258,10 @@ pFlow::iOstream& pFlow::Ostream::writeBinaryBlockFlag()
|
|||
return *this;
|
||||
}
|
||||
|
||||
void pFlow::Ostream::seek(size_t pos)
|
||||
{
|
||||
os_.seekp(pos, std::ios_base::cur);
|
||||
}
|
||||
|
||||
void pFlow::Ostream::indent()
|
||||
{
|
||||
|
@ -267,6 +271,18 @@ void pFlow::Ostream::indent()
|
|||
}
|
||||
}
|
||||
|
||||
void pFlow::Ostream::startOfBinaryStreaming()
|
||||
{
|
||||
this->endl();
|
||||
this->flush();
|
||||
}
|
||||
|
||||
void pFlow::Ostream::endOfBinaryStreaming()
|
||||
{
|
||||
os_.seekp(0, std::ios_base::end);
|
||||
this->endl();
|
||||
this->flush();
|
||||
}
|
||||
|
||||
void pFlow::Ostream::flush()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
{}
|
||||
|
|
|
@ -7,12 +7,9 @@
|
|||
#include <cstdio>
|
||||
#include <numeric>
|
||||
|
||||
|
||||
#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<pFlow::uint64>(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<pFlow::uint64>(fpos);
|
||||
pFlow::uint64 filePos = static_cast<pFlow::uint64>(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<unsigned char>& 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 <<endl;
|
||||
"Error in Opening file "<< wordPath <<endl;
|
||||
std::fclose(fh);
|
||||
return false;
|
||||
}
|
||||
|
@ -145,15 +132,16 @@ bool pFlow::dataIO::writeDataToFileEndSTD
|
|||
if(std::fseek(fh, 0 , SEEK_END)!=0)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"error at reaching end of file "<<filePath<<endl;
|
||||
"error at reaching end of file "<<wordPath<<endl;
|
||||
std::fclose(fh);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(!writeBinaryBlockFlagSTD(fh) )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in writing to file "<< filePath<<endl;
|
||||
"Error in writing to file "<< wordPath<<endl;
|
||||
std::fclose(fh);
|
||||
return false;
|
||||
}
|
||||
|
@ -166,7 +154,7 @@ bool pFlow::dataIO::writeDataToFileEndSTD
|
|||
if(wc < 1)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in writing numChunks to file "<< filePath <<endl;
|
||||
"Error in writing numChunks to file "<< wordPath <<endl;
|
||||
std::fclose(fh);
|
||||
return false;
|
||||
}
|
||||
|
@ -179,7 +167,7 @@ bool pFlow::dataIO::writeDataToFileEndSTD
|
|||
if(wc <1)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in writing size of data chunk to file "<< filePath <<endl;
|
||||
"Error in writing size of data chunk to file "<< wordPath <<endl;
|
||||
std::fclose(fh);
|
||||
return false;
|
||||
}
|
||||
|
@ -191,12 +179,15 @@ bool pFlow::dataIO::writeDataToFileEndSTD
|
|||
if(wc < sizeOfData )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in writing size of data to file "<< filePath <<endl;
|
||||
"Error in writing size of data to file "<< wordPath <<endl;
|
||||
std::fclose(fh);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
lastPosRead_ = static_cast<uint64>(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<unsigned char>& 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<<endl;
|
||||
"Cannot open file "<< wordPath<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -255,7 +245,7 @@ bool pFlow::dataIO::writeDataToFileEndMPI
|
|||
) != MPI_SUCCESS )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Cannot write binary block flag into "<< filePath<<endl;
|
||||
"Cannot write binary block flag into "<< wordPath<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -263,7 +253,7 @@ bool pFlow::dataIO::writeDataToFileEndMPI
|
|||
if( MPI_File_get_position(fh, &posOfBlock) != MPI_SUCCESS )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Cannot get the end pos of file "<< filePath<<endl;
|
||||
"Cannot get the end pos of file "<< wordPath<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -295,7 +285,7 @@ bool pFlow::dataIO::writeDataToFileEndMPI
|
|||
MPI_STATUS_IGNORE) != MPI_SUCCESS)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Cannot write number of chunks into "<<filePath<<endl;
|
||||
"Cannot write number of chunks into "<<wordPath<<endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -312,7 +302,7 @@ bool pFlow::dataIO::writeDataToFileEndMPI
|
|||
MPI_STATUS_IGNORE)!= MPI_SUCCESS)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Cannot write size of chunk into "<<filePath<<endl;
|
||||
"Cannot write size of chunk into "<<wordPath<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -330,30 +320,50 @@ bool pFlow::dataIO::writeDataToFileEndMPI
|
|||
MPI_STATUS_IGNORE) != MPI_SUCCESS)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Cannot write data into "<<filePath<<endl;
|
||||
"Cannot write data into "<<wordPath<<endl;
|
||||
return false;;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MPI_File_close(&fh);
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
return true;
|
||||
|
||||
uint64 lastPos = chunkOffset + thisSize;
|
||||
return maxReduction(lastPos, lastPosWrite_);
|
||||
|
||||
/*if( MPI_Allreduce(
|
||||
&lastPos,
|
||||
&lastPosWrite_,
|
||||
1,
|
||||
MPI_UINT64_T,
|
||||
MPI_MAX,
|
||||
MPI_COMM_WORLD) != MPI_SUCCESS )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in max_reduction for write operation"<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;*/
|
||||
|
||||
#else
|
||||
return writeDataToFileEndSTD(filePath, data);
|
||||
// if MPI is not active, we use std routins
|
||||
return writeDataToFileEndSTD(wordPath, data);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool pFlow::dataIO::readDataSTD
|
||||
(
|
||||
const fileSystem& filePath,
|
||||
const word& wordPath,
|
||||
const std::vector<uint64> chunkSizes,
|
||||
span<unsigned char>& 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<<endl;
|
||||
"Error in Opening file "<< wordPath<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// start of data chunks
|
||||
uint64 offset = binaryBlockStart + chunkSizeOffeset(chunkSizes.size());
|
||||
|
||||
|
||||
if(auto res = std::fseek(fh, offset, SEEK_SET); res!= 0 )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in file seek "<< filePath<<endl;
|
||||
"Error in file seek "<< wordPath<<endl;
|
||||
std::fclose(fh);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(auto res = std::fread(
|
||||
data.data(),
|
||||
sizeof(unsigned char),
|
||||
|
@ -395,11 +407,13 @@ bool pFlow::dataIO::readDataSTD
|
|||
res!= data.size() )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in reading file "<< filePath<<endl;
|
||||
"Error in reading file "<< wordPath<<endl;
|
||||
std::fclose(fh);
|
||||
return false;
|
||||
}
|
||||
|
||||
lastPosRead_ = static_cast<uint64>(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<uint64> chunkSizes,
|
||||
span<unsigned char>& 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_"<<endl;
|
||||
return false;
|
||||
}*/
|
||||
|
||||
return maxReduction(lastPos, lastPosRead_);
|
||||
#else
|
||||
return readDataSTD(wordPath, chunkSizes, data, binaryBlockStart);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool pFlow::dataIO::readMetaMPI
|
||||
(
|
||||
const fileSystem& filePath,
|
||||
const word& wordPath,
|
||||
std::vector<uint64>& 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_"<<endl;
|
||||
return false;
|
||||
}*/
|
||||
|
||||
#else
|
||||
return readMetaSTD(wordPath, chunkSizes, startPosBinaryBlock);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool pFlow::dataIO::readMetaSTD
|
||||
(
|
||||
const fileSystem& filePath,
|
||||
const word& wordPath,
|
||||
std::vector<uint64>& 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<<endl;
|
||||
"Error in Opening file "<< wordPath<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// set the start position for search
|
||||
std::fseek(fh, startPosSearch, SEEK_SET);
|
||||
|
||||
|
||||
uint64 startPos = findBindaryBlockFlagSTD(fh);
|
||||
if(startPos == -1 )
|
||||
if(startPos == ErrorReturn )
|
||||
{
|
||||
fatalErrorInFunction;
|
||||
return false;
|
||||
|
@ -587,7 +629,7 @@ bool pFlow::dataIO::readMetaSTD
|
|||
if(res != 1 )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in reading file "<< filePath<<endl;
|
||||
"Error in reading file "<< wordPath<<endl;
|
||||
std::fclose(fh);
|
||||
return false;
|
||||
}
|
||||
|
@ -600,13 +642,76 @@ bool pFlow::dataIO::readMetaSTD
|
|||
if(res!= numProcInFile)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in reading chunkSizes from file "<< filePath<<endl;
|
||||
"Error in reading chunkSizes from file "<< wordPath<<endl;
|
||||
std::fclose(fh);
|
||||
return false;
|
||||
}
|
||||
|
||||
lastPosRead_ = static_cast<uint64>(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"<<endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst = src;
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
dst = src;
|
||||
return true;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool pFlow::dataIO::BcastPos(uint64 & pos)
|
||||
{
|
||||
#ifdef pFlow_Build_MPI
|
||||
if(processors::isParallel())
|
||||
{
|
||||
if( MPI_Bcast(
|
||||
& pos,
|
||||
1,
|
||||
MPI_UINT64_T,
|
||||
processors::masterNo(),
|
||||
MPI_COMM_WORLD)!=MPI_SUCCESS )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in Bcast position"<<endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "types.hpp"
|
||||
#include "span.hpp"
|
||||
#include "processors.hpp"
|
||||
#include "IOPattern.hpp"
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
|
@ -19,80 +19,133 @@ class dataIO
|
|||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Type of input/output
|
||||
* MasterProcessor: Read or write is done on master processor
|
||||
* and the data on master processor is affected.
|
||||
* AllProcessorsDifferent: Read or write is done on all processors,
|
||||
* and each processor munipulates its own data.
|
||||
* AllProcessorsSimilar: Read is done on all processors but the read data
|
||||
* is similar on processors. Write is done on master processor, since
|
||||
* all processors have the same copy of data.
|
||||
*/
|
||||
enum IOType : int
|
||||
{
|
||||
MasterProcessor,
|
||||
AllProcessorsDifferent,
|
||||
AllProcessorsSimilar
|
||||
};
|
||||
|
||||
static inline const uint64 ErrorReturn = static_cast<uint64>(-1);
|
||||
|
||||
protected:
|
||||
|
||||
IOType IOType_;
|
||||
IOPattern ioPattern_;
|
||||
|
||||
uint64 lastPosWrite_ = 0;
|
||||
|
||||
uint64 lastPosRead_ = 0;
|
||||
|
||||
|
||||
bool writeDataToFileEndSTD(
|
||||
const fileSystem& filePath,
|
||||
const word& wordPath,
|
||||
const span<unsigned char>& data);
|
||||
|
||||
bool writeDataToFileEndMPI(
|
||||
const fileSystem& filePath,
|
||||
const word& wordPath,
|
||||
const span<unsigned char>& data);
|
||||
|
||||
bool readDataSTD(
|
||||
const fileSystem& filePath,
|
||||
const word& wordPath,
|
||||
const std::vector<uint64> chunkSizes,
|
||||
span<unsigned char>& data,
|
||||
uint64 binaryBlockStart);
|
||||
|
||||
bool readDataMPI(
|
||||
const fileSystem& filePath,
|
||||
const word& wordPath,
|
||||
const std::vector<uint64> chunkSizes,
|
||||
span<unsigned char>& data,
|
||||
uint64 binaryBlockStart);
|
||||
|
||||
bool readMetaMPI(
|
||||
const fileSystem& filePath,
|
||||
const word& wordPath,
|
||||
std::vector<uint64>& chunkSizes,
|
||||
uint64 startPosSearch,
|
||||
uint64 &startPosBinaryBlock);
|
||||
|
||||
bool readMetaSTD(
|
||||
const fileSystem& filePath,
|
||||
const word& wordPath,
|
||||
std::vector<uint64>& 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<typename T>
|
||||
bool writeDataEnd(
|
||||
const fileSystem& filePath,
|
||||
const word& wordPath,
|
||||
const span<T>& data);
|
||||
|
||||
template<typename T>
|
||||
bool writeAsciiEnd(
|
||||
iOstream& os,
|
||||
const span<T>& data);
|
||||
|
||||
template<typename T>
|
||||
bool readDataBinary(
|
||||
const word& wordPath,
|
||||
std::vector<T>& data,
|
||||
uint64 startPos = 0);
|
||||
|
||||
template<typename T>
|
||||
bool readAscii(
|
||||
iIstream& is,
|
||||
std::vector<T>& vec );
|
||||
|
||||
template<typename T>
|
||||
bool readData(
|
||||
const fileSystem& filePath,
|
||||
std::vector<T>& data);
|
||||
iIstream& is,
|
||||
std::vector<T>& vec,
|
||||
bool resume = false); // resume only works for binary
|
||||
// for ascii, by default it starts from the current position
|
||||
|
||||
|
||||
template<typename T>
|
||||
bool writeData(iOstream& os,
|
||||
const span<T>& data);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
inline
|
||||
bool pFlow::dataIO::writeData<pFlow::word>
|
||||
(
|
||||
iOstream& os,
|
||||
const span<word>& data
|
||||
)
|
||||
{
|
||||
if( !writeAsciiEnd(os, data) )
|
||||
{
|
||||
fatalErrorInFunction;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
bool pFlow::dataIO::readData<pFlow::word>(
|
||||
iIstream& is,
|
||||
std::vector<word>& vec,
|
||||
bool resume)
|
||||
{
|
||||
if(!readAscii(is, vec))
|
||||
{
|
||||
fatalErrorInFunction;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#include "dataIOTemplate.cpp"
|
||||
|
|
|
@ -1,112 +1,320 @@
|
|||
|
||||
template<typename T>
|
||||
bool pFlow::dataIO::writeDataEnd(
|
||||
const fileSystem& filePath,
|
||||
const word& wordPath,
|
||||
const span<T>& data)
|
||||
{
|
||||
|
||||
span<unsigned char> charSpan(
|
||||
if( ioPattern_.thisProcWriteData() )
|
||||
{
|
||||
span<unsigned char> charSpan(
|
||||
reinterpret_cast<unsigned char*> (const_cast<T*>(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<typename T>
|
||||
bool pFlow::dataIO::readData
|
||||
bool pFlow::dataIO::writeAsciiEnd
|
||||
(
|
||||
const fileSystem& filePath,
|
||||
std::vector<T>& data
|
||||
iOstream& os,
|
||||
const span<T>& data
|
||||
)
|
||||
{
|
||||
if(ioPattern_.thisProcWriteData())
|
||||
{
|
||||
return data.writeASCII(os);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
bool pFlow::dataIO::readDataBinary
|
||||
(
|
||||
const word& wordPath,
|
||||
std::vector<T>& data,
|
||||
uint64 startPos
|
||||
)
|
||||
{
|
||||
|
||||
std::vector<uint64> 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<uint64>(0));
|
||||
|
||||
|
||||
data.resize(sizeOfData/sizeof(T));
|
||||
|
||||
data.resize(sizeOfData/sizeof(T));
|
||||
span<unsigned char> charSpan(
|
||||
reinterpret_cast<unsigned char*>(data.data()),
|
||||
data.size()*sizeof(T));
|
||||
|
||||
span<unsigned char> charSpan(
|
||||
reinterpret_cast<unsigned char*>(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<uint64>(0));
|
||||
|
||||
|
||||
data.resize(sizeOfData/sizeof(T));
|
||||
|
||||
span<unsigned char> charSpan(
|
||||
reinterpret_cast<unsigned char*>(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<unsigned char> charSpan(
|
||||
reinterpret_cast<unsigned char*>(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<unsigned char> charSpan(
|
||||
reinterpret_cast<unsigned char*>(data.data()),
|
||||
data.size()*sizeof(T));
|
||||
template<typename T>
|
||||
bool pFlow::dataIO::readAscii
|
||||
(
|
||||
iIstream& is,
|
||||
std::vector<T>& vec
|
||||
)
|
||||
{
|
||||
|
||||
std::cout<<"MPI part"<<std::endl;
|
||||
readDataMPI(filePath, chunkSizes, charSpan, startPosBinaryBlock);
|
||||
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<<endl; ;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(len>0&& len != vec.size())
|
||||
{
|
||||
warningInFunction<<"vector lendth specified "<< len <<
|
||||
" is different from number of elements "<< vec.size()<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool pFlow::dataIO::readData
|
||||
(
|
||||
iIstream& is,
|
||||
std::vector<T>& 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_<<std::endl;
|
||||
|
||||
/// set the stream indicator to the last position
|
||||
is.seek(lastPosRead_);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!readAscii(is, vec))
|
||||
{
|
||||
fatalErrorInFunction;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool pFlow::dataIO::writeData
|
||||
(
|
||||
iOstream& os,
|
||||
const span<T>& 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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ public:
|
|||
bool isBinary()const
|
||||
{
|
||||
return writeFormat_ == BINARY;
|
||||
}
|
||||
}
|
||||
|
||||
/// Return true if next operation might succeed
|
||||
bool good() const
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)<<endl;
|
||||
fatalExit;
|
||||
}
|
||||
normal_ = normalize(ln);
|
||||
d_ = -dot(normal_, p1);
|
||||
}
|
||||
|
||||
bool pFlow::infinitePlane::write(iOstream& os)const
|
||||
{
|
||||
os.writeWordEntry("normal", normal_);
|
||||
os.writeWordEntry("d", d_);
|
||||
return os.check(FUNCTION_NAME);
|
||||
}
|
||||
|
||||
bool pFlow::infinitePlane::read(iIstream & is)
|
||||
{
|
||||
if(!is.nextData<realx3>("normal", normal_)) return false;
|
||||
if(!is.nextData<real>("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);
|
||||
}
|
|
@ -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__
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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"<<endl;
|
||||
fatalExit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pFlow::plane pFlow::plane::parallelPlane(real distance)const
|
||||
{
|
||||
auto pp1 = line(normal_, p1_, true).point(distance);
|
||||
auto pp2 = line(normal_, p2_, true).point(distance);
|
||||
auto pp3 = line(normal_, p3_, true).point(distance);
|
||||
auto pp4 = line(normal_, p4_, true).point(distance);
|
||||
|
||||
return plane(pp1, pp2, pp3, pp4);
|
||||
}
|
||||
|
||||
bool pFlow::plane::validPlane4
|
||||
(
|
||||
const realx3& p1,
|
||||
const realx3& p2,
|
||||
const realx3& p3,
|
||||
const realx3& p4
|
||||
)
|
||||
{
|
||||
if( !validPlane3(p1,p2,p3)) return false;
|
||||
if( !infinitePlane(p1,p2,p3).pointOnPlane(p4)) return false;
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/*------------------------------- 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 __plane_hpp__
|
||||
#define __plane_hpp__
|
||||
|
||||
#include "infinitePlane.hpp"
|
||||
#include "line.hpp"
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
|
||||
class plane
|
||||
:
|
||||
public infinitePlane
|
||||
{
|
||||
protected:
|
||||
|
||||
/// First point
|
||||
realx3 p1_;
|
||||
|
||||
/// Second point
|
||||
realx3 p2_;
|
||||
|
||||
/// Third point
|
||||
realx3 p3_;
|
||||
|
||||
/// Fourth point
|
||||
realx3 p4_;
|
||||
|
||||
public:
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
plane(){}
|
||||
|
||||
plane(
|
||||
const realx3& p1,
|
||||
const realx3& p2,
|
||||
const realx3& p3,
|
||||
const realx3& p4);
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
plane(const plane&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
plane(plane&&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
plane& operator = (const plane&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
plane& operator =( plane&&)=default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
~plane()=default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
const realx3& p1()const
|
||||
{
|
||||
return p1_;
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
const realx3& p2()const
|
||||
{
|
||||
return p2_;
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
const realx3& p3()const
|
||||
{
|
||||
return p3_;
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
const realx3& p4()const
|
||||
{
|
||||
return p4_;
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
line line1()const
|
||||
{
|
||||
return line(p1_,p2_);
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
line line2()const
|
||||
{
|
||||
return line(p2_,p3_);
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
line line3()const
|
||||
{
|
||||
return line(p3_,p4_);
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
line line4()const
|
||||
{
|
||||
return line(p4_,p1_);
|
||||
}
|
||||
|
||||
// return the parallel plane to this plane
|
||||
plane parallelPlane(real distance)const;
|
||||
|
||||
static
|
||||
bool validPlane4(
|
||||
const realx3& p1,
|
||||
const realx3& p2,
|
||||
const realx3& p3,
|
||||
const realx3& p4);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //__plane_hpp__
|
Loading…
Reference in New Issue