Merge branch 'master' into cvm

This commit is contained in:
graham
2010-11-01 17:23:23 +00:00
54 changed files with 4285 additions and 616 deletions

View File

@ -37,8 +37,11 @@ namespace Foam
const label SIBS::nSeq_[iMaxX_] = {2, 6, 10, 14, 22, 34, 50, 70};
const scalar
SIBS::safe1 = 0.25, SIBS::safe2 = 0.7,
SIBS::redMax = 1.0e-5, SIBS::redMin = 0.0, SIBS::scaleMX = 0.1;
SIBS::safe1 = 0.25,
SIBS::safe2 = 0.7,
SIBS::redMax = 1.0e-5,
SIBS::redMin = 0.7,
SIBS::scaleMX = 0.1;
};

View File

@ -170,7 +170,9 @@ namespace Foam
<< "inotify instances" << endl
<< " (/proc/sys/fs/inotify/max_user_instances"
<< " on Linux)" << endl
<< " or switch off runTimeModifiable." << endl
<< " , switch off runTimeModifiable." << endl
<< " or compile this file with FOAM_USE_STAT to use"
<< " time stamps instead of inotify." << endl
<< " Continuing without additional file monitoring."
<< endl;
}

View File

@ -28,8 +28,8 @@ License
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList()
:
List<T>(SizeInc),
capacity_(SizeInc)
List<T>(0),
capacity_(0)
{
List<T>::size(0);
}

View File

@ -128,7 +128,10 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::start()
template<class OutputFilter>
bool Foam::OutputFilterFunctionObject<OutputFilter>::execute()
bool Foam::OutputFilterFunctionObject<OutputFilter>::execute
(
const bool forceWrite
)
{
if (enabled_)
{
@ -139,7 +142,7 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::execute()
ptr_->execute();
if (outputControl_.output())
if (forceWrite || outputControl_.output())
{
ptr_->write();
}

View File

@ -183,7 +183,7 @@ public:
virtual bool start();
//- Called at each ++ or += of the time-loop
virtual bool execute();
virtual bool execute(const bool forceWrite);
//- Called when Time::run() determines that the time-loop exits
virtual bool end();

View File

@ -112,7 +112,7 @@ const Foam::word& Foam::functionObject::name() const
bool Foam::functionObject::end()
{
return execute();
return execute(false);
}

View File

@ -147,8 +147,9 @@ public:
//- Called at the start of the time-loop
virtual bool start() = 0;
//- Called at each ++ or += of the time-loop
virtual bool execute() = 0;
//- Called at each ++ or += of the time-loop. forceWrite overrides the
// outputControl behaviour.
virtual bool execute(const bool forceWrite) = 0;
//- Called when Time::run() determines that the time-loop exits.
// By default it simply calls execute().

View File

@ -144,7 +144,7 @@ bool Foam::functionObjectList::start()
}
bool Foam::functionObjectList::execute()
bool Foam::functionObjectList::execute(const bool forceWrite)
{
bool ok = true;
@ -157,7 +157,7 @@ bool Foam::functionObjectList::execute()
forAll(*this, objectI)
{
ok = operator[](objectI).execute() && ok;
ok = operator[](objectI).execute(forceWrite) && ok;
}
}

View File

@ -153,8 +153,10 @@ public:
//- Called at the start of the time-loop
virtual bool start();
//- Called at each ++ or += of the time-loop
virtual bool execute();
//- Called at each ++ or += of the time-loop. forceWrite overrides
// the usual outputControl behaviour and forces writing always
// (used in postprocessing mode)
virtual bool execute(const bool forceWrite = false);
//- Called when Time::run() determines that the time-loop exits
virtual bool end();

View File

@ -25,87 +25,53 @@ License
#include "DynamicField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * //
template<class Type>
const char* const DynamicField<Type>::typeName("DynamicField");
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
DynamicField<Type>::DynamicField(Istream& is)
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField(Istream& is)
:
Field<Type>(is),
capacity_(Field<Type>::size())
Field<T>(is),
capacity_(Field<T>::size())
{}
template<class Type>
tmp<DynamicField<Type> > DynamicField<Type>::clone() const
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
Foam::tmp<Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv> >
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clone() const
{
return tmp<DynamicField<Type> >(new DynamicField<Type>(*this));
return tmp<DynamicField<T, SizeInc, SizeMult, SizeDiv> >
(
new DynamicField<T, SizeInc, SizeMult, SizeDiv>(*this)
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void DynamicField<Type>::setSize(const label nElem)
{
// allocate more capacity?
if (nElem > capacity_)
{
capacity_ = max(nElem, label(1 + capacity_*2));
Field<Type>::setSize(capacity_);
}
// adjust addressed size
Field<Type>::size(nElem);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * IOstream Operator * * * * * * * * * * * * * //
template<class Type>
Ostream& operator<<(Ostream& os, const DynamicField<Type>& f)
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst
)
{
os << static_cast<const Field<Type>&>(f);
os << static_cast<const Field<T>&>(lst);
return os;
}
template<class Type>
Ostream& operator<<(Ostream& os, const tmp<DynamicField<Type> >& tf)
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
Foam::Istream& Foam::operator>>
(
Istream& is,
DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst
)
{
os << tf();
tf.clear();
return os;
}
template<class Type>
Istream& operator>>(Istream& is, DynamicField<Type>& lst)
{
is >> static_cast<Field<Type>&>(lst);
lst.capacity_ = lst.Field<Type>::size();
is >> static_cast<Field<T>&>(lst);
lst.capacity_ = lst.Field<T>::size();
return is;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -25,9 +25,10 @@ Class
Foam::DynamicField
Description
Dynamically sized Field. WIP.
Dynamically sized Field.
SourceFiles
DynamicFieldI.H
DynamicField.C
\*---------------------------------------------------------------------------*/
@ -44,89 +45,78 @@ namespace Foam
// Forward declaration of friend functions and operators
template<class Type>
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
class DynamicField;
template<class Type>
Ostream& operator<<(Ostream&, const DynamicField<Type>&);
template<class Type>
Ostream& operator<<(Ostream&, const tmp<DynamicField<Type> >&);
template<class Type>
Istream& operator>>(Istream&, DynamicField<Type>&);
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
Ostream& operator<<
(
Ostream&,
const DynamicField<T, SizeInc, SizeMult, SizeDiv>&
);
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
Istream& operator>>
(
Istream&,
DynamicField<T, SizeInc, SizeMult, SizeDiv>&
);
/*---------------------------------------------------------------------------*\
Class DynamicField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
template<class T, unsigned SizeInc=0, unsigned SizeMult=2, unsigned SizeDiv=1>
class DynamicField
:
public Field<Type>
public Field<T>
{
// Private data
//- The capacity (allocated size) of the underlying field.
label capacity_;
//- Construct given size and initial value
DynamicField(const label, const Type&);
//- Construct as copy of tmp<DynamicField>
# ifdef ConstructFromTmp
DynamicField(const tmp<DynamicField<Type> >&);
# endif
//- Construct from a dictionary entry
DynamicField(const word&, const dictionary&, const label);
public:
// Static data members
static const char* const typeName;
// Static Member Functions
//- Return a null field
inline static const DynamicField<Type>& null()
inline static const DynamicField<T, SizeInc, SizeMult, SizeDiv>& null()
{
return *reinterpret_cast< DynamicField<Type>* >(0);
return *reinterpret_cast
<
DynamicField<T, SizeInc, SizeMult, SizeDiv>*
>(0);
}
// Constructors
//- Construct null
// Used for temporary fields which are initialised after construction
DynamicField();
inline DynamicField();
//- Construct given size
// Used for temporary fields which are initialised after construction
//- Construct given size.
explicit inline DynamicField(const label);
//- Construct as copy of a UList\<Type\>
explicit inline DynamicField(const UList<Type>&);
//- Construct from UList. Size set to UList size.
// Also constructs from DynamicField with different sizing parameters.
explicit inline DynamicField(const UList<T>&);
//- Construct by transferring the List contents
explicit inline DynamicField(const Xfer<List<Type> >&);
//- Construct by transferring the parameter contents
explicit inline DynamicField(const Xfer<List<T> >&);
//- Construct by 1 to 1 mapping from the given field
inline DynamicField
(
const UList<Type>& mapF,
const UList<T>& mapF,
const labelList& mapAddressing
);
//- Construct by interpolative mapping from the given field
inline DynamicField
(
const UList<Type>& mapF,
const UList<T>& mapF,
const labelListList& mapAddressing,
const scalarListList& weights
);
@ -134,59 +124,129 @@ public:
//- Construct by mapping from the given field
inline DynamicField
(
const UList<Type>& mapF,
const UList<T>& mapF,
const FieldMapper& map
);
//- Construct as copy
inline DynamicField(const DynamicField<Type>&);
//- Construct as copy or re-use as specified.
inline DynamicField(DynamicField<Type>&, bool reUse);
//- Construct copy
inline DynamicField(const DynamicField<T, SizeInc, SizeMult, SizeDiv>&);
//- Construct by transferring the Field contents
inline DynamicField(const Xfer<DynamicField<Type> >&);
inline DynamicField
(
const Xfer<DynamicField<T, SizeInc, SizeMult, SizeDiv> >&
);
//- Construct from Istream
inline DynamicField(Istream&);
//- Construct from Istream. Size set to size of list read.
explicit DynamicField(Istream&);
//- Clone
tmp<DynamicField<Type> > clone() const;
tmp<DynamicField<T, SizeInc, SizeMult, SizeDiv> > clone() const;
// Member Functions
//- Size of the underlying storage.
inline label capacity() const;
// Access
//- Append an element at the end of the list
inline void append(const Type&);
//- Size of the underlying storage.
inline label capacity() const;
//- Alter the addressed list size.
// New space will be allocated if required.
// Use this to resize the list prior to using the operator[] for
// setting values (as per List usage).
void setSize(const label nElem);
// Edit
// Member operators
//- Alter the size of the underlying storage.
// The addressed size will be truncated if needed to fit, but will
// remain otherwise untouched.
// Use this or reserve() in combination with append().
inline void setCapacity(const label);
inline void operator=(const DynamicField<Type>&);
inline void operator=(const UList<Type>&);
inline void operator=(const tmp<DynamicField<Type> >&);
//- Alter the addressed list size.
// New space will be allocated if required.
// Use this to resize the list prior to using the operator[] for
// setting values (as per List usage).
inline void setSize(const label);
//- Return element of Field.
using Field<Type>::operator[];
//- Alter the addressed list size and fill new space with a
// constant.
inline void setSize(const label, const T&);
// IOstream operators
//- Alter the addressed list size.
// New space will be allocated if required.
// Use this to resize the list prior to using the operator[] for
// setting values (as per List usage).
inline void resize(const label);
friend Ostream& operator<< <Type>
(Ostream&, const DynamicField<Type>&);
//- Alter the addressed list size and fill new space with a
// constant.
inline void resize(const label, const T&);
friend Ostream& operator<< <Type>
(Ostream&, const tmp<DynamicField<Type> >&);
//- Reserve allocation space for at least this size.
// Never shrinks the allocated size, use setCapacity() for that.
inline void reserve(const label);
friend Istream& operator>> <Type>
(Istream&, DynamicField<Type>&);
//- Clear the addressed list, i.e. set the size to zero.
// Allocated size does not change
inline void clear();
//- Clear the list and delete storage.
inline void clearStorage();
//- Shrink the allocated space to the number of elements used.
// Returns a reference to the DynamicField.
inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& shrink();
//- Transfer contents to the Xfer container as a plain List
inline Xfer<List<T> > xfer();
// Member Operators
//- Append an element at the end of the list
inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& append
(
const T&
);
//- Append a List at the end of this list
inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& append
(
const UList<T>&
);
//- Remove and return the top element
inline T remove();
//- Return non-const access to an element, resizing list if
// necessary
inline T& operator()(const label);
//- Assignment of all addressed entries to the given value
inline void operator=(const T&);
//- Assignment from DynamicField
inline void operator=
(
const DynamicField<T, SizeInc, SizeMult, SizeDiv>&
);
//- Assignment from UList
inline void operator=(const UList<T>&);
// IOstream operators
// Write DynamicField to Ostream.
friend Ostream& operator<< <T, SizeInc, SizeMult, SizeDiv>
(
Ostream&,
const DynamicField<T, SizeInc, SizeMult, SizeDiv>&
);
//- Read from Istream, discarding contents of existing DynamicField.
friend Istream& operator>> <T, SizeInc, SizeMult, SizeDiv>
(
Istream&,
DynamicField<T, SizeInc, SizeMult, SizeDiv>&
);
};

View File

@ -23,175 +23,441 @@ License
\*---------------------------------------------------------------------------*/
#include "DynamicField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::DynamicField<Type>::DynamicField()
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField()
:
Field<Type>(),
capacity_(0)
Field<T>(0),
capacity_(Field<T>::size())
{}
template<class Type>
Foam::DynamicField<Type>::DynamicField(const label size)
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
(
const label nElem
)
:
Field<Type>(size),
capacity_(Field<Type>::size())
Field<T>(nElem),
capacity_(Field<T>::size())
{
Field<Type>::size(0);
// we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
Field<T>::size(0);
}
template<class Type>
inline Foam::DynamicField<Type>::DynamicField
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
(
const UList<Type>& lst
const UList<T>& lst
)
:
Field<Type>(lst),
capacity_(Field<Type>::size())
Field<T>(lst),
capacity_(Field<T>::size())
{}
template<class Type>
inline Foam::DynamicField<Type>::DynamicField
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
(
const Xfer<List<Type> >& lst
const Xfer<List<T> >& lst
)
:
Field<Type>(lst),
capacity_(Field<Type>::size())
Field<T>(lst),
capacity_(Field<T>::size())
{}
template<class Type>
Foam::DynamicField<Type>::DynamicField
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
(
const UList<Type>& mapF,
const UList<T>& mapF,
const labelList& mapAddressing
)
:
Field<Type>(mapF, mapAddressing),
capacity_(Field<Type>::size())
Field<T>(mapF, mapAddressing),
capacity_(Field<T>::size())
{}
template<class Type>
Foam::DynamicField<Type>::DynamicField
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
(
const UList<Type>& mapF,
const UList<T>& mapF,
const labelListList& mapAddressing,
const scalarListList& weights
)
:
Field<Type>(mapF, mapAddressing, weights),
capacity_(Field<Type>::size())
Field<T>(mapF, mapAddressing, weights),
capacity_(Field<T>::size())
{}
//- Construct by mapping from the given field
template<class Type>
Foam::DynamicField<Type>::DynamicField
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
(
const UList<Type>& mapF,
const UList<T>& mapF,
const FieldMapper& map
)
:
DynamicField<Type>(mapF, map),
capacity_(Field<Type>::size())
Field<T>(mapF, map),
capacity_(Field<T>::size())
{}
template<class Type>
Foam::DynamicField<Type>::DynamicField(const DynamicField<Type>& f)
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
(
const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst
)
:
Field<Type>(f),
capacity_(Field<Type>::size())
Field<T>(lst),
capacity_(lst.capacity())
{}
template<class Type>
Foam::DynamicField<Type>::DynamicField(DynamicField<Type>& f, bool reUse)
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
(
const Xfer<DynamicField<T, SizeInc, SizeMult, SizeDiv> >& lst
)
:
Field<Type>(f, reUse),
capacity_(Field<Type>::size())
{}
template<class Type>
Foam::DynamicField<Type>::DynamicField(const Xfer<DynamicField<Type> >& f)
:
Field<Type>(f),
capacity_(Field<Type>::size())
Field<T>(lst),
capacity_(Field<T>::size())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::label Foam::DynamicField<Type>::capacity() const
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::label Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::capacity()
const
{
return capacity_;
}
template<class Type>
void Foam::DynamicField<Type>::append(const Type& t)
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setCapacity
(
const label nElem
)
{
label elemI = Field<Type>::size();
label nextFree = Field<T>::size();
capacity_ = nElem;
if (nextFree > capacity_)
{
// truncate addressed sizes too
nextFree = capacity_;
}
// we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
Field<T>::setSize(capacity_);
Field<T>::size(nextFree);
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::reserve
(
const label nElem
)
{
// allocate more capacity?
if (nElem > capacity_)
{
// TODO: convince the compiler that division by zero does not occur
// if (SizeInc && (!SizeMult || !SizeDiv))
// {
// // resize with SizeInc as the granularity
// capacity_ = nElem;
// unsigned pad = SizeInc - (capacity_ % SizeInc);
// if (pad != SizeInc)
// {
// capacity_ += pad;
// }
// }
// else
{
capacity_ = max
(
nElem,
label(SizeInc + capacity_ * SizeMult / SizeDiv)
);
}
// adjust allocated size, leave addressed size untouched
label nextFree = Field<T>::size();
Field<T>::setSize(capacity_);
Field<T>::size(nextFree);
}
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setSize
(
const label nElem
)
{
// allocate more capacity?
if (nElem > capacity_)
{
// TODO: convince the compiler that division by zero does not occur
// if (SizeInc && (!SizeMult || !SizeDiv))
// {
// // resize with SizeInc as the granularity
// capacity_ = nElem;
// unsigned pad = SizeInc - (capacity_ % SizeInc);
// if (pad != SizeInc)
// {
// capacity_ += pad;
// }
// }
// else
{
capacity_ = max
(
nElem,
label(SizeInc + capacity_ * SizeMult / SizeDiv)
);
}
Field<T>::setSize(capacity_);
}
// adjust addressed size
Field<T>::size(nElem);
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setSize
(
const label nElem,
const T& t
)
{
label nextFree = Field<T>::size();
setSize(nElem);
// set new elements to constant value
while (nextFree < nElem)
{
this->operator[](nextFree++) = t;
}
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::resize
(
const label nElem
)
{
this->setSize(nElem);
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::resize
(
const label nElem,
const T& t
)
{
this->setSize(nElem, t);
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clear()
{
Field<T>::size(0);
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clearStorage()
{
Field<T>::clear();
capacity_ = 0;
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>&
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::shrink()
{
label nextFree = Field<T>::size();
if (capacity_ > nextFree)
{
// use the full list when resizing
Field<T>::size(capacity_);
// the new size
capacity_ = nextFree;
Field<T>::setSize(capacity_);
Field<T>::size(nextFree);
}
return *this;
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::Xfer<Foam::List<T> >
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::xfer()
{
return xferMoveTo< List<T> >(*this);
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>&
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::append
(
const T& t
)
{
const label elemI = List<T>::size();
setSize(elemI + 1);
this->operator[](elemI) = t;
return *this;
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>&
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::append
(
const UList<T>& lst
)
{
if (this == &lst)
{
FatalErrorIn
(
"DynamicField<T, SizeInc, SizeMult, SizeDiv>::append"
"(const UList<T>&)"
) << "attempted appending to self" << abort(FatalError);
}
label nextFree = List<T>::size();
setSize(nextFree + lst.size());
forAll(lst, elemI)
{
this->operator[](nextFree++) = lst[elemI];
}
return *this;
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline T Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::remove()
{
const label elemI = List<T>::size() - 1;
if (elemI < 0)
{
FatalErrorIn
(
"Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::remove()"
) << "List is empty" << abort(FatalError);
}
const T& val = List<T>::operator[](elemI);
List<T>::size(elemI);
return val;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
void Foam::DynamicField<Type>::operator=(const DynamicField<Type>& rhs)
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline T& Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator()
(
const label elemI
)
{
if (this == &rhs)
if (elemI >= Field<T>::size())
{
FatalErrorIn("DynamicField<Type>::operator=(const DynamicField<Type>&)")
<< "attempted assignment to self"
<< abort(FatalError);
setSize(elemI + 1);
}
Field<Type>::operator=(rhs);
capacity_ = Field<Type>::size();
return this->operator[](elemI);
}
template<class Type>
void Foam::DynamicField<Type>::operator=(const UList<Type>& rhs)
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
(
const T& t
)
{
Field<Type>::operator=(rhs);
capacity_ = Field<Type>::size();
UList<T>::operator=(t);
}
template<class Type>
void Foam::DynamicField<Type>::operator=(const tmp<DynamicField>& rhs)
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
(
const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst
)
{
if (this == &(rhs()))
if (this == &lst)
{
FatalErrorIn("DynamicField<Type>::operator=(const tmp<DynamicField>&)")
<< "attempted assignment to self"
<< abort(FatalError);
FatalErrorIn
(
"DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator="
"(const DynamicField<T, SizeInc, SizeMult, SizeDiv>&)"
) << "attempted assignment to self" << abort(FatalError);
}
// This is dodgy stuff, don't try it at home.
DynamicField* fieldPtr = rhs.ptr();
List<Type>::transfer(*fieldPtr);
delete fieldPtr;
capacity_ = Field<Type>::size();
if (capacity_ >= lst.size())
{
// can copy w/o reallocating, match initial size to avoid reallocation
Field<T>::size(lst.size());
Field<T>::operator=(lst);
}
else
{
// make everything available for the copy operation
Field<T>::size(capacity_);
Field<T>::operator=(lst);
capacity_ = Field<T>::size();
}
}
// * * * * * * * * * * * * * * * IOstream Operator * * * * * * * * * * * * * //
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
(
const UList<T>& lst
)
{
if (capacity_ >= lst.size())
{
// can copy w/o reallocating, match initial size to avoid reallocation
Field<T>::size(lst.size());
Field<T>::operator=(lst);
}
else
{
// make everything available for the copy operation
Field<T>::size(capacity_);
Field<T>::operator=(lst);
capacity_ = Field<T>::size();
}
}
// ************************************************************************* //

View File

@ -287,6 +287,7 @@ $(ddtSchemes)/steadyStateDdtScheme/steadyStateDdtSchemes.C
$(ddtSchemes)/EulerDdtScheme/EulerDdtSchemes.C
$(ddtSchemes)/CoEulerDdtScheme/CoEulerDdtSchemes.C
$(ddtSchemes)/SLTSDdtScheme/SLTSDdtSchemes.C
$(ddtSchemes)/localEulerDdtScheme/localEulerDdtSchemes.C
$(ddtSchemes)/backwardDdtScheme/backwardDdtSchemes.C
$(ddtSchemes)/boundedBackwardDdtScheme/boundedBackwardDdtScheme.C
$(ddtSchemes)/boundedBackwardDdtScheme/boundedBackwardDdtSchemes.C
@ -337,6 +338,7 @@ $(laplacianSchemes)/laplacianScheme/laplacianSchemes.C
$(laplacianSchemes)/gaussLaplacianScheme/gaussLaplacianSchemes.C
finiteVolume/fvc/fvcMeshPhi.C
finiteVolume/fvc/fvcSmooth/fvcSmooth.C
general = cfdTools/general
$(general)/findRefCell/findRefCell.C

View File

@ -0,0 +1,584 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "localEulerDdtScheme.H"
#include "surfaceInterpolate.H"
#include "fvMatrices.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace fv
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
const volScalarField& localEulerDdtScheme<Type>::localRDeltaT() const
{
return mesh().objectRegistry::lookupObject<volScalarField>(rDeltaTName_);
}
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> >
localEulerDdtScheme<Type>::fvcDdt
(
const dimensioned<Type>& dt
)
{
const volScalarField& rDeltaT = localRDeltaT();
IOobject ddtIOobject
(
"ddt(" + dt.name() + ')',
mesh().time().timeName(),
mesh()
);
if (mesh().moving())
{
tmp<GeometricField<Type, fvPatchField, volMesh> > tdtdt
(
new GeometricField<Type, fvPatchField, volMesh>
(
ddtIOobject,
mesh(),
dimensioned<Type>
(
"0",
dt.dimensions()/dimTime,
pTraits<Type>::zero
)
)
);
tdtdt().internalField() =
rDeltaT.internalField()*dt.value()*(1.0 - mesh().V0()/mesh().V());
return tdtdt;
}
else
{
return tmp<GeometricField<Type, fvPatchField, volMesh> >
(
new GeometricField<Type, fvPatchField, volMesh>
(
ddtIOobject,
mesh(),
dimensioned<Type>
(
"0",
dt.dimensions()/dimTime,
pTraits<Type>::zero
),
calculatedFvPatchField<Type>::typeName
)
);
}
}
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> >
localEulerDdtScheme<Type>::fvcDdt
(
const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
const volScalarField& rDeltaT = localRDeltaT();
IOobject ddtIOobject
(
"ddt(" + vf.name() + ')',
mesh().time().timeName(),
mesh()
);
if (mesh().moving())
{
return tmp<GeometricField<Type, fvPatchField, volMesh> >
(
new GeometricField<Type, fvPatchField, volMesh>
(
ddtIOobject,
mesh(),
rDeltaT.dimensions()*vf.dimensions(),
rDeltaT.internalField()*
(
vf.internalField()
- vf.oldTime().internalField()*mesh().V0()/mesh().V()
),
rDeltaT.boundaryField()*
(
vf.boundaryField() - vf.oldTime().boundaryField()
)
)
);
}
else
{
return tmp<GeometricField<Type, fvPatchField, volMesh> >
(
new GeometricField<Type, fvPatchField, volMesh>
(
ddtIOobject,
rDeltaT*(vf - vf.oldTime())
)
);
}
}
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> >
localEulerDdtScheme<Type>::fvcDdt
(
const dimensionedScalar& rho,
const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
const volScalarField& rDeltaT = localRDeltaT();
IOobject ddtIOobject
(
"ddt(" + rho.name() + ',' + vf.name() + ')',
mesh().time().timeName(),
mesh()
);
if (mesh().moving())
{
return tmp<GeometricField<Type, fvPatchField, volMesh> >
(
new GeometricField<Type, fvPatchField, volMesh>
(
ddtIOobject,
mesh(),
rDeltaT.dimensions()*rho.dimensions()*vf.dimensions(),
rDeltaT.internalField()*rho.value()*
(
vf.internalField()
- vf.oldTime().internalField()*mesh().V0()/mesh().V()
),
rDeltaT.boundaryField()*rho.value()*
(
vf.boundaryField() - vf.oldTime().boundaryField()
)
)
);
}
else
{
return tmp<GeometricField<Type, fvPatchField, volMesh> >
(
new GeometricField<Type, fvPatchField, volMesh>
(
ddtIOobject,
rDeltaT*rho*(vf - vf.oldTime())
)
);
}
}
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> >
localEulerDdtScheme<Type>::fvcDdt
(
const volScalarField& rho,
const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
const volScalarField& rDeltaT = localRDeltaT();
IOobject ddtIOobject
(
"ddt(" + rho.name() + ',' + vf.name() + ')',
mesh().time().timeName(),
mesh()
);
if (mesh().moving())
{
return tmp<GeometricField<Type, fvPatchField, volMesh> >
(
new GeometricField<Type, fvPatchField, volMesh>
(
ddtIOobject,
mesh(),
rDeltaT.dimensions()*rho.dimensions()*vf.dimensions(),
rDeltaT.internalField()*
(
rho.internalField()*vf.internalField()
- rho.oldTime().internalField()
*vf.oldTime().internalField()*mesh().V0()/mesh().V()
),
rDeltaT.boundaryField()*
(
rho.boundaryField()*vf.boundaryField()
- rho.oldTime().boundaryField()
*vf.oldTime().boundaryField()
)
)
);
}
else
{
return tmp<GeometricField<Type, fvPatchField, volMesh> >
(
new GeometricField<Type, fvPatchField, volMesh>
(
ddtIOobject,
rDeltaT*(rho*vf - rho.oldTime()*vf.oldTime())
)
);
}
}
template<class Type>
tmp<fvMatrix<Type> >
localEulerDdtScheme<Type>::fvmDdt
(
const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
tmp<fvMatrix<Type> > tfvm
(
new fvMatrix<Type>
(
vf,
vf.dimensions()*dimVol/dimTime
)
);
fvMatrix<Type>& fvm = tfvm();
const scalarField& rDeltaT = localRDeltaT().internalField();
fvm.diag() = rDeltaT*mesh().V();
if (mesh().moving())
{
fvm.source() = rDeltaT*vf.oldTime().internalField()*mesh().V0();
}
else
{
fvm.source() = rDeltaT*vf.oldTime().internalField()*mesh().V();
}
return tfvm;
}
template<class Type>
tmp<fvMatrix<Type> >
localEulerDdtScheme<Type>::fvmDdt
(
const dimensionedScalar& rho,
const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
tmp<fvMatrix<Type> > tfvm
(
new fvMatrix<Type>
(
vf,
rho.dimensions()*vf.dimensions()*dimVol/dimTime
)
);
fvMatrix<Type>& fvm = tfvm();
const scalarField& rDeltaT = localRDeltaT().internalField();
fvm.diag() = rDeltaT*rho.value()*mesh().V();
if (mesh().moving())
{
fvm.source() = rDeltaT
*rho.value()*vf.oldTime().internalField()*mesh().V0();
}
else
{
fvm.source() = rDeltaT
*rho.value()*vf.oldTime().internalField()*mesh().V();
}
return tfvm;
}
template<class Type>
tmp<fvMatrix<Type> >
localEulerDdtScheme<Type>::fvmDdt
(
const volScalarField& rho,
const GeometricField<Type, fvPatchField, volMesh>& vf
)
{
tmp<fvMatrix<Type> > tfvm
(
new fvMatrix<Type>
(
vf,
rho.dimensions()*vf.dimensions()*dimVol/dimTime
)
);
fvMatrix<Type>& fvm = tfvm();
const scalarField& rDeltaT = localRDeltaT().internalField();
fvm.diag() = rDeltaT*rho.internalField()*mesh().V();
if (mesh().moving())
{
fvm.source() = rDeltaT
*rho.oldTime().internalField()
*vf.oldTime().internalField()*mesh().V0();
}
else
{
fvm.source() = rDeltaT
*rho.oldTime().internalField()
*vf.oldTime().internalField()*mesh().V();
}
return tfvm;
}
template<class Type>
tmp<typename localEulerDdtScheme<Type>::fluxFieldType>
localEulerDdtScheme<Type>::fvcDdtPhiCorr
(
const volScalarField& rA,
const GeometricField<Type, fvPatchField, volMesh>& U,
const fluxFieldType& phi
)
{
IOobject ddtIOobject
(
"ddtPhiCorr(" + rA.name() + ',' + U.name() + ',' + phi.name() + ')',
mesh().time().timeName(),
mesh()
);
if (mesh().moving())
{
return tmp<fluxFieldType>
(
new fluxFieldType
(
ddtIOobject,
mesh(),
dimensioned<typename flux<Type>::type>
(
"0",
rA.dimensions()*phi.dimensions()/dimTime,
pTraits<typename flux<Type>::type>::zero
)
)
);
}
else
{
const volScalarField& rDeltaT = localRDeltaT();
return tmp<fluxFieldType>
(
new fluxFieldType
(
ddtIOobject,
fvcDdtPhiCoeff(U.oldTime(), phi.oldTime())*
(
fvc::interpolate(rDeltaT*rA)*phi.oldTime()
- (fvc::interpolate(rDeltaT*rA*U.oldTime()) & mesh().Sf())
)
)
);
}
}
template<class Type>
tmp<typename localEulerDdtScheme<Type>::fluxFieldType>
localEulerDdtScheme<Type>::fvcDdtPhiCorr
(
const volScalarField& rA,
const volScalarField& rho,
const GeometricField<Type, fvPatchField, volMesh>& U,
const fluxFieldType& phi
)
{
IOobject ddtIOobject
(
"ddtPhiCorr("
+ rA.name() + ',' + rho.name() + ',' + U.name() + ',' + phi.name() + ')',
mesh().time().timeName(),
mesh()
);
if (mesh().moving())
{
return tmp<fluxFieldType>
(
new fluxFieldType
(
ddtIOobject,
mesh(),
dimensioned<typename flux<Type>::type>
(
"0",
rA.dimensions()*rho.dimensions()*phi.dimensions()/dimTime,
pTraits<typename flux<Type>::type>::zero
)
)
);
}
else
{
const volScalarField& rDeltaT = localRDeltaT();
if
(
U.dimensions() == dimVelocity
&& phi.dimensions() == dimVelocity*dimArea
)
{
return tmp<fluxFieldType>
(
new fluxFieldType
(
ddtIOobject,
fvcDdtPhiCoeff(U.oldTime(), phi.oldTime())
*(
fvc::interpolate(rDeltaT*rA*rho.oldTime())*phi.oldTime()
- (fvc::interpolate(rDeltaT*rA*rho.oldTime()*U.oldTime())
& mesh().Sf())
)
)
);
}
else if
(
U.dimensions() == dimVelocity
&& phi.dimensions() == dimDensity*dimVelocity*dimArea
)
{
return tmp<fluxFieldType>
(
new fluxFieldType
(
ddtIOobject,
fvcDdtPhiCoeff
(
U.oldTime(),
phi.oldTime()/fvc::interpolate(rho.oldTime())
)
*(
fvc::interpolate(rDeltaT*rA*rho.oldTime())
*phi.oldTime()/fvc::interpolate(rho.oldTime())
- (
fvc::interpolate
(
rDeltaT*rA*rho.oldTime()*U.oldTime()
) & mesh().Sf()
)
)
)
);
}
else if
(
U.dimensions() == dimDensity*dimVelocity
&& phi.dimensions() == dimDensity*dimVelocity*dimArea
)
{
return tmp<fluxFieldType>
(
new fluxFieldType
(
ddtIOobject,
fvcDdtPhiCoeff(rho.oldTime(), U.oldTime(), phi.oldTime())
*(
fvc::interpolate(rDeltaT*rA)*phi.oldTime()
- (
fvc::interpolate(rDeltaT*rA*U.oldTime())&mesh().Sf()
)
)
)
);
}
else
{
FatalErrorIn
(
"localEulerDdtScheme<Type>::fvcDdtPhiCorr"
) << "dimensions of phi are not correct"
<< abort(FatalError);
return fluxFieldType::null();
}
}
}
template<class Type>
tmp<surfaceScalarField> localEulerDdtScheme<Type>::meshPhi
(
const GeometricField<Type, fvPatchField, volMesh>&
)
{
return tmp<surfaceScalarField>
(
new surfaceScalarField
(
IOobject
(
"meshPhi",
mesh().time().timeName(),
mesh()
),
mesh(),
dimensionedScalar("0", dimVolume/dimTime, 0.0)
)
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,210 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::fv::localEulerDdtScheme
Description
Local time-step first-order Euler implicit/explicit ddt.
The reciprocal of the local time-step field is looked-up from the
database with the name provided.
This scheme should only be used for steady-state computations
using transient codes where local time-stepping is preferably to
under-relaxation for transport consistency reasons.
See also CoEulerDdtScheme.
SourceFiles
localEulerDdtScheme.C
localEulerDdtSchemes.C
\*---------------------------------------------------------------------------*/
#ifndef localEulerDdtScheme_H
#define localEulerDdtScheme_H
#include "ddtScheme.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace fv
{
/*---------------------------------------------------------------------------*\
Class localEulerDdtScheme Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class localEulerDdtScheme
:
public fv::ddtScheme<Type>
{
// Private Data
//- Name of the reciprocal local time-step field
word rDeltaTName_;
// Private Member Functions
//- Disallow default bitwise copy construct
localEulerDdtScheme(const localEulerDdtScheme&);
//- Disallow default bitwise assignment
void operator=(const localEulerDdtScheme&);
//- Return the reciprocal of the local time-step
const volScalarField& localRDeltaT() const;
public:
//- Runtime type information
TypeName("localEuler");
// Constructors
//- Construct from mesh and Istream
localEulerDdtScheme(const fvMesh& mesh, Istream& is)
:
ddtScheme<Type>(mesh, is),
rDeltaTName_(is)
{}
// Member Functions
//- Return mesh reference
const fvMesh& mesh() const
{
return fv::ddtScheme<Type>::mesh();
}
tmp<GeometricField<Type, fvPatchField, volMesh> > fvcDdt
(
const dimensioned<Type>&
);
tmp<GeometricField<Type, fvPatchField, volMesh> > fvcDdt
(
const GeometricField<Type, fvPatchField, volMesh>&
);
tmp<GeometricField<Type, fvPatchField, volMesh> > fvcDdt
(
const dimensionedScalar&,
const GeometricField<Type, fvPatchField, volMesh>&
);
tmp<GeometricField<Type, fvPatchField, volMesh> > fvcDdt
(
const volScalarField&,
const GeometricField<Type, fvPatchField, volMesh>&
);
tmp<fvMatrix<Type> > fvmDdt
(
const GeometricField<Type, fvPatchField, volMesh>&
);
tmp<fvMatrix<Type> > fvmDdt
(
const dimensionedScalar&,
const GeometricField<Type, fvPatchField, volMesh>&
);
tmp<fvMatrix<Type> > fvmDdt
(
const volScalarField&,
const GeometricField<Type, fvPatchField, volMesh>&
);
typedef typename ddtScheme<Type>::fluxFieldType fluxFieldType;
tmp<fluxFieldType> fvcDdtPhiCorr
(
const volScalarField& rA,
const GeometricField<Type, fvPatchField, volMesh>& U,
const fluxFieldType& phi
);
tmp<fluxFieldType> fvcDdtPhiCorr
(
const volScalarField& rA,
const volScalarField& rho,
const GeometricField<Type, fvPatchField, volMesh>& U,
const fluxFieldType& phi
);
tmp<surfaceScalarField> meshPhi
(
const GeometricField<Type, fvPatchField, volMesh>&
);
};
template<>
tmp<surfaceScalarField> localEulerDdtScheme<scalar>::fvcDdtPhiCorr
(
const volScalarField& rA,
const volScalarField& U,
const surfaceScalarField& phi
);
template<>
tmp<surfaceScalarField> localEulerDdtScheme<scalar>::fvcDdtPhiCorr
(
const volScalarField& rA,
const volScalarField& rho,
const volScalarField& U,
const surfaceScalarField& phi
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "localEulerDdtScheme.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "localEulerDdtScheme.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
makeFvDdtScheme(localEulerDdtScheme)
}
}
// ************************************************************************* //

View File

@ -0,0 +1,324 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "fvcSmooth.H"
#include "volFields.H"
#include "FaceCellWave.H"
#include "smoothData.H"
#include "sweepData.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::scalar Foam::smoothData::maxRatio = 1.0;
void Foam::fvc::smooth
(
volScalarField& field,
const scalar coeff
)
{
const fvMesh& mesh = field.mesh();
smoothData::maxRatio = 1 + coeff;
DynamicList<label> changedFaces(mesh.nFaces()/100 + 100);
DynamicList<smoothData> changedFacesInfo(changedFaces.size());
const unallocLabelList& owner = mesh.owner();
const unallocLabelList& neighbour = mesh.neighbour();
forAll(owner, facei)
{
const label own = owner[facei];
const label nbr = neighbour[facei];
// Check if owner value much larger than neighbour value or vice versa
if (field[own] > smoothData::maxRatio*field[nbr])
{
changedFaces.append(facei);
changedFacesInfo.append(smoothData(field[own]));
}
else if (field[nbr] > smoothData::maxRatio*field[own])
{
changedFaces.append(facei);
changedFacesInfo.append(smoothData(field[nbr]));
}
}
// Insert all faces of coupled patches - FaceCellWave will correct them
forAll(mesh.boundaryMesh(), patchi)
{
const polyPatch& patch = mesh.boundaryMesh()[patchi];
if (patch.coupled())
{
forAll(patch, patchFacei)
{
label facei = patch.start() + patchFacei;
label own = mesh.faceOwner()[facei];
changedFaces.append(facei);
changedFacesInfo.append(smoothData(field[own]));
}
}
}
changedFaces.shrink();
changedFacesInfo.shrink();
// Set initial field on cells
List<smoothData> cellData(mesh.nCells());
forAll(field, celli)
{
cellData[celli] = field[celli];
}
// Set initial field on faces
List<smoothData> faceData(mesh.nFaces());
// Propagate information over whole domain
FaceCellWave<smoothData > smoothData
(
mesh,
changedFaces,
changedFacesInfo,
faceData,
cellData,
mesh.globalData().nTotalCells() // max iterations
);
forAll(field, celli)
{
field[celli] = cellData[celli].value();
}
field.correctBoundaryConditions();
}
void Foam::fvc::spread
(
volScalarField& field,
const volScalarField& alpha,
const label nLayers,
const scalar alphaDiff,
const scalar alphaMax,
const scalar alphaMin
)
{
const fvMesh& mesh = field.mesh();
smoothData::maxRatio = 1;
DynamicList<label> changedFaces(mesh.nFaces()/100 + 100);
DynamicList<smoothData> changedFacesInfo(changedFaces.size());
// Set initial field on cells
List<smoothData> cellData(mesh.nCells());
forAll(field, celli)
{
cellData[celli] = field[celli];
}
// Set initial field on faces
List<smoothData> faceData(mesh.nFaces());
const unallocLabelList& owner = mesh.owner();
const unallocLabelList& neighbour = mesh.neighbour();
forAll(owner, facei)
{
const label own = owner[facei];
const label nbr = neighbour[facei];
if
(
(alpha[own] > alphaMin && alpha[own] < alphaMax)
|| (alpha[nbr] > alphaMin && alpha[nbr] < alphaMax)
)
{
if (mag(alpha[own] - alpha[nbr]) > alphaDiff)
{
changedFaces.append(facei);
changedFacesInfo.append
(
smoothData(max(field[own], field[nbr]))
);
}
}
}
// Insert all faces of coupled patches - FaceCellWave will correct them
forAll(mesh.boundaryMesh(), patchi)
{
const polyPatch& patch = mesh.boundaryMesh()[patchi];
if (patch.coupled())
{
forAll(patch, patchFacei)
{
label facei = patch.start() + patchFacei;
label own = mesh.faceOwner()[facei];
scalarField alphapn =
alpha.boundaryField()[patchi].patchNeighbourField();
if
(
(alpha[own] > alphaMin && alpha[own] < alphaMax)
|| (
alphapn[patchFacei] > alphaMin
&& alphapn[patchFacei] < alphaMax
)
)
{
if (mag(alpha[own] - alphapn[patchFacei]) > alphaDiff)
{
changedFaces.append(facei);
changedFacesInfo.append(smoothData(field[own]));
}
}
}
}
}
changedFaces.shrink();
changedFacesInfo.shrink();
// Propagate information over whole domain
FaceCellWave<smoothData> smoothData
(
mesh,
faceData,
cellData
);
smoothData.setFaceInfo(changedFaces, changedFacesInfo);
smoothData.iterate(nLayers);
forAll(field, celli)
{
field[celli] = cellData[celli].value();
}
field.correctBoundaryConditions();
}
void Foam::fvc::sweep
(
volScalarField& field,
const volScalarField& alpha,
const label nLayers,
const scalar alphaDiff
)
{
const fvMesh& mesh = field.mesh();
DynamicList<label> changedFaces(mesh.nFaces()/100 + 100);
DynamicList<sweepData> changedFacesInfo(changedFaces.size());
// Set initial field on cells
List<sweepData> cellData(mesh.nCells());
// Set initial field on faces
List<sweepData> faceData(mesh.nFaces());
const unallocLabelList& owner = mesh.owner();
const unallocLabelList& neighbour = mesh.neighbour();
const vectorField& Cf = mesh.faceCentres();
forAll(owner, facei)
{
const label own = owner[facei];
const label nbr = neighbour[facei];
if (mag(alpha[own] - alpha[nbr]) > alphaDiff)
{
changedFaces.append(facei);
changedFacesInfo.append
(
sweepData(max(field[own], field[nbr]), Cf[facei])
);
}
}
// Insert all faces of coupled patches - FaceCellWave will correct them
forAll(mesh.boundaryMesh(), patchi)
{
const polyPatch& patch = mesh.boundaryMesh()[patchi];
if (patch.coupled())
{
forAll(patch, patchFacei)
{
label facei = patch.start() + patchFacei;
label own = mesh.faceOwner()[facei];
scalarField alphapn =
alpha.boundaryField()[patchi].patchNeighbourField();
if (mag(alpha[own] - alphapn[patchFacei]) > alphaDiff)
{
changedFaces.append(facei);
changedFacesInfo.append
(
sweepData(field[own], Cf[facei])
);
}
}
}
}
changedFaces.shrink();
changedFacesInfo.shrink();
// Propagate information over whole domain
FaceCellWave<sweepData> sweepData
(
mesh,
faceData,
cellData
);
sweepData.setFaceInfo(changedFaces, changedFacesInfo);
sweepData.iterate(nLayers);
forAll(field, celli)
{
if (cellData[celli].valid())
{
field[celli] = max(field[celli], cellData[celli].value());
}
}
field.correctBoundaryConditions();
}
// ************************************************************************* //

View File

@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InNamespace
Foam::fvc
Description
Provides functions smooth spread and sweep which use the FaceCellWave
algorithm to smooth and redistribute the first field argument.
smooth: smooths the field by ensuring the values in neighbouring cells are
at least coeff* the cell value.
spread: redistributes the field by spreading the maximum value within the
region defined by the value (being between alphaMax and alphaMin)
and gradient of alpha (where the difference between the values in
neighbouring cells is larger than alphaDiff).
sweep: redistributes the field by sweeping the maximum value where the
gradient of alpha is large (where the difference between the values
in neighbouring cells is larger than alphaDiff) away from that
starting point of the sweep.
SourceFiles
fvcSmooth.C
\*---------------------------------------------------------------------------*/
#ifndef fvcSmooth_H
#define fvcSmooth_H
#include "volFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fvc
{
void smooth
(
volScalarField& field,
const scalar coeff
);
void spread
(
volScalarField& field,
const volScalarField& alpha,
const label nLayers,
const scalar alphaDiff = 0.2,
const scalar alphaMax = 0.99,
const scalar alphaMin = 0.01
);
void sweep
(
volScalarField& field,
const volScalarField& alpha,
const label nLayers,
const scalar alphaDiff = 0.2
);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,204 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::smoothData
Description
Helper class used by the fvc::smooth and fvc::spread functions.
SourceFiles
smoothData.H
smoothDataI.H
\*---------------------------------------------------------------------------*/
#ifndef smoothData_H
#define smoothData_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class smoothData Declaration
\*---------------------------------------------------------------------------*/
class smoothData
{
scalar value_;
// Private Member Functions
//- Update - gets information from neighbouring face/cell and
// uses this to update itself (if necessary) and return true
inline bool update
(
const smoothData& svf,
const scalar scale,
const scalar tol
);
public:
// Static data members
//- Field fraction
static scalar maxRatio;
// Constructors
//- Construct null
inline smoothData();
//- Construct from inverse field value
inline smoothData(const scalar value);
// Member Functions
// Access
//- Return value
scalar value() const
{
return value_;
}
// Needed by FaceCellWave
//- Check whether origin has been changed at all or
// still contains original (invalid) value
inline bool valid() const;
//- Check for identical geometrical data
// Used for cyclics checking
inline bool sameGeometry
(
const polyMesh&,
const smoothData&,
const scalar
) const;
//- Convert any absolute coordinates into relative to
// (patch)face centre
inline void leaveDomain
(
const polyMesh&,
const polyPatch&,
const label patchFaceI,
const point& faceCentre
);
//- Reverse of leaveDomain
inline void enterDomain
(
const polyMesh&,
const polyPatch&,
const label patchFaceI,
const point& faceCentre
);
//- Apply rotation matrix to any coordinates
inline void transform
(
const polyMesh&,
const tensor&
);
//- Influence of neighbouring face
inline bool updateCell
(
const polyMesh&,
const label thisCellI,
const label neighbourFaceI,
const smoothData& svf,
const scalar tol
);
//- Influence of neighbouring cell
inline bool updateFace
(
const polyMesh&,
const label thisFaceI,
const label neighbourCellI,
const smoothData& svf,
const scalar tol
);
//- Influence of different value on same face
inline bool updateFace
(
const polyMesh&,
const label thisFaceI,
const smoothData& svf,
const scalar tol
);
// Member Operators
inline void operator=(const scalar value);
// Needed for List IO
inline bool operator==(const smoothData&) const;
inline bool operator!=(const smoothData&) const;
// IOstream Operators
friend Ostream& operator<<
(
Ostream& os,
const smoothData& svf
)
{
return os << svf.value_;
}
friend Istream& operator>>(Istream& is, smoothData& svf)
{
return is >> svf.value_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "smoothDataI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,192 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
inline bool Foam::smoothData::update
(
const smoothData& svf,
const scalar scale,
const scalar tol
)
{
if (!valid() || (value_ < VSMALL))
{
// My value not set - take over neighbour
value_ = svf.value()/scale;
// Something changed - let caller know
return true;
}
else if (svf.value() > (1 + tol)*scale*value_)
{
// Neighbour is too big for me - Up my value
value_ = svf.value()/scale;
// Something changed - let caller know
return true;
}
else
{
// Neighbour is not too big for me or change is too small
// Nothing changed
return false;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::smoothData::smoothData()
:
value_(-GREAT)
{}
inline Foam::smoothData::smoothData(const scalar value)
:
value_(value)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::smoothData::valid() const
{
return value_ > -SMALL;
}
inline bool Foam::smoothData::sameGeometry
(
const polyMesh&,
const smoothData&,
const scalar
) const
{
return true;
}
inline void Foam::smoothData::leaveDomain
(
const polyMesh&,
const polyPatch&,
const label,
const point&
)
{}
inline void Foam::smoothData::transform
(
const polyMesh&,
const tensor&
)
{}
inline void Foam::smoothData::enterDomain
(
const polyMesh&,
const polyPatch&,
const label,
const point&
)
{}
inline bool Foam::smoothData::updateCell
(
const polyMesh&,
const label,
const label,
const smoothData& svf,
const scalar tol
)
{
// Take over info from face if more than deltaRatio larger
return update(svf, maxRatio, tol);
}
inline bool Foam::smoothData::updateFace
(
const polyMesh&,
const label,
const label,
const smoothData& svf,
const scalar tol
)
{
// Take over information from cell without any scaling (scale = 1.0)
return update(svf, 1.0, tol);
}
// Update this (face) with coupled face information.
inline bool Foam::smoothData::updateFace
(
const polyMesh&,
const label,
const smoothData& svf,
const scalar tol
)
{
// Take over information from coupled face without any scaling (scale = 1.0)
return update(svf, 1.0, tol);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline void Foam::smoothData::operator=
(
const scalar value
)
{
value_ = value;
}
inline bool Foam::smoothData::operator==
(
const smoothData& rhs
) const
{
return value_ == rhs.value();
}
inline bool Foam::smoothData::operator!=
(
const smoothData& rhs
) const
{
return !(*this == rhs);
}
// ************************************************************************* //

View File

@ -0,0 +1,205 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::sweepData
Description
Helper class used by fvc::sweep function.
SourceFiles
sweepData.H
sweepDataI.H
\*---------------------------------------------------------------------------*/
#ifndef sweepData_H
#define sweepData_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class sweepData Declaration
\*---------------------------------------------------------------------------*/
class sweepData
{
scalar value_;
point origin_;
// Private Member Functions
//- Update - gets information from neighbouring face/cell and
// uses this to update itself (if necessary) and return true
inline bool update
(
const sweepData& svf,
const point& position,
const scalar tol
);
public:
// Constructors
//- Construct null
inline sweepData();
//- Construct from component
inline sweepData(const scalar value, const point& origin);
// Member Functions
// Access
//- Return value
scalar value() const
{
return value_;
}
//- Return origin
const point& origin() const
{
return origin_;
}
// Needed by FaceCellWave
//- Check whether origin has been changed at all or
// still contains original (invalid) value
inline bool valid() const;
//- Check for identical geometrical data
// Used for cyclics checking
inline bool sameGeometry
(
const polyMesh&,
const sweepData&,
const scalar
) const;
//- Convert any absolute coordinates into relative to
// (patch)face centre
inline void leaveDomain
(
const polyMesh&,
const polyPatch&,
const label patchFaceI,
const point& faceCentre
);
//- Reverse of leaveDomain
inline void enterDomain
(
const polyMesh&,
const polyPatch&,
const label patchFaceI,
const point& faceCentre
);
//- Apply rotation matrix to any coordinates
inline void transform
(
const polyMesh&,
const tensor&
);
//- Influence of neighbouring face
inline bool updateCell
(
const polyMesh&,
const label thisCellI,
const label neighbourFaceI,
const sweepData& svf,
const scalar tol
);
//- Influence of neighbouring cell
inline bool updateFace
(
const polyMesh&,
const label thisFaceI,
const label neighbourCellI,
const sweepData& svf,
const scalar tol
);
//- Influence of different value on same face
inline bool updateFace
(
const polyMesh&,
const label thisFaceI,
const sweepData& svf,
const scalar tol
);
// Member Operators
inline void operator=(const scalar value);
// Needed for List IO
inline bool operator==(const sweepData&) const;
inline bool operator!=(const sweepData&) const;
// IOstream Operators
friend Ostream& operator<<
(
Ostream& os,
const sweepData& svf
)
{
return os << svf.value_ << svf.origin_;
}
friend Istream& operator>>(Istream& is, sweepData& svf)
{
return is >> svf.value_ >> svf.origin_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "sweepDataI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,208 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "transform.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
inline bool Foam::sweepData::update
(
const sweepData& svf,
const point& position,
const scalar tol
)
{
if (!valid())
{
operator=(svf);
return true;
}
scalar myDist2 = magSqr(position - origin());
if (myDist2 < SMALL)
{
if (svf.value() > value())
{
operator=(svf);
return true;
}
else
{
return false;
}
}
scalar dist2 = magSqr(position - svf.origin());
if (dist2 < myDist2)
{
operator=(svf);
return true;
}
return false;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::sweepData::sweepData()
:
value_(-GREAT),
origin_(vector::max)
{}
inline Foam::sweepData::sweepData(const scalar value, const point& origin)
:
value_(value),
origin_(origin)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::sweepData::valid() const
{
return value_ > -SMALL;
}
inline bool Foam::sweepData::sameGeometry
(
const polyMesh&,
const sweepData&,
const scalar
) const
{
return true;
}
inline void Foam::sweepData::leaveDomain
(
const polyMesh&,
const polyPatch&,
const label,
const point& faceCentre
)
{
origin_ -= faceCentre;
}
inline void Foam::sweepData::transform
(
const polyMesh&,
const tensor& rotTensor
)
{
origin_ = Foam::transform(rotTensor, origin_);
}
inline void Foam::sweepData::enterDomain
(
const polyMesh&,
const polyPatch&,
const label,
const point& faceCentre
)
{
// back to absolute form
origin_ += faceCentre;
}
inline bool Foam::sweepData::updateCell
(
const polyMesh& mesh,
const label thisCellI,
const label,
const sweepData& svf,
const scalar tol
)
{
return update(svf, mesh.cellCentres()[thisCellI], tol);
}
inline bool Foam::sweepData::updateFace
(
const polyMesh& mesh,
const label thisFaceI,
const label,
const sweepData& svf,
const scalar tol
)
{
return update(svf, mesh.faceCentres()[thisFaceI], tol);
}
// Update this (face) with coupled face information.
inline bool Foam::sweepData::updateFace
(
const polyMesh& mesh,
const label thisFaceI,
const sweepData& svf,
const scalar tol
)
{
return update(svf, mesh.faceCentres()[thisFaceI], tol);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline void Foam::sweepData::operator=
(
const scalar value
)
{
value_ = value;
}
inline bool Foam::sweepData::operator==
(
const sweepData& rhs
) const
{
return origin() == rhs.origin();
}
inline bool Foam::sweepData::operator!=
(
const sweepData& rhs
) const
{
return !(*this == rhs);
}
// ************************************************************************* //

View File

@ -617,30 +617,25 @@ bool Foam::meshSearch::pointInCell(const point& p, label cellI) const
{
label faceI = cFaces[i];
const face& f = mesh_.faces()[faceI];
pointHit inter = mesh_.faces()[faceI].ray
(
ctr,
dir,
mesh_.points(),
intersection::HALF_RAY,
intersection::VECTOR
);
forAll(f, fp)
if (inter.hit())
{
pointHit inter = f.ray
(
ctr,
dir,
mesh_.points(),
intersection::HALF_RAY,
intersection::VECTOR
);
scalar dist = inter.distance();
if (inter.hit())
if (dist < magDir)
{
scalar dist = inter.distance();
// Valid hit. Hit face so point is not in cell.
intersection::setPlanarTol(oldTol);
if (dist < magDir)
{
// Valid hit. Hit face so point is not in cell.
intersection::setPlanarTol(oldTol);
return false;
}
return false;
}
}
}

View File

@ -53,16 +53,10 @@ void Foam::streamLine::track()
initialParticles
);
//Pout<< "Seeding particles." << endl;
const sampledSet& seedPoints = sampledSetPtr_();
forAll(seedPoints, i)
{
//Pout<< "Seeded particle at " << seedPoints[i]
// << " at cell:" << seedPoints.cells()[i]
// << endl;
particles.addParticle
(
new streamLineParticle
@ -228,15 +222,14 @@ void Foam::streamLine::track()
vvInterp,
UIndex, // index of U in vvInterp
trackForward_, // track in +u direction
nSubCycle_, // step through cells in steps?
allTracks_,
allScalars_,
allVectors_
);
// Track
//Pout<< "Tracking particles." << endl;
particles.move(td);
//Pout<< "Finished tracking particles." << endl;
}
@ -296,6 +289,19 @@ void Foam::streamLine::read(const dictionary& dict)
UName_ = dict.lookupOrDefault<word>("U", "U");
dict.lookup("trackForward") >> trackForward_;
dict.lookup("lifeTime") >> lifeTime_;
if (lifeTime_ < 1)
{
FatalErrorIn(":streamLine::read(const dictionary&)")
<< "Illegal value " << lifeTime_ << " for lifeTime"
<< exit(FatalError);
}
dict.lookup("nSubCycle") >> nSubCycle_;
if (nSubCycle_ < 1)
{
nSubCycle_ = 1;
}
cloudName_ = dict.lookupOrDefault<word>("cloudName", "streamLine");
dict.lookup("seedSampleSet") >> seedSet_;
@ -323,7 +329,6 @@ void Foam::streamLine::execute()
{
// const Time& runTime = const_cast<Time&>(obr_.time());
// Pout<< "**streamLine::execute : time:" << runTime.timeName() << endl;
// Pout<< "**streamLine::execute : time:" << runTime.timeIndex() << endl;
//
// bool isOutputTime = false;
//

View File

@ -92,6 +92,9 @@ class streamLine
//- Maximum lifetime (= number of cells) of particle
label lifeTime_;
//- Number of subcycling steps
label nSubCycle_;
//- Optional specified name of particles
word cloudName_;

View File

@ -36,6 +36,25 @@ namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Estimate dt to cross cell in a few steps
Foam::scalar Foam::streamLineParticle::calcSubCycleDeltaT
(
streamLineParticle::trackData& td,
const scalar dt,
const vector& U
) const
{
streamLineParticle testParticle(*this);
bool oldKeepParticle = td.keepParticle;
bool oldSwitchProcessor = td.switchProcessor;
scalar fraction = testParticle.trackToFace(position()+dt*U, td);
td.keepParticle = oldKeepParticle;
td.switchProcessor = oldSwitchProcessor;
// Adapt the dt to subdivide the trajectory into 4 substeps.
return dt*fraction/td.nSubCycle_;
}
Foam::vector Foam::streamLineParticle::interpolateFields
(
const streamLineParticle::trackData& td,
@ -170,34 +189,60 @@ bool Foam::streamLineParticle::move(streamLineParticle::trackData& td)
&& lifeTime_ > 0
)
{
// TBD: implement subcycling so step through cells in more than
// one step.
// set the lagrangian time-step
scalar dt = min(dtMax, tEnd);
// Store current position and sampled velocity.
--lifeTime_;
sampledPositions_.append(position());
vector U = interpolateFields(td, position(), cell());
if (!td.trackForward_)
// Cross cell in steps:
// - at subiter 0 calculate dt to cross cell in nSubCycle steps
// - at the last subiter do all of the remaining track
// - do a few more subiters than nSubCycle since velocity might
// be decreasing
for (label subIter = 0; subIter < 2*td.nSubCycle_; subIter++)
{
U = -U;
}
--lifeTime_;
dt *= trackToFace(position()+dt*U, td);
// Store current position and sampled velocity.
sampledPositions_.append(position());
vector U = interpolateFields(td, position(), cell());
tEnd -= dt;
stepFraction() = 1.0 - tEnd/deltaT;
if (!td.trackForward_)
{
U = -U;
}
if (tEnd <= ROOTVSMALL)
{
// Force removal
lifeTime_ = 0;
if (subIter == 0 && td.nSubCycle_ > 1)
{
// Adapt dt to cross cell in a few steps
dt = calcSubCycleDeltaT(td, dt, U);
}
else if (subIter == td.nSubCycle_-1)
{
// Do full step on last subcycle
dt = min(dtMax, tEnd);
}
scalar fraction = trackToFace(position()+dt*U, td);
dt *= fraction;
tEnd -= dt;
stepFraction() = 1.0 - tEnd/deltaT;
if (tEnd <= ROOTVSMALL)
{
// Force removal
lifeTime_ = 0;
}
if (!td.keepParticle || td.switchProcessor || lifeTime_ == 0)
{
break;
}
}
}
if (!td.keepParticle || lifeTime_ == 0)
{
if (lifeTime_ == 0)

View File

@ -72,6 +72,7 @@ public:
const PtrList<interpolationCellPoint<vector> >& vvInterp_;
const label UIndex_;
const bool trackForward_;
const label nSubCycle_;
DynamicList<vectorList>& allPositions_;
List<DynamicList<scalarList> >& allScalars_;
@ -87,6 +88,7 @@ public:
const PtrList<interpolationCellPoint<vector> >& vvInterp,
const label UIndex,
const bool trackForward,
const label nSubCycle,
DynamicList<List<point> >& allPositions,
List<DynamicList<scalarList> >& allScalars,
List<DynamicList<vectorList> >& allVectors
@ -97,6 +99,7 @@ public:
vvInterp_(vvInterp),
UIndex_(UIndex),
trackForward_(trackForward),
nSubCycle_(nSubCycle),
allPositions_(allPositions),
allScalars_(allScalars),
allVectors_(allVectors)
@ -123,6 +126,15 @@ private:
// Private Member Functions
//- Estimate dt to cross from current face to next one in nSubCycle
// steps.
scalar calcSubCycleDeltaT
(
streamLineParticle::trackData& td,
const scalar dt,
const vector& U
) const;
//- Interpolate all quantities; return interpolated velocity.
vector interpolateFields
(