Merge branch 'master' of /home/hunt2/OpenFOAM/OpenFOAM-dev

This commit is contained in:
mattijs
2008-09-28 19:27:13 +01:00
24 changed files with 2722 additions and 249 deletions

View File

@ -179,6 +179,7 @@ matrices/solution/solution.C
scalarMatrix = matrices/scalarMatrix
$(scalarMatrix)/scalarMatrix.C
$(scalarMatrix)/SVD/SVD.C
LUscalarMatrix = matrices/LUscalarMatrix
$(LUscalarMatrix)/LUscalarMatrix.C

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "DiagonalMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::DiagonalMatrix<Type>::DiagonalMatrix(const Matrix<Type>& a)
:
List<Type>(min(a.n(), a.m()))
{
forAll(*this, i)
{
this->operator[](i) = a[i][i];
}
}
template<class Type>
Foam::DiagonalMatrix<Type>::DiagonalMatrix(const label size)
:
List<Type>(size)
{}
template<class Type>
Foam::DiagonalMatrix<Type>::DiagonalMatrix(const label size, const Type& val)
:
List<Type>(size, val)
{}
template<class Type>
Foam::DiagonalMatrix<Type>& Foam::DiagonalMatrix<Type>::invert()
{
forAll(*this, i)
{
Type x = this->operator[](i);
if (mag(x) < VSMALL)
{
this->operator[](i) = Type(0);
}
else
{
this->operator[](i) = Type(1)/x;
}
}
return this;
}
template<class Type>
Foam::DiagonalMatrix<Type> Foam::inv(const DiagonalMatrix<Type>& A)
{
DiagonalMatrix<Type> Ainv = A;
forAll(A, i)
{
Type x = A[i];
if (mag(x) < VSMALL)
{
Ainv[i] = Type(0);
}
else
{
Ainv[i] = Type(1)/x;
}
}
return Ainv;
}
// ************************************************************************* //

View File

@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::DiagonalMatrix<Type>
Description
DiagonalMatrix<Type> is a 2D diagonal matrix of objects
of type Type, size nxn
SourceFiles
DiagonalMatrix.C
\*---------------------------------------------------------------------------*/
#ifndef DiagonalMatrix_H
#define DiagonalMatrix_H
#include "List.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * Class Forward declaration * * * * * * * * * * * //
template<class Type> class Matrix;
/*---------------------------------------------------------------------------*\
Class DiagonalMatrix Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class DiagonalMatrix
:
public List<Type>
{
public:
// Constructors
//- Construct from diagonal component of a Matrix
DiagonalMatrix<Type>(const Matrix<Type>&);
//- Construct empty from size
DiagonalMatrix<Type>(const label size);
//- Construct from size and a value
DiagonalMatrix<Type>(const label, const Type&);
// Member functions
//- Invert the diaganol matrix and return itself
DiagonalMatrix<Type>& invert();
};
// Global functions
//- Return the diagonal Matrix inverse
template<class Type>
DiagonalMatrix<Type> inv(const DiagonalMatrix<Type>&);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "DiagonalMatrix.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -28,16 +28,16 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
void Foam::LUscalarMatrix::solve(Field<T>& sourceSol) const
template<class Type>
void Foam::LUscalarMatrix::solve(Field<Type>& sourceSol) const
{
if (Pstream::parRun())
{
Field<T> completeSourceSol(n());
Field<Type> completeSourceSol(n());
if (Pstream::master())
{
typename Field<T>::subField
typename Field<Type>::subField
(
completeSourceSol,
sourceSol.size()
@ -58,7 +58,7 @@ void Foam::LUscalarMatrix::solve(Field<T>& sourceSol) const
(
&(completeSourceSol[procOffsets_[slave]])
),
(procOffsets_[slave + 1] - procOffsets_[slave])*sizeof(T)
(procOffsets_[slave + 1] - procOffsets_[slave])*sizeof(Type)
);
}
}
@ -77,7 +77,7 @@ void Foam::LUscalarMatrix::solve(Field<T>& sourceSol) const
{
LUBacksubstitute(*this, pivotIndices_, completeSourceSol);
sourceSol = typename Field<T>::subField
sourceSol = typename Field<Type>::subField
(
completeSourceSol,
sourceSol.size()
@ -98,7 +98,7 @@ void Foam::LUscalarMatrix::solve(Field<T>& sourceSol) const
(
&(completeSourceSol[procOffsets_[slave]])
),
(procOffsets_[slave + 1] - procOffsets_[slave])*sizeof(T)
(procOffsets_[slave + 1] - procOffsets_[slave])*sizeof(Type)
);
}
}

View File

@ -28,13 +28,13 @@ License
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
template<class T>
void Foam::Matrix<T>::allocate()
template<class Type>
void Foam::Matrix<Type>::allocate()
{
if (n_ && m_)
{
v_ = new T*[n_];
v_[0] = new T[n_*m_];
v_ = new Type*[n_];
v_[0] = new Type[n_*m_];
for (register label i=1; i<n_; i++)
{
@ -46,12 +46,12 @@ void Foam::Matrix<T>::allocate()
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
template<class T>
Foam::Matrix<T>::~Matrix()
template<class Type>
Foam::Matrix<Type>::~Matrix()
{
if (v_)
{
delete[] (v_[0]);
delete[] (v_[0]);
delete[] v_;
}
}
@ -59,16 +59,16 @@ Foam::Matrix<T>::~Matrix()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
const Foam::Matrix<T>& Foam::Matrix<T>::null()
template<class Type>
const Foam::Matrix<Type>& Foam::Matrix<Type>::null()
{
Matrix<T>* nullPtr = reinterpret_cast<Matrix<T>*>(NULL);
Matrix<Type>* nullPtr = reinterpret_cast<Matrix<Type>*>(NULL);
return *nullPtr;
}
template<class T>
Foam::Matrix<T>::Matrix(const label n, const label m)
template<class Type>
Foam::Matrix<Type>::Matrix(const label n, const label m)
:
n_(n),
m_(m),
@ -76,7 +76,7 @@ Foam::Matrix<T>::Matrix(const label n, const label m)
{
if (n_ < 0 || m_ < 0)
{
FatalErrorIn("Matrix<T>::Matrix(const label n, const label m)")
FatalErrorIn("Matrix<Type>::Matrix(const label n, const label m)")
<< "bad n, m " << n_ << ", " << m_
<< abort(FatalError);
}
@ -85,8 +85,8 @@ Foam::Matrix<T>::Matrix(const label n, const label m)
}
template<class T>
Foam::Matrix<T>::Matrix(const label n, const label m, const T& a)
template<class Type>
Foam::Matrix<Type>::Matrix(const label n, const label m, const Type& a)
:
n_(n),
m_(m),
@ -96,7 +96,7 @@ Foam::Matrix<T>::Matrix(const label n, const label m, const T& a)
{
FatalErrorIn
(
"Matrix<T>::Matrix(const label n, const label m, const T&)"
"Matrix<Type>::Matrix(const label n, const label m, const T&)"
) << "bad n, m " << n_ << ", " << m_
<< abort(FatalError);
}
@ -105,7 +105,7 @@ Foam::Matrix<T>::Matrix(const label n, const label m, const T& a)
if (v_)
{
T* v = v_[0];
Type* v = v_[0];
label nm = n_*m_;
@ -117,8 +117,8 @@ Foam::Matrix<T>::Matrix(const label n, const label m, const T& a)
}
template<class T>
Foam::Matrix<T>::Matrix(const Matrix<T>& a)
template<class Type>
Foam::Matrix<Type>::Matrix(const Matrix<Type>& a)
:
n_(a.n_),
m_(a.m_),
@ -127,8 +127,8 @@ Foam::Matrix<T>::Matrix(const Matrix<T>& a)
if (a.v_)
{
allocate();
T* v = v_[0];
const T* av = a.v_[0];
Type* v = v_[0];
const Type* av = a.v_[0];
label nm = n_*m_;
for (register label i=0; i<nm; i++)
@ -138,13 +138,13 @@ Foam::Matrix<T>::Matrix(const Matrix<T>& a)
}
}
template<class T>
void Foam::Matrix<T>::clear()
template<class Type>
void Foam::Matrix<Type>::clear()
{
if (v_)
{
delete[] (v_[0]);
delete[] (v_[0]);
delete[] v_;
}
n_ = 0;
@ -153,8 +153,8 @@ void Foam::Matrix<T>::clear()
}
template<class T>
void Foam::Matrix<T>::transfer(Matrix<T>& a)
template<class Type>
void Foam::Matrix<Type>::transfer(Matrix<Type>& a)
{
clear();
@ -171,12 +171,30 @@ void Foam::Matrix<T>::transfer(Matrix<T>& a)
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T>
void Foam::Matrix<T>::operator=(const T& t)
template<class Type>
Foam::Matrix<Type> Foam::Matrix<Type>::T() const
{
const Matrix<Type>& A = *this;
Matrix<Type> At(m(), n());
for (register label i=0; i<n(); i++)
{
for (register label j=0; j<m(); j++)
{
At[j][i] = A[i][j];
}
}
return At;
}
template<class Type>
void Foam::Matrix<Type>::operator=(const Type& t)
{
if (v_)
{
T* v = v_[0];
Type* v = v_[0];
label nm = n_*m_;
for (register label i=0; i<nm; i++)
@ -188,12 +206,12 @@ void Foam::Matrix<T>::operator=(const T& t)
// Assignment operator. Takes linear time.
template<class T>
void Foam::Matrix<T>::operator=(const Matrix<T>& a)
template<class Type>
void Foam::Matrix<Type>::operator=(const Matrix<Type>& a)
{
if (this == &a)
{
FatalErrorIn("Matrix<T>::operator=(const Matrix<T>&)")
FatalErrorIn("Matrix<Type>::operator=(const Matrix<Type>&)")
<< "attempted assignment to self"
<< abort(FatalError);
}
@ -204,12 +222,12 @@ void Foam::Matrix<T>::operator=(const Matrix<T>& a)
n_ = a.n_;
m_ = a.m_;
allocate();
}
}
if (v_)
{
T* v = v_[0];
const T* av = a.v_[0];
Type* v = v_[0];
const Type* av = a.v_[0];
label nm = n_*m_;
for (register label i=0; i<nm; i++)
@ -222,15 +240,15 @@ void Foam::Matrix<T>::operator=(const Matrix<T>& a)
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class T>
const T& Foam::max(const Matrix<T>& a)
template<class Type>
const Type& Foam::max(const Matrix<Type>& a)
{
label nm = a.n_*a.m_;
if (nm)
{
label curMaxI = 0;
const T* v = a.v_[0];
const Type* v = a.v_[0];
for (register label i=1; i<nm; i++)
{
@ -244,7 +262,7 @@ const T& Foam::max(const Matrix<T>& a)
}
else
{
FatalErrorIn("max(const Matrix<T>&)")
FatalErrorIn("max(const Matrix<Type>&)")
<< "matrix is empty"
<< abort(FatalError);
@ -254,15 +272,15 @@ const T& Foam::max(const Matrix<T>& a)
}
template<class T>
const T& Foam::min(const Matrix<T>& a)
template<class Type>
const Type& Foam::min(const Matrix<Type>& a)
{
label nm = a.n_*a.m_;
if (nm)
{
label curMinI = 0;
const T* v = a.v_[0];
const Type* v = a.v_[0];
for (register label i=1; i<nm; i++)
{
@ -276,7 +294,7 @@ const T& Foam::min(const Matrix<T>& a)
}
else
{
FatalErrorIn("min(const Matrix<T>&)")
FatalErrorIn("min(const Matrix<Type>&)")
<< "matrix is empty"
<< abort(FatalError);
@ -288,15 +306,15 @@ const T& Foam::min(const Matrix<T>& a)
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
template<class T>
Foam::Matrix<T> Foam::operator-(const Matrix<T>& a)
template<class Type>
Foam::Matrix<Type> Foam::operator-(const Matrix<Type>& a)
{
Matrix<T> na(a.n_, a.m_);
Matrix<Type> na(a.n_, a.m_);
if (a.n_ && a.m_)
{
T* nav = na.v_[0];
const T* av = a.v_[0];
Type* nav = na.v_[0];
const Type* av = a.v_[0];
label nm = a.n_*a.m_;
for (register label i=0; i<nm; i++)
@ -309,30 +327,34 @@ Foam::Matrix<T> Foam::operator-(const Matrix<T>& a)
}
template<class T>
Foam::Matrix<T> Foam::operator+(const Matrix<T>& a, const Matrix<T>& b)
template<class Type>
Foam::Matrix<Type> Foam::operator+(const Matrix<Type>& a, const Matrix<Type>& b)
{
if (a.n_ != b.n_)
{
FatalErrorIn("Matrix<T>::operator+(const Matrix<T>&, const Matrix<T>&)")
<< "attempted add matrices with different number of rows: "
FatalErrorIn
(
"Matrix<Type>::operator+(const Matrix<Type>&, const Matrix<Type>&)"
) << "attempted add matrices with different number of rows: "
<< a.n_ << ", " << b.n_
<< abort(FatalError);
}
if (a.m_ != b.m_)
{
FatalErrorIn("Matrix<T>::operator+(const Matrix<T>&, const Matrix<T>&)")
<< "attempted add matrices with different number of columns: "
FatalErrorIn
(
"Matrix<Type>::operator+(const Matrix<Type>&, const Matrix<Type>&)"
) << "attempted add matrices with different number of columns: "
<< a.m_ << ", " << b.m_
<< abort(FatalError);
}
Matrix<T> ab(a.n_, a.m_);
Matrix<Type> ab(a.n_, a.m_);
T* abv = ab.v_[0];
const T* av = a.v_[0];
const T* bv = b.v_[0];
Type* abv = ab.v_[0];
const Type* av = a.v_[0];
const Type* bv = b.v_[0];
label nm = a.n_*a.m_;;
for (register label i=0; i<nm; i++)
@ -344,30 +366,34 @@ Foam::Matrix<T> Foam::operator+(const Matrix<T>& a, const Matrix<T>& b)
}
template<class T>
Foam::Matrix<T> Foam::operator-(const Matrix<T>& a, const Matrix<T>& b)
template<class Type>
Foam::Matrix<Type> Foam::operator-(const Matrix<Type>& a, const Matrix<Type>& b)
{
if (a.n_ != b.n_)
{
FatalErrorIn("Matrix<T>::operator-(const Matrix<T>&, const Matrix<T>&)")
<< "attempted add matrices with different number of rows: "
FatalErrorIn
(
"Matrix<Type>::operator-(const Matrix<Type>&, const Matrix<Type>&)"
) << "attempted add matrices with different number of rows: "
<< a.n_ << ", " << b.n_
<< abort(FatalError);
}
if (a.m_ != b.m_)
{
FatalErrorIn("Matrix<T>::operator-(const Matrix<T>&, const Matrix<T>&)")
<< "attempted add matrices with different number of columns: "
FatalErrorIn
(
"Matrix<Type>::operator-(const Matrix<Type>&, const Matrix<Type>&)"
) << "attempted add matrices with different number of columns: "
<< a.m_ << ", " << b.m_
<< abort(FatalError);
}
Matrix<T> ab(a.n_, a.m_);
Matrix<Type> ab(a.n_, a.m_);
T* abv = ab.v_[0];
const T* av = a.v_[0];
const T* bv = b.v_[0];
Type* abv = ab.v_[0];
const Type* av = a.v_[0];
const Type* bv = b.v_[0];
label nm = a.n_*a.m_;;
for (register label i=0; i<nm; i++)
@ -379,15 +405,15 @@ Foam::Matrix<T> Foam::operator-(const Matrix<T>& a, const Matrix<T>& b)
}
template<class T>
Foam::Matrix<T> Foam::operator*(const scalar s, const Matrix<T>& a)
template<class Type>
Foam::Matrix<Type> Foam::operator*(const scalar s, const Matrix<Type>& a)
{
Matrix<T> sa(a.n_, a.m_);
Matrix<Type> sa(a.n_, a.m_);
if (a.n_ && a.m_)
{
T* sav = sa.v_[0];
const T* av = a.v_[0];
Type* sav = sa.v_[0];
const Type* av = a.v_[0];
label nm = a.n_*a.m_;;
for (register label i=0; i<nm; i++)

View File

@ -51,25 +51,37 @@ namespace Foam
// Forward declaration of friend functions and operators
template<class T> class Matrix;
template<class Type> class Matrix;
template<class T> const T& max(const Matrix<T>&);
template<class T> const T& min(const Matrix<T>&);
template<class Type> const Type& max(const Matrix<Type>&);
template<class Type> const Type& min(const Matrix<Type>&);
template<class T> Matrix<T> operator-(const Matrix<T>&);
template<class T> Matrix<T> operator+(const Matrix<T>&, const Matrix<T>&);
template<class T> Matrix<T> operator-(const Matrix<T>&, const Matrix<T>&);
template<class T> Matrix<T> operator*(const scalar, const Matrix<T>&);
template<class Type> Matrix<Type> operator-(const Matrix<Type>&);
template<class Type> Matrix<Type> operator+
(
const Matrix<Type>&,
const Matrix<Type>&
);
template<class Type> Matrix<Type> operator-
(
const Matrix<Type>&,
const Matrix<Type>&
);
template<class Type> Matrix<Type> operator*
(
const scalar,
const Matrix<Type>&
);
template<class T> Istream& operator>>(Istream&, Matrix<T>&);
template<class T> Ostream& operator<<(Ostream&, const Matrix<T>&);
template<class Type> Istream& operator>>(Istream&, Matrix<Type>&);
template<class Type> Ostream& operator<<(Ostream&, const Matrix<Type>&);
/*---------------------------------------------------------------------------*\
Class Matrix Declaration
\*---------------------------------------------------------------------------*/
template<class T>
template<class Type>
class Matrix
{
// Private data
@ -78,7 +90,7 @@ class Matrix
label n_, m_;
//- Row pointers
T** __restrict__ v_;
Type** __restrict__ v_;
//- Allocate the storage for the row-pointers and the data
// and set the row pointers
@ -97,16 +109,16 @@ public:
//- Construct with given number of rows and columns
// and value for all elements.
Matrix(const label n, const label m, const T&);
Matrix(const label n, const label m, const Type&);
//- Copy constructor.
Matrix(const Matrix<T>&);
Matrix(const Matrix<Type>&);
//- Construct from Istream.
Matrix(Istream&);
//- Clone
inline autoPtr<Matrix<T> > clone() const;
inline autoPtr<Matrix<Type> > clone() const;
// Destructor
@ -117,7 +129,7 @@ public:
// Member functions
//- Return a null Matrix
static const Matrix<T>& null();
static const Matrix<Type>& null();
// Access
@ -148,45 +160,60 @@ public:
//- Transfer the contents of the argument Matrix into this Matrix
// and annull the argument Matrix.
void transfer(Matrix<T>&);
void transfer(Matrix<Type>&);
// Member operators
//- Return subscript-checked element of Matrix.
inline T* operator[](const label);
inline Type* operator[](const label);
//- Return subscript-checked element of constant Matrix.
inline const T* operator[](const label) const;
inline const Type* operator[](const label) const;
//- Return the transpose of the matrix
Matrix<Type> T() const;
//- Assignment operator. Takes linear time.
void operator=(const Matrix<T>&);
void operator=(const Matrix<Type>&);
//- Assignment of all entries to the given value
void operator=(const T&);
void operator=(const Type&);
// Friend functions
friend const T& max<T>(const Matrix<T>&);
friend const T& min<T>(const Matrix<T>&);
friend const Type& max<Type>(const Matrix<Type>&);
friend const Type& min<Type>(const Matrix<Type>&);
// Friend operators
friend Matrix<T> operator-<T>(const Matrix<T>&);
friend Matrix<T> operator+<T>(const Matrix<T>&, const Matrix<T>&);
friend Matrix<T> operator-<T>(const Matrix<T>&, const Matrix<T>&);
friend Matrix<T> operator*<T>(const scalar, const Matrix<T>&);
friend Matrix<Type> operator-<Type>(const Matrix<Type>&);
friend Matrix<Type> operator+<Type>
(
const Matrix<Type>&,
const Matrix<Type>&
);
friend Matrix<Type> operator-<Type>
(
const Matrix<Type>&,
const Matrix<Type>&
);
friend Matrix<Type> operator*<Type>
(
const scalar,
const Matrix<Type>&
);
// IOstream operators
//- Read Matrix from Istream, discarding contents of existing Matrix.
friend Istream& operator>> <T>(Istream&, Matrix<T>&);
friend Istream& operator>> <Type>(Istream&, Matrix<Type>&);
// Write Matrix to Ostream.
friend Ostream& operator<< <T>(Ostream&, const Matrix<T>&);
friend Ostream& operator<< <Type>(Ostream&, const Matrix<Type>&);
};

View File

@ -26,8 +26,8 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T>
inline Foam::Matrix<T>::Matrix()
template<class Type>
inline Foam::Matrix<Type>::Matrix()
:
n_(0),
m_(0),
@ -35,71 +35,67 @@ inline Foam::Matrix<T>::Matrix()
{}
template<class T>
inline Foam::autoPtr<Foam::Matrix<T> > Foam::Matrix<T>::clone() const
template<class Type>
inline Foam::autoPtr<Foam::Matrix<Type> > Foam::Matrix<Type>::clone() const
{
return autoPtr<Matrix<T> >(new Matrix<T>(*this));
return autoPtr<Matrix<Type> >(new Matrix<Type>(*this));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
//- Return the number of rows
template<class T>
inline Foam::label Foam::Matrix<T>::n() const
template<class Type>
inline Foam::label Foam::Matrix<Type>::n() const
{
return n_;
}
//- Return the number of columns
template<class T>
inline Foam::label Foam::Matrix<T>::m() const
template<class Type>
inline Foam::label Foam::Matrix<Type>::m() const
{
return m_;
}
//- Return the number of columns
template<class T>
inline Foam::label Foam::Matrix<T>::size() const
template<class Type>
inline Foam::label Foam::Matrix<Type>::size() const
{
return n_*m_;
}
// Check index i is within valid range (0 ... n-1).
template<class T>
inline void Foam::Matrix<T>::checki(const label i) const
template<class Type>
inline void Foam::Matrix<Type>::checki(const label i) const
{
if (!n_)
{
FatalErrorIn("Matrix<T>::checki(const label)")
FatalErrorIn("Matrix<Type>::checki(const label)")
<< "attempt to access element from zero sized row"
<< abort(FatalError);
}
else if (i<0 || i>=n_)
{
FatalErrorIn("Matrix<T>::checki(const label)")
FatalErrorIn("Matrix<Type>::checki(const label)")
<< "index " << i << " out of range 0 ... " << n_-1
<< abort(FatalError);
}
}
// Check index j is within valid range (0 ... n-1).
template<class T>
inline void Foam::Matrix<T>::checkj(const label j) const
template<class Type>
inline void Foam::Matrix<Type>::checkj(const label j) const
{
if (!m_)
{
FatalErrorIn("Matrix<T>::checkj(const label)")
FatalErrorIn("Matrix<Type>::checkj(const label)")
<< "attempt to access element from zero sized column"
<< abort(FatalError);
}
else if (j<0 || j>=m_)
{
FatalErrorIn("Matrix<T>::checkj(const label)")
FatalErrorIn("Matrix<Type>::checkj(const label)")
<< "index " << j << " out of range 0 ... " << m_-1
<< abort(FatalError);
}
@ -108,9 +104,8 @@ inline void Foam::Matrix<T>::checkj(const label j) const
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
// Return subscript-checked element access
template<class T>
inline T* Foam::Matrix<T>::operator[](const label i)
template<class Type>
inline Type* Foam::Matrix<Type>::operator[](const label i)
{
# ifdef FULLDEBUG
checki(i);
@ -119,9 +114,8 @@ inline T* Foam::Matrix<T>::operator[](const label i)
}
// Return subscript-checked const element access
template<class T>
inline const T* Foam::Matrix<T>::operator[](const label i) const
template<class Type>
inline const Type* Foam::Matrix<Type>::operator[](const label i) const
{
# ifdef FULLDEBUG
checki(i);

View File

@ -32,8 +32,8 @@ License
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class T>
Foam::Matrix<T>::Matrix(Istream& is)
template<class Type>
Foam::Matrix<Type>::Matrix(Istream& is)
:
n_(0),
m_(0),
@ -43,17 +43,17 @@ Foam::Matrix<T>::Matrix(Istream& is)
}
template<class T>
Foam::Istream& Foam::operator>>(Istream& is, Matrix<T>& M)
template<class Type>
Foam::Istream& Foam::operator>>(Istream& is, Matrix<Type>& M)
{
// Anull matrix
M.clear();
is.fatalCheck("operator>>(Istream&, Matrix<T>&)");
is.fatalCheck("operator>>(Istream&, Matrix<Type>&)");
token firstToken(is);
is.fatalCheck("operator>>(Istream&, Matrix<T>&) : reading first token");
is.fatalCheck("operator>>(Istream&, Matrix<Type>&) : reading first token");
if (firstToken.isLabel())
{
@ -63,7 +63,7 @@ Foam::Istream& Foam::operator>>(Istream& is, Matrix<T>& M)
label nm = M.n_*M.m_;
// Read list contents depending on data format
if (is.format() == IOstream::ASCII || !contiguous<T>())
if (is.format() == IOstream::ASCII || !contiguous<Type>())
{
// Read beginning of contents
char listDelimiter = is.readBeginList("Matrix");
@ -71,7 +71,7 @@ Foam::Istream& Foam::operator>>(Istream& is, Matrix<T>& M)
if (nm)
{
M.allocate();
T* v = M.v_[0];
Type* v = M.v_[0];
if (listDelimiter == token::BEGIN_LIST)
{
@ -88,7 +88,7 @@ Foam::Istream& Foam::operator>>(Istream& is, Matrix<T>& M)
is.fatalCheck
(
"operator>>(Istream&, Matrix<T>&) : "
"operator>>(Istream&, Matrix<Type>&) : "
"reading entry"
);
}
@ -98,12 +98,12 @@ Foam::Istream& Foam::operator>>(Istream& is, Matrix<T>& M)
}
else
{
T element;
Type element;
is >> element;
is.fatalCheck
(
"operator>>(Istream&, Matrix<T>&) : "
"operator>>(Istream&, Matrix<Type>&) : "
"reading the single entry"
);
@ -122,13 +122,13 @@ Foam::Istream& Foam::operator>>(Istream& is, Matrix<T>& M)
if (nm)
{
M.allocate();
T* v = M.v_[0];
Type* v = M.v_[0];
is.read(reinterpret_cast<char*>(v), nm*sizeof(T));
is.read(reinterpret_cast<char*>(v), nm*sizeof(Type));
is.fatalCheck
(
"operator>>(Istream&, Matrix<T>&) : "
"operator>>(Istream&, Matrix<Type>&) : "
"reading the binary block"
);
}
@ -136,7 +136,7 @@ Foam::Istream& Foam::operator>>(Istream& is, Matrix<T>& M)
}
else
{
FatalIOErrorIn("operator>>(Istream&, Matrix<T>&)", is)
FatalIOErrorIn("operator>>(Istream&, Matrix<Type>&)", is)
<< "incorrect first token, expected <int>, found "
<< firstToken.info()
<< exit(FatalIOError);
@ -146,23 +146,23 @@ Foam::Istream& Foam::operator>>(Istream& is, Matrix<T>& M)
}
template<class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const Matrix<T>& M)
template<class Type>
Foam::Ostream& Foam::operator<<(Ostream& os, const Matrix<Type>& M)
{
label nm = M.n_*M.m_;
os << M.n() << token::SPACE << M.m();
// Write list contents depending on data format
if (os.format() == IOstream::ASCII || !contiguous<T>())
if (os.format() == IOstream::ASCII || !contiguous<Type>())
{
if (nm)
{
bool uniform = false;
const T* v = M.v_[0];
const Type* v = M.v_[0];
if (nm > 1 && contiguous<T>())
if (nm > 1 && contiguous<Type>())
{
uniform = true;
@ -187,7 +187,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const Matrix<T>& M)
// Write end of contents delimiter
os << token::END_BLOCK;
}
else if (nm < 10 && contiguous<T>())
else if (nm < 10 && contiguous<Type>())
{
// Write size of list and start contents delimiter
os << token::BEGIN_LIST;
@ -246,7 +246,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const Matrix<T>& M)
{
if (nm)
{
os.write(reinterpret_cast<const char*>(M.v_[0]), nm*sizeof(T));
os.write(reinterpret_cast<const char*>(M.v_[0]), nm*sizeof(Type));
}
}

View File

@ -0,0 +1,400 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2005 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "SVD.H"
#include "scalarList.H"
#include "scalarMatrix.H"
#include "ListOps.H"
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * //
Foam::SVD::SVD(const Matrix<scalar>& A, const scalar minCondition)
:
U_(A),
V_(A.m(), A.m()),
S_(A.m()),
VSinvUt_(A.m(), A.n()),
nZeros_(0)
{
// SVDcomp to find U_, V_ and S_ - the singular values
const label Um = U_.m();
const label Un = U_.n();
scalarList rv1(Um);
scalar g = 0;
scalar scale = 0;
scalar s = 0;
scalar anorm = 0;
label l = 0;
for (label i = 0; i < Um; i++)
{
l = i+2;
rv1[i] = scale*g;
g = s = scale = 0;
if (i < Un)
{
for (label k = i; k < Un; k++)
{
scale += mag(U_[k][i]);
}
if (scale != 0)
{
for (label k = i; k < Un; k++)
{
U_[k][i] /= scale;
s += U_[k][i]*U_[k][i];
}
scalar f = U_[i][i];
g = -sign(Foam::sqrt(s), f);
scalar h = f*g - s;
U_[i][i] = f - g;
for (label j = l-1; j < Um; j++)
{
s = 0;
for (label k = i; k < Un; k++)
{
s += U_[k][i]*U_[k][j];
}
f = s/h;
for (label k = i; k < A.n(); k++)
{
U_[k][j] += f*U_[k][i];
}
}
for (label k = i; k < Un; k++)
{
U_[k][i] *= scale;
}
}
}
S_[i] = scale*g;
g = s = scale = 0;
if (i+1 <= Un && i != Um)
{
for (label k = l-1; k < Um; k++)
{
scale += mag(U_[i][k]);
}
if (scale != 0)
{
for (label k=l-1; k < Um; k++)
{
U_[i][k] /= scale;
s += U_[i][k]*U_[i][k];
}
scalar f = U_[i][l-1];
g = -sign(Foam::sqrt(s),f);
scalar h = f*g - s;
U_[i][l-1] = f - g;
for (label k = l-1; k < Um; k++)
{
rv1[k] = U_[i][k]/h;
}
for (label j = l-1; j < Un; j++)
{
s = 0;
for (label k = l-1; k < Um; k++)
{
s += U_[j][k]*U_[i][k];
}
for (label k = l-1; k < Um; k++)
{
U_[j][k] += s*rv1[k];
}
}
for (label k = l-1; k < Um; k++)
{
U_[i][k] *= scale;
}
}
}
anorm = max(anorm, mag(S_[i]) + mag(rv1[i]));
}
for (label i = Um-1; i >= 0; i--)
{
if (i < Um-1)
{
if (g != 0)
{
for (label j = l; j < Um; j++)
{
V_[j][i] = (U_[i][j]/U_[i][l])/g;
}
for (label j=l; j < Um; j++)
{
s = 0;
for (label k = l; k < Um; k++)
{
s += U_[i][k]*V_[k][j];
}
for (label k = l; k < Um; k++)
{
V_[k][j] += s*V_[k][i];
}
}
}
for (label j = l; j < Um;j++)
{
V_[i][j] = V_[j][i] = 0.0;
}
}
V_[i][i] = 1;
g = rv1[i];
l = i;
}
for (label i = min(Um, Un) - 1; i >= 0; i--)
{
l = i+1;
g = S_[i];
for (label j = l; j < Um; j++)
{
U_[i][j] = 0.0;
}
if (g != 0)
{
g = 1.0/g;
for (label j = l; j < Um; j++)
{
s = 0;
for (label k = l; k < Un; k++)
{
s += U_[k][i]*U_[k][j];
}
scalar f = (s/U_[i][i])*g;
for (label k = i; k < Un; k++)
{
U_[k][j] += f*U_[k][i];
}
}
for (label j = i; j < Un; j++)
{
U_[j][i] *= g;
}
}
else
{
for (label j = i; j < Un; j++)
{
U_[j][i] = 0.0;
}
}
++U_[i][i];
}
for (label k = Um-1; k >= 0; k--)
{
for (label its = 0; its < 35; its++)
{
bool flag = true;
label nm;
for (l = k; l >= 0; l--)
{
nm = l-1;
if (mag(rv1[l]) + anorm == anorm)
{
flag = false;
break;
}
if (mag(S_[nm]) + anorm == anorm) break;
}
if (flag)
{
scalar c = 0.0;
s = 1.0;
for (label i = l-1; i < k+1; i++)
{
scalar f = s*rv1[i];
rv1[i] = c*rv1[i];
if (mag(f) + anorm == anorm) break;
g = S_[i];
scalar h = sqrtSumSqr(f, g);
S_[i] = h;
h = 1.0/h;
c = g*h;
s = -f*h;
for (label j = 0; j < Un; j++)
{
scalar y = U_[j][nm];
scalar z = U_[j][i];
U_[j][nm] = y*c + z*s;
U_[j][i] = z*c - y*s;
}
}
}
scalar z = S_[k];
if (l == k)
{
if (z < 0.0)
{
S_[k] = -z;
for (label j = 0; j < Um; j++) V_[j][k] = -V_[j][k];
}
break;
}
if (its == 34)
{
WarningIn("SVD::SVD(Matrix<scalar>& A)")
<< "no convergence in 35 SVD iterations"
<< endl;
}
scalar x = S_[l];
nm = k-1;
scalar y = S_[nm];
g = rv1[nm];
scalar h = rv1[k];
scalar f = ((y - z)*(y + z) + (g - h)*(g + h))/(2.0*h*y);
g = sqrtSumSqr(f, 1.0);
f = ((x - z)*(x + z) + h*((y/(f + sign(g, f))) - h))/x;
scalar c = 1.0;
s = 1.0;
for (label j = l; j <= nm; j++)
{
label i = j + 1;
g = rv1[i];
y = S_[i];
h = s*g;
g = c*g;
scalar z = sqrtSumSqr(f, h);
rv1[j] = z;
c = f/z;
s = h/z;
f = x*c + g*s;
g = g*c - x*s;
h = y*s;
y *= c;
for (label jj = 0; jj < Um; jj++)
{
x = V_[jj][j];
z = V_[jj][i];
V_[jj][j] = x*c + z*s;
V_[jj][i] = z*c - x*s;
}
z = sqrtSumSqr(f, h);
S_[j] = z;
if (z)
{
z = 1.0/z;
c = f*z;
s = h*z;
}
f = c*g + s*y;
x = c*y - s*g;
for (label jj=0; jj < Un; jj++)
{
y = U_[jj][j];
z = U_[jj][i];
U_[jj][j] = y*c + z*s;
U_[jj][i] = z*c - y*s;
}
}
rv1[l] = 0.0;
rv1[k] = f;
S_[k] = x;
}
}
// zero singular values that are less than minCondition*maxS
const scalar minS = minCondition*S_[findMax(S_)];
for (label i = 0; i < S_.size(); i++)
{
if (S_[i] <= minS)
{
//Info << "Removing " << S_[i] << " < " << minS << endl;
S_[i] = 0;
nZeros_++;
}
}
// now multiply out to find the pseudo inverse of A, VSinvUt_
multiply(VSinvUt_, V_, inv(S_), U_.T());
// test SVD
/*Matrix<scalar> SVDA(A.n(), A.m());
multiply(SVDA, U_, S_, transpose(V_));
scalar maxDiff = 0;
scalar diff = 0;
for(label i = 0; i < A.n(); i++)
{
for(label j = 0; j < A.m(); j++)
{
diff = mag(A[i][j] - SVDA[i][j]);
if (diff > maxDiff) maxDiff = diff;
}
}
Info << "Maximum discrepancy between A and svd(A) = " << maxDiff << endl;
if (maxDiff > 4)
{
Info << "singular values " << S_ << endl;
}
*/
}
// ************************************************************************* //

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2005 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
SVD
Description
Singular value decomposition of a rectangular matrix.
SourceFiles
SVD.C
\*---------------------------------------------------------------------------*/
#ifndef SVD_H
#define SVD_H
#include "DiagonalMatrix.H"
#include "Matrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
/*---------------------------------------------------------------------------*\
Class SVD Declaration
\*---------------------------------------------------------------------------*/
class SVD
{
// Private data
//- Rectangular matrix with the same dimensions as the input
Matrix<scalar> U_;
//- square matrix V
Matrix<scalar> V_;
//- The singular values
DiagonalMatrix<scalar> S_;
//- The matrix product V S^(-1) U^T
Matrix<scalar> VSinvUt_;
//- The number of zero singular values
label nZeros_;
// Private Member Functions
//- Disallow default bitwise copy construct
SVD(const SVD&);
//- Disallow default bitwise assignment
void operator=(const SVD&);
template<class T>
inline const T sign(const T& a, const T& b);
public:
// Constructors
//- Construct from a rectangular Matrix
SVD(const Matrix<scalar>& A, const scalar minCondition = 0);
// Access functions
//- Return U
inline const Matrix<scalar>& U() const;
//- Return the square matrix V
inline const Matrix<scalar>& V() const;
//- Return the singular values
inline const DiagonalMatrix<scalar>& S() const;
//- Return VSinvUt (the pseudo inverse)
inline const Matrix<scalar>& VSinvUt() const;
//- Return the number of zero singular values
inline label nZeros() const;
//- Return the minimum non-zero singular value
inline scalar minNonZeroS() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "SVDI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
template<class T>
inline const T Foam::SVD::sign(const T& a, const T& b)
{
return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::Matrix<Foam::scalar>& Foam::SVD::U() const
{
return U_;
}
inline const Foam::Matrix<Foam::scalar>& Foam::SVD::V() const
{
return V_;
}
inline const Foam::DiagonalMatrix<Foam::scalar>& Foam::SVD::S() const
{
return S_;
}
inline const Foam::Matrix<Foam::scalar>& Foam::SVD::VSinvUt() const
{
return VSinvUt_;
}
inline Foam::label Foam::SVD::nZeros() const
{
return nZeros_;
}
inline Foam::scalar Foam::SVD::minNonZeroS() const
{
scalar minS = S_[0];
for(label i = 1; i < S_.size(); i++)
{
scalar s = S_[i];
if (s > VSMALL && s < minS) minS = s;
}
return minS;
}
// ************************************************************************* //

View File

@ -25,6 +25,8 @@ License
\*---------------------------------------------------------------------------*/
#include "scalarMatrix.H"
#include "SVD.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -136,7 +138,7 @@ void Foam::scalarMatrix::LUDecompose
{
Swap(matrixj[k], matrixiMax[k]);
}
vv[iMax] = vv[j];
}
@ -158,4 +160,159 @@ void Foam::scalarMatrix::LUDecompose
}
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
void Foam::multiply
(
Matrix<scalar>& ans, // value changed in return
const Matrix<scalar>& A,
const Matrix<scalar>& B
)
{
if (A.m() != B.n())
{
FatalErrorIn
(
"multiply("
"Matrix<scalar>& answer "
"const Matrix<scalar>& A, "
"const Matrix<scalar>& B)"
) << "A and B must have identical inner dimensions but A.m = "
<< A.m() << " and B.n = " << B.n()
<< abort(FatalError);
}
ans = Matrix<scalar>(A.n(), B.m(), scalar(0));
for(register label i = 0; i < A.n(); i++)
{
for(register label j = 0; j < B.m(); j++)
{
for(register label l = 0; l < B.n(); l++)
{
ans[i][j] += A[i][l]*B[l][j];
}
}
}
}
void Foam::multiply
(
Matrix<scalar>& ans, // value changed in return
const Matrix<scalar>& A,
const Matrix<scalar>& B,
const Matrix<scalar>& C
)
{
if (A.m() != B.n())
{
FatalErrorIn
(
"multiply("
"const Matrix<scalar>& A, "
"const Matrix<scalar>& B, "
"const Matrix<scalar>& C, "
"Matrix<scalar>& answer)"
) << "A and B must have identical inner dimensions but A.m = "
<< A.m() << " and B.n = " << B.n()
<< abort(FatalError);
}
if (B.m() != C.n())
{
FatalErrorIn
(
"multiply("
"const Matrix<scalar>& A, "
"const Matrix<scalar>& B, "
"const Matrix<scalar>& C, "
"Matrix<scalar>& answer)"
) << "B and C must have identical inner dimensions but B.m = "
<< B.m() << " and C.n = " << C.n()
<< abort(FatalError);
}
ans = Matrix<scalar>(A.n(), C.m(), scalar(0));
for(register label i = 0; i < A.n(); i++)
{
for(register label g = 0; g < C.m(); g++)
{
for(register label l = 0; l < C.n(); l++)
{
scalar ab = 0;
for(register label j = 0; j < A.m(); j++)
{
ab += A[i][j]*B[j][l];
}
ans[i][g] += C[l][g] * ab;
}
}
}
}
void Foam::multiply
(
Matrix<scalar>& ans, // value changed in return
const Matrix<scalar>& A,
const DiagonalMatrix<scalar>& B,
const Matrix<scalar>& C
)
{
if (A.m() != B.size())
{
FatalErrorIn
(
"multiply("
"const Matrix<scalar>& A, "
"const DiagonalMatrix<scalar>& B, "
"const Matrix<scalar>& C, "
"Matrix<scalar>& answer)"
) << "A and B must have identical inner dimensions but A.m = "
<< A.m() << " and B.n = " << B.size()
<< abort(FatalError);
}
if (B.size() != C.n())
{
FatalErrorIn
(
"multiply("
"const Matrix<scalar>& A, "
"const DiagonalMatrix<scalar>& B, "
"const Matrix<scalar>& C, "
"Matrix<scalar>& answer)"
) << "B and C must have identical inner dimensions but B.m = "
<< B.size() << " and C.n = " << C.n()
<< abort(FatalError);
}
ans = Matrix<scalar>(A.n(), C.m(), scalar(0));
for(register label i = 0; i < A.n(); i++)
{
for(register label g = 0; g < C.m(); g++)
{
for(register label l = 0; l < C.n(); l++)
{
ans[i][g] += C[l][g] * A[i][l]*B[l];
}
}
}
}
Foam::Matrix<Foam::scalar> Foam::SVDinv
(
const Matrix<scalar>& A,
scalar minCondition
)
{
SVD svd(A, minCondition);
return svd.VSinvUt();
}
// ************************************************************************* //

View File

@ -37,6 +37,7 @@ SourceFiles
#define scalarMatrix_H
#include "Matrix.H"
#include "DiagonalMatrix.H"
#include "scalarField.H"
#include "labelList.H"
@ -75,13 +76,13 @@ public:
//- Solve the matrix using Gaussian elimination with pivoting,
// returning the solution in the source
template<class T>
static void solve(Matrix<scalar>& matrix, Field<T>& source);
template<class Type>
static void solve(Matrix<scalar>& matrix, Field<Type>& source);
//- Solve the matrix using Gaussian elimination with pivoting
// and return the solution
template<class T>
void solve(Field<T>& psi, const Field<T>& source) const;
template<class Type>
void solve(Field<Type>& psi, const Field<Type>& source) const;
//- LU decompose the matrix with pivoting
@ -93,21 +94,50 @@ public:
//- LU back-substitution with given source, returning the solution
// in the source
template<class T>
template<class Type>
static void LUBacksubstitute
(
const Matrix<scalar>& luMmatrix,
const labelList& pivotIndices,
Field<T>& source
Field<Type>& source
);
//- Solve the matrix using LU decomposition with pivoting
// returning the LU form of the matrix and the solution in the source
template<class T>
static void LUsolve(Matrix<scalar>& matrix, Field<T>& source);
template<class Type>
static void LUsolve(Matrix<scalar>& matrix, Field<Type>& source);
};
// Global functions
void multiply
(
Matrix<scalar>& answer, // value changed in return
const Matrix<scalar>& A,
const Matrix<scalar>& B
);
void multiply
(
Matrix<scalar>& answer, // value changed in return
const Matrix<scalar>& A,
const Matrix<scalar>& B,
const Matrix<scalar>& C
);
void multiply
(
Matrix<scalar>& answer, // value changed in return
const Matrix<scalar>& A,
const DiagonalMatrix<scalar>& B,
const Matrix<scalar>& C
);
//- Return the inverse of matrix A using SVD
Matrix<scalar> SVDinv(const Matrix<scalar>& A, scalar minCondition = 0);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -29,11 +29,11 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
template<class Type>
void Foam::scalarMatrix::solve
(
Matrix<scalar>& tmpMatrix,
Field<T>& sourceSol
Field<Type>& sourceSol
)
{
label n = tmpMatrix.n();
@ -89,7 +89,7 @@ void Foam::scalarMatrix::solve
// Back-substitution
for (register label j=n-1; j>=0; j--)
{
T ntempvec = pTraits<T>::zero;
Type ntempvec = pTraits<Type>::zero;
for (register label k=j+1; k<n; k++)
{
@ -101,8 +101,8 @@ void Foam::scalarMatrix::solve
}
template<class T>
void Foam::scalarMatrix::solve(Field<T>& psi, const Field<T>& source) const
template<class Type>
void Foam::scalarMatrix::solve(Field<Type>& psi, const Field<Type>& source) const
{
Matrix<scalar> tmpMatrix = *this;
psi = source;
@ -110,12 +110,12 @@ void Foam::scalarMatrix::solve(Field<T>& psi, const Field<T>& source) const
}
template<class T>
template<class Type>
void Foam::scalarMatrix::LUBacksubstitute
(
const Matrix<scalar>& luMatrix,
const labelList& pivotIndices,
Field<T>& sourceSol
Field<Type>& sourceSol
)
{
label n = luMatrix.n();
@ -125,7 +125,7 @@ void Foam::scalarMatrix::LUBacksubstitute
for (register label i=0; i<n; i++)
{
label ip = pivotIndices[i];
T sum = sourceSol[ip];
Type sum = sourceSol[ip];
sourceSol[ip] = sourceSol[i];
const scalar* __restrict__ luMatrixi = luMatrix[i];
@ -136,7 +136,7 @@ void Foam::scalarMatrix::LUBacksubstitute
sum -= luMatrixi[j]*sourceSol[j];
}
}
else if (sum != pTraits<T>::zero)
else if (sum != pTraits<Type>::zero)
{
ii = i+1;
}
@ -146,11 +146,11 @@ void Foam::scalarMatrix::LUBacksubstitute
for (register label i=n-1; i>=0; i--)
{
T sum = sourceSol[i];
Type sum = sourceSol[i];
const scalar* __restrict__ luMatrixi = luMatrix[i];
for (register label j=i+1; j<n; j++)
{
{
sum -= luMatrixi[j]*sourceSol[j];
}
@ -159,11 +159,11 @@ void Foam::scalarMatrix::LUBacksubstitute
}
template<class T>
template<class Type>
void Foam::scalarMatrix::LUsolve
(
Matrix<scalar>& matrix,
Field<T>& sourceSol
Field<Type>& sourceSol
)
{
labelList pivotIndices(matrix.n());

View File

@ -28,19 +28,19 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T>
Foam::simpleMatrix<T>::simpleMatrix(const label mSize)
template<class Type>
Foam::simpleMatrix<Type>::simpleMatrix(const label mSize)
:
scalarMatrix(mSize),
source_(mSize, pTraits<T>::zero)
source_(mSize, pTraits<Type>::zero)
{}
template<class T>
Foam::simpleMatrix<T>::simpleMatrix
template<class Type>
Foam::simpleMatrix<Type>::simpleMatrix
(
const scalarMatrix& matrix,
const Field<T>& source
const Field<Type>& source
)
:
scalarMatrix(matrix),
@ -48,8 +48,8 @@ Foam::simpleMatrix<T>::simpleMatrix
{}
template<class T>
Foam::simpleMatrix<T>::simpleMatrix(Istream& is)
template<class Type>
Foam::simpleMatrix<Type>::simpleMatrix(Istream& is)
:
scalarMatrix(is),
source_(is)
@ -58,11 +58,11 @@ Foam::simpleMatrix<T>::simpleMatrix(Istream& is)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
Foam::Field<T> Foam::simpleMatrix<T>::solve() const
template<class Type>
Foam::Field<Type> Foam::simpleMatrix<Type>::solve() const
{
scalarMatrix tmpMatrix = *this;
Field<T> sourceSol = source_;
Field<Type> sourceSol = source_;
scalarMatrix::solve(tmpMatrix, sourceSol);
@ -70,11 +70,11 @@ Foam::Field<T> Foam::simpleMatrix<T>::solve() const
}
template<class T>
Foam::Field<T> Foam::simpleMatrix<T>::LUsolve() const
template<class Type>
Foam::Field<Type> Foam::simpleMatrix<Type>::LUsolve() const
{
scalarMatrix luMatrix = *this;
Field<T> sourceSol = source_;
Field<Type> sourceSol = source_;
scalarMatrix::LUsolve(luMatrix, sourceSol);
@ -84,26 +84,26 @@ Foam::Field<T> Foam::simpleMatrix<T>::LUsolve() const
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T>
void Foam::simpleMatrix<T>::operator=(const simpleMatrix<T>& m)
template<class Type>
void Foam::simpleMatrix<Type>::operator=(const simpleMatrix<Type>& m)
{
if (this == &m)
{
FatalErrorIn("simpleMatrix<T>::operator=(const simpleMatrix<T>&)")
FatalErrorIn("simpleMatrix<Type>::operator=(const simpleMatrix<Type>&)")
<< "Attempted assignment to self"
<< abort(FatalError);
}
if (n() != m.n())
{
FatalErrorIn("simpleMatrix<T>::operator=(const simpleMatrix<T>&)")
FatalErrorIn("simpleMatrix<Type>::operator=(const simpleMatrix<Type>&)")
<< "Different size matrices"
<< abort(FatalError);
}
if (source_.size() != m.source_.size())
{
FatalErrorIn("simpleMatrix<T>::operator=(const simpleMatrix<T>&)")
FatalErrorIn("simpleMatrix<Type>::operator=(const simpleMatrix<Type>&)")
<< "Different size source vectors"
<< abort(FatalError);
}
@ -115,14 +115,14 @@ void Foam::simpleMatrix<T>::operator=(const simpleMatrix<T>& m)
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class T>
Foam::simpleMatrix<T> Foam::operator+
template<class Type>
Foam::simpleMatrix<Type> Foam::operator+
(
const simpleMatrix<T>& m1,
const simpleMatrix<T>& m2
const simpleMatrix<Type>& m1,
const simpleMatrix<Type>& m2
)
{
return simpleMatrix<T>
return simpleMatrix<Type>
(
static_cast<const scalarMatrix&>(m1)
+ static_cast<const scalarMatrix&>(m2),
@ -131,14 +131,14 @@ Foam::simpleMatrix<T> Foam::operator+
}
template<class T>
Foam::simpleMatrix<T> Foam::operator-
template<class Type>
Foam::simpleMatrix<Type> Foam::operator-
(
const simpleMatrix<T>& m1,
const simpleMatrix<T>& m2
const simpleMatrix<Type>& m1,
const simpleMatrix<Type>& m2
)
{
return simpleMatrix<T>
return simpleMatrix<Type>
(
static_cast<const scalarMatrix&>(m1)
- static_cast<const scalarMatrix&>(m2),
@ -147,17 +147,17 @@ Foam::simpleMatrix<T> Foam::operator-
}
template<class T>
Foam::simpleMatrix<T> Foam::operator*(const scalar s, const simpleMatrix<T>& m)
template<class Type>
Foam::simpleMatrix<Type> Foam::operator*(const scalar s, const simpleMatrix<Type>& m)
{
return simpleMatrix<T>(s*m.matrix_, s*m.source_);
return simpleMatrix<Type>(s*m.matrix_, s*m.source_);
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const simpleMatrix<T>& m)
template<class Type>
Foam::Ostream& Foam::operator<<(Ostream& os, const simpleMatrix<Type>& m)
{
os << static_cast<const scalarMatrix&>(m) << nl << m.source_;
return os;

View File

@ -45,35 +45,35 @@ namespace Foam
// Forward declaration of friend functions and operators
template<class T>
template<class Type>
class simpleMatrix;
template<class T>
simpleMatrix<T> operator+
template<class Type>
simpleMatrix<Type> operator+
(
const simpleMatrix<T>&,
const simpleMatrix<T>&
const simpleMatrix<Type>&,
const simpleMatrix<Type>&
);
template<class T>
simpleMatrix<T> operator-
template<class Type>
simpleMatrix<Type> operator-
(
const simpleMatrix<T>&,
const simpleMatrix<T>&
const simpleMatrix<Type>&,
const simpleMatrix<Type>&
);
template<class T>
simpleMatrix<T> operator*
template<class Type>
simpleMatrix<Type> operator*
(
const scalar,
const simpleMatrix<T>&
const simpleMatrix<Type>&
);
template<class T>
template<class Type>
Ostream& operator<<
(
Ostream&,
const simpleMatrix<T>&
const simpleMatrix<Type>&
);
@ -81,14 +81,14 @@ Ostream& operator<<
Class simpleMatrix Declaration
\*---------------------------------------------------------------------------*/
template<class T>
template<class Type>
class simpleMatrix
:
public scalarMatrix
{
// Private data
Field<T> source_;
Field<Type> source_;
public:
@ -99,25 +99,25 @@ public:
simpleMatrix(const label);
//- Construct from components
simpleMatrix(const scalarMatrix&, const Field<T>&);
simpleMatrix(const scalarMatrix&, const Field<Type>&);
//- Construct from Istream
simpleMatrix(Istream&);
//- Construct as copy
simpleMatrix(const simpleMatrix<T>&);
simpleMatrix(const simpleMatrix<Type>&);
// Member Functions
// Access
Field<T>& source()
Field<Type>& source()
{
return source_;
}
const Field<T>& source() const
const Field<Type>& source() const
{
return source_;
}
@ -125,45 +125,45 @@ public:
//- Solve the matrix using Gaussian elimination with pivoting
// and return the solution
Field<T> solve() const;
Field<Type> solve() const;
//- Solve the matrix using LU decomposition with pivoting
// and return the solution
Field<T> LUsolve() const;
Field<Type> LUsolve() const;
// Member Operators
void operator=(const simpleMatrix<T>&);
void operator=(const simpleMatrix<Type>&);
// Friend Operators
friend simpleMatrix<T> operator+ <T>
friend simpleMatrix<Type> operator+ <Type>
(
const simpleMatrix<T>&,
const simpleMatrix<T>&
const simpleMatrix<Type>&,
const simpleMatrix<Type>&
);
friend simpleMatrix<T> operator- <T>
friend simpleMatrix<Type> operator- <Type>
(
const simpleMatrix<T>&,
const simpleMatrix<T>&
const simpleMatrix<Type>&,
const simpleMatrix<Type>&
);
friend simpleMatrix<T> operator* <T>
friend simpleMatrix<Type> operator* <Type>
(
const scalar,
const simpleMatrix<T>&
const simpleMatrix<Type>&
);
// Ostream Operator
friend Ostream& operator<< <T>
friend Ostream& operator<< <Type>
(
Ostream&,
const simpleMatrix<T>&
const simpleMatrix<Type>&
);
};

View File

@ -38,6 +38,9 @@ fvMeshMapper = fvMesh/fvMeshMapper
$(fvMeshMapper)/fvPatchMapper.C
$(fvMeshMapper)/fvSurfaceMapper.C
extendedStencil = fvMesh/extendedStencil
$(extendedStencil)/extendedStencil.C
fvPatchFields = fields/fvPatchFields
$(fvPatchFields)/fvPatchField/fvPatchFields.C
@ -165,6 +168,8 @@ $(schemes)/harmonic/harmonic.C
$(schemes)/localBlended/localBlended.C
$(schemes)/localMax/localMax.C
$(schemes)/localMin/localMin.C
$(schemes)/quadraticFit/quadraticFit.C
$(schemes)/quadraticFit/quadraticFitData.C
limitedSchemes = $(surfaceInterpolation)/limitedSchemes
$(limitedSchemes)/limitedSurfaceInterpolationScheme/limitedSurfaceInterpolationSchemes.C

View File

@ -0,0 +1,525 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "extendedStencil.H"
#include "globalIndex.H"
#include "syncTools.H"
#include "SortableList.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Calculates per face a list of global cell/face indices.
void Foam::extendedStencil::calcFaceStencils
(
const polyMesh& mesh,
const globalIndex& globalNumbering
)
{
const polyBoundaryMesh& patches = mesh.boundaryMesh();
const label nBnd = mesh.nFaces()-mesh.nInternalFaces();
const labelList& own = mesh.faceOwner();
const labelList& nei = mesh.faceNeighbour();
// Determine neighbouring global cell or boundary face
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
labelList neiGlobal(nBnd);
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
label faceI = pp.start();
if (pp.coupled())
{
// For coupled faces get the cell on the other side
forAll(pp, i)
{
label bFaceI = faceI-mesh.nInternalFaces();
neiGlobal[bFaceI] = globalNumbering.toGlobal(own[faceI]);
faceI++;
}
}
else if (isA<emptyPolyPatch>(pp))
{
forAll(pp, i)
{
label bFaceI = faceI-mesh.nInternalFaces();
neiGlobal[bFaceI] = -1;
faceI++;
}
}
else
{
// For noncoupled faces get the boundary face.
forAll(pp, i)
{
label bFaceI = faceI-mesh.nInternalFaces();
neiGlobal[bFaceI] =
globalNumbering.toGlobal(mesh.nCells()+bFaceI);
faceI++;
}
}
}
syncTools::swapBoundaryFaceList(mesh, neiGlobal, false);
// Determine cellCells in global numbering
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
labelListList globalCellCells(mesh.nCells());
forAll(globalCellCells, cellI)
{
const cell& cFaces = mesh.cells()[cellI];
labelList& cCells = globalCellCells[cellI];
cCells.setSize(cFaces.size());
// Collect neighbouring cells/faces
label nNbr = 0;
forAll(cFaces, i)
{
label faceI = cFaces[i];
if (mesh.isInternalFace(faceI))
{
label nbrCellI = own[faceI];
if (nbrCellI == cellI)
{
nbrCellI = nei[faceI];
}
cCells[nNbr++] = globalNumbering.toGlobal(nbrCellI);
}
else
{
label nbrCellI = neiGlobal[faceI-mesh.nInternalFaces()];
if (nbrCellI != -1)
{
cCells[nNbr++] = nbrCellI;
}
}
}
cCells.setSize(nNbr);
}
// Determine neighbouring global cell Cells
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
labelListList neiGlobalCellCells(nBnd);
for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
{
neiGlobalCellCells[faceI-mesh.nInternalFaces()] =
globalCellCells[own[faceI]];
}
syncTools::swapBoundaryFaceList(mesh, neiGlobalCellCells, false);
// Construct stencil in global numbering
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
stencil_.setSize(mesh.nFaces());
labelHashSet faceStencil;
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
{
faceStencil.clear();
label globalOwn = globalNumbering.toGlobal(own[faceI]);
faceStencil.insert(globalOwn);
const labelList& ownCCells = globalCellCells[own[faceI]];
forAll(ownCCells, i)
{
faceStencil.insert(ownCCells[i]);
}
label globalNei = globalNumbering.toGlobal(nei[faceI]);
faceStencil.insert(globalNei);
const labelList& neiCCells = globalCellCells[nei[faceI]];
forAll(neiCCells, i)
{
faceStencil.insert(neiCCells[i]);
}
// Guarantee owner first, neighbour second.
stencil_[faceI].setSize(faceStencil.size());
label n = 0;
stencil_[faceI][n++] = globalOwn;
stencil_[faceI][n++] = globalNei;
forAllConstIter(labelHashSet, faceStencil, iter)
{
if (iter.key() != globalOwn && iter.key() != globalNei)
{
stencil_[faceI][n++] = iter.key();
}
}
//Pout<< "internalface:" << faceI << " toc:" << faceStencil.toc()
// << " stencil:" << stencil_[faceI] << endl;
}
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
label faceI = pp.start();
if (pp.coupled())
{
forAll(pp, i)
{
faceStencil.clear();
label globalOwn = globalNumbering.toGlobal(own[faceI]);
faceStencil.insert(globalOwn);
const labelList& ownCCells = globalCellCells[own[faceI]];
forAll(ownCCells, i)
{
faceStencil.insert(ownCCells[i]);
}
// Get the coupled cell
label globalNei = neiGlobal[faceI-mesh.nInternalFaces()];
faceStencil.insert(globalNei);
// And the neighbours of the coupled cell
const labelList& neiCCells =
neiGlobalCellCells[faceI-mesh.nInternalFaces()];
forAll(neiCCells, i)
{
faceStencil.insert(neiCCells[i]);
}
// Guarantee owner first, neighbour second.
stencil_[faceI].setSize(faceStencil.size());
label n = 0;
stencil_[faceI][n++] = globalOwn;
stencil_[faceI][n++] = globalNei;
forAllConstIter(labelHashSet, faceStencil, iter)
{
if (iter.key() != globalOwn && iter.key() != globalNei)
{
stencil_[faceI][n++] = iter.key();
}
}
//Pout<< "coupledface:" << faceI
// << " toc:" << faceStencil.toc()
// << " stencil:" << stencil_[faceI] << endl;
faceI++;
}
}
else if (!isA<emptyPolyPatch>(pp))
{
forAll(pp, i)
{
faceStencil.clear();
label globalOwn = globalNumbering.toGlobal(own[faceI]);
faceStencil.insert(globalOwn);
const labelList& ownCCells = globalCellCells[own[faceI]];
forAll(ownCCells, i)
{
faceStencil.insert(ownCCells[i]);
}
// Guarantee owner first, neighbour second.
stencil_[faceI].setSize(faceStencil.size());
label n = 0;
stencil_[faceI][n++] = globalOwn;
forAllConstIter(labelHashSet, faceStencil, iter)
{
if (iter.key() != globalOwn)
{
stencil_[faceI][n++] = iter.key();
}
}
//Pout<< "boundaryface:" << faceI
// << " toc:" << faceStencil.toc()
// << " stencil:" << stencil_[faceI] << endl;
faceI++;
}
}
}
}
// Calculates extended stencil. This is per face
// - owner
// - cellCells of owner
// - neighbour
// - cellCells of neighbour
// It comes in two parts:
// - a map which collects/distributes all necessary data in a compact array
// - the stencil (a labelList per face) which is a set of indices into this
// compact array.
// The compact array is laid out as follows:
// - first data for current processor (Pstream::myProcNo())
// - all cells
// - all boundary faces
// - then per processor
// - all used cells and boundary faces
void Foam::extendedStencil::calcExtendedFaceStencil(const polyMesh& mesh)
{
const label nBnd = mesh.nFaces()-mesh.nInternalFaces();
// Global numbering for cells and boundary faces
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
globalIndex globalNumbering(mesh.nCells()+nBnd);
// Calculate stencil in global cell indices
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calcFaceStencils(mesh, globalNumbering);
// Convert stencil to schedule
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
// We now know what information we need from other processors. This needs
// to be converted into what information I need to send as well
// (mapDistribute)
// 1. Construct per processor compact addressing of the global cells
// needed. The ones from the local processor are not included since
// these are always all needed.
List<Map<label> > globalToProc(Pstream::nProcs());
{
const labelList& procPatchMap = mesh.globalData().procPatchMap();
const polyBoundaryMesh& patches = mesh.boundaryMesh();
// Presize with (as estimate) size of patch to neighbour.
forAll(procPatchMap, procI)
{
if (procPatchMap[procI] != -1)
{
globalToProc[procI].resize
(
patches[procPatchMap[procI]].size()
);
}
}
// Collect all (non-local) globalcells/faces needed.
forAll(stencil_, faceI)
{
const labelList& stencilCells = stencil_[faceI];
forAll(stencilCells, i)
{
label globalCellI = stencilCells[i];
label procI = globalNumbering.whichProcID(stencilCells[i]);
if (procI != Pstream::myProcNo())
{
label nCompact = globalToProc[procI].size();
globalToProc[procI].insert(globalCellI, nCompact);
}
}
}
// Sort global cells needed (not really necessary)
forAll(globalToProc, procI)
{
if (procI != Pstream::myProcNo())
{
Map<label>& globalMap = globalToProc[procI];
SortableList<label> sorted(globalMap.toc());
forAll(sorted, i)
{
Map<label>::iterator iter = globalMap.find(sorted[i]);
iter() = i;
}
}
}
// forAll(globalToProc, procI)
// {
// Pout<< "From processor:" << procI << " want cells/faces:" << endl;
// forAllConstIter(Map<label>, globalToProc[procI], iter)
// {
// Pout<< " global:" << iter.key()
// << " local:" << globalNumbering.toLocal(procI, iter.key())
// << endl;
// }
// Pout<< endl;
// }
}
// 2. The overall compact addressing is
// - myProcNo first
// - all other processors consecutively
labelList compactStart(Pstream::nProcs());
compactStart[Pstream::myProcNo()] = 0;
label nCompact = mesh.nCells()+nBnd;
forAll(compactStart, procI)
{
if (procI != Pstream::myProcNo())
{
compactStart[procI] = nCompact;
nCompact += globalToProc[procI].size();
// Pout<< "Data wanted from " << procI << " starts at "
// << compactStart[procI] << endl;
}
}
// Pout<< "Overall cells needed:" << nCompact << endl;
// 3. Find out what to receive/send in compact addressing.
labelListList recvCompact(Pstream::nProcs());
for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
if (procI != Pstream::myProcNo())
{
labelList wantedGlobals(globalToProc[procI].size());
recvCompact[procI].setSize(globalToProc[procI].size());
label i = 0;
forAllConstIter(Map<label>, globalToProc[procI], iter)
{
wantedGlobals[i] = iter.key();
recvCompact[procI][i] = compactStart[procI]+iter();
i++;
}
// Pout<< "From proc:" << procI
// << " I need (globalcells):" << wantedGlobals
// << " which are my compact:" << recvCompact[procI]
// << endl;
// Send the global cell numbers I need from procI
OPstream str(Pstream::blocking, procI);
str << wantedGlobals;
}
else
{
recvCompact[procI] =
compactStart[procI]
+ identity(mesh.nCells()+nBnd);
}
}
labelListList sendCompact(Pstream::nProcs());
for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
if (procI != Pstream::myProcNo())
{
// See what neighbour wants to receive (= what I need to send)
IPstream str(Pstream::blocking, procI);
labelList globalCells(str);
labelList& procCompact = sendCompact[procI];
procCompact.setSize(globalCells.size());
// Convert from globalCells (all on my processor!) into compact
// addressing
forAll(globalCells, i)
{
label cellI = globalNumbering.toLocal(globalCells[i]);
procCompact[i] = compactStart[Pstream::myProcNo()]+cellI;
}
}
else
{
sendCompact[procI] = recvCompact[procI];
}
}
// Convert stencil to compact numbering
forAll(stencil_, faceI)
{
labelList& stencilCells = stencil_[faceI];
forAll(stencilCells, i)
{
label globalCellI = stencilCells[i];
label procI = globalNumbering.whichProcID(globalCellI);
if (procI != Pstream::myProcNo())
{
label localCompact = globalToProc[procI][globalCellI];
stencilCells[i] = compactStart[procI]+localCompact;
}
else
{
label localCompact = globalNumbering.toLocal(globalCellI);
stencilCells[i] = compactStart[procI]+localCompact;
}
}
}
// Pout<< "***stencil_:" << stencil_ << endl;
// Constuct map for distribution of compact data.
mapPtr_.reset
(
new mapDistribute
(
nCompact,
sendCompact,
recvCompact,
true // reuse send/recv maps.
)
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::extendedStencil::extendedStencil
(
const mapDistribute& map,
const labelListList& stencil
)
:
mapPtr_
(
autoPtr<mapDistribute>
(
new mapDistribute
(
map.constructSize(),
map.subMap(),
map.constructMap()
)
)
),
stencil_(stencil)
{}
Foam::extendedStencil::extendedStencil(const polyMesh& mesh)
{
calcExtendedFaceStencil(mesh);
}
// ************************************************************************* //

View File

@ -0,0 +1,151 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::extendedStencil
Description
Calculates/constains the extended face stencil.
The stencil is a list of indices into either cells or boundary faces
in a compact way. (element 0 is owner, 1 is neighbour). The index numbering
is
- cells first
- then all (non-empty patch) boundary faces
When used in evaluation is a two stage process:
- collect the data (cell data and non-empty boundaries) into a
single field
- (parallel) distribute the field
- sum the weights*field.
SourceFiles
extendedStencil.C
\*---------------------------------------------------------------------------*/
#ifndef extendedStencil_H
#define extendedStencil_H
#include "mapDistribute.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class globalIndex;
/*---------------------------------------------------------------------------*\
Class extendedStencil Declaration
\*---------------------------------------------------------------------------*/
class extendedStencil
{
// Private data
//- Swap map for getting neigbouring data
autoPtr<mapDistribute> mapPtr_;
//- Per face the stencil.
labelListList stencil_;
// Private Member Functions
void calcFaceStencils(const polyMesh&, const globalIndex&);
//- Calculate the stencil (but not weights)
void calcExtendedFaceStencil(const polyMesh&);
//- Disallow default bitwise copy construct
extendedStencil(const extendedStencil&);
//- Disallow default bitwise assignment
void operator=(const extendedStencil&);
public:
// Constructors
//- Construct from components
extendedStencil(const mapDistribute& map, const labelListList&);
//- Construct from all cells and boundary faces
extendedStencil(const polyMesh&);
// Member Functions
//- Return reference to the parallel distribution map
const mapDistribute& map() const
{
return mapPtr_();
}
//- Return reference to the stencil
const labelListList& stencil() const
{
return stencil_;
}
//- Use map to get the data into stencil order
template<class T>
void collectData
(
const GeometricField<T, fvPatchField, volMesh>& fld,
List<List<T> >& stencilFld
) const;
//- Given weights interpolate vol field
template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > interpolate
(
const GeometricField<Type, fvPatchField, volMesh>& fld,
const List<List<scalar> >& stencilWeights
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "extendedStencilTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "extendedStencil.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::extendedStencil::collectData
(
const GeometricField<Type, fvPatchField, volMesh>& fld,
List<List<Type> >& stencilFld
) const
{
// 1. Construct cell data in compact addressing
List<Type> compactFld(map().constructSize(), pTraits<Type>::zero);
// Insert my internal values
forAll(fld, cellI)
{
compactFld[cellI] = fld[cellI];
}
// Insert my boundary values
label nCompact = fld.size();
forAll(fld.boundaryField(), patchI)
{
const fvPatchField<Type>& pfld = fld.boundaryField()[patchI];
forAll(pfld, i)
{
compactFld[nCompact++] = pfld[i];
}
}
// Do all swapping
map().distribute(compactFld);
// 2. Pull to stencil
stencilFld.setSize(stencil_.size());
forAll(stencil_, faceI)
{
const labelList& compactCells = stencil_[faceI];
stencilFld[faceI].setSize(compactCells.size());
forAll(compactCells, i)
{
stencilFld[faceI][i] = compactFld[compactCells[i]];
}
}
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::extendedStencil::interpolate
(
const GeometricField<Type, fvPatchField, volMesh>& fld,
const List<List<scalar> >& stencilWeights
) const
{
const fvMesh& mesh = fld.mesh();
// Collect internal and boundary values
List<List<Type> > stencilFld;
collectData(fld, stencilFld);
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr
(
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fld.name(),
mesh.time().timeName(),
mesh
),
mesh,
dimensioned<Type>
(
fld.name(),
fld.dimensions(),
pTraits<Type>::zero
)
)
);
GeometricField<Type, fvsPatchField, surfaceMesh>& sf = tsfCorr();
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
{
const List<Type>& stField = stencilFld[faceI];
const List<scalar>& stWeight = stencilWeights[faceI];
forAll(stField, i)
{
sf[faceI] += stField[i]*stWeight[i];
}
}
// And what for boundaries?
return tsfCorr;
}
// ************************************************************************* //

View File

@ -0,0 +1,36 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "quadraticFit.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makeSurfaceInterpolationScheme(quadraticFit);
}
// ************************************************************************* //

View File

@ -0,0 +1,138 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
quadraticFit
Description
Quadratic fit interpolation scheme which applies an explicit correction to
linear.
SourceFiles
quadraticFit.C
\*---------------------------------------------------------------------------*/
#ifndef quadraticFit_H
#define quadraticFit_H
#include "linear.H"
#include "quadraticFitData.H"
#include "extendedStencil.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class quadraticFit Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class quadraticFit
:
public linear<Type>
{
// Private Data
const scalar centralWeight_;
// Private Member Functions
//- Disallow default bitwise copy construct
quadraticFit(const quadraticFit&);
//- Disallow default bitwise assignment
void operator=(const quadraticFit&);
public:
//- Runtime type information
TypeName("quadraticFit");
// Constructors
//- Construct from mesh and Istream
quadraticFit(const fvMesh& mesh, Istream& is)
:
linear<Type>(mesh),
centralWeight_(readScalar(is))
{}
//- Construct from mesh, faceFlux and Istream
quadraticFit
(
const fvMesh& mesh,
const surfaceScalarField& faceFlux,
Istream& is
)
:
linear<Type>(mesh),
centralWeight_(readScalar(is))
{}
// Member Functions
//- Return true if this scheme uses an explicit correction
virtual bool corrected() const
{
return true;
}
//- Return the explicit correction to the face-interpolate
virtual tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
correction
(
const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
const fvMesh& mesh = this->mesh();
const quadraticFitData& cfd = quadraticFitData::New
(
mesh,
centralWeight_
);
const extendedStencil& stencil = cfd.stencil();
const List<scalarList>& f = cfd.fit();
return stencil.interpolate(vf, f);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,310 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "quadraticFitData.H"
#include "surfaceFields.H"
#include "volFields.H"
#include "SVD.H"
#include "syncTools.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(quadraticFitData, 0);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::quadraticFitData::quadraticFitData
(
const fvMesh& mesh,
const scalar cWeight
)
:
MeshObject<fvMesh, quadraticFitData>(mesh),
centralWeight_(cWeight),
#ifdef SPHERICAL_GEOMETRY
dim_(2),
#else
dim_(mesh.nGeometricD()),
#endif
minSize_
(
dim_ == 1 ? 3 :
dim_ == 2 ? 6 :
dim_ == 3 ? 9 : 0
),
stencil_(mesh),
fit_(mesh.nInternalFaces())
{
if (debug)
{
Info << "Contructing quadraticFitData" << endl;
}
// check input
if (centralWeight_ < 1 - SMALL)
{
FatalErrorIn("quadraticFitData::quadraticFitData")
<< "centralWeight requested = " << centralWeight_
<< " should not be less than one"
<< exit(FatalError);
}
if (minSize_ == 0)
{
FatalErrorIn("quadraticFitSnGradData")
<< " dimension must be 1,2 or 3, not" << dim_ << exit(FatalError);
}
// store the polynomial size for each cell to write out
surfaceScalarField interpPolySize
(
IOobject
(
"quadraticFitInterpPolySize",
"constant",
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("quadraticFitInterpPolySize", dimless, scalar(0))
);
// Get the cell/face centres in stencil order.
// Centred face stencils no good for triangles of tets. Need bigger stencils
List<List<point> > stencilPoints(stencil_.stencil().size());
stencil_.collectData
(
mesh.C(),
stencilPoints
);
// find the fit coefficients for every face in the mesh
for(label faci = 0; faci < mesh.nInternalFaces(); faci++)
{
interpPolySize[faci] = calcFit(stencilPoints[faci], faci);
}
interpPolySize.write();
if (debug)
{
Info<< "quadraticFitData::quadraticFitData() :"
<< "Finished constructing polynomialFit data"
<< endl;
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::quadraticFitData::findFaceDirs
(
vector& idir, // value changed in return
vector& jdir, // value changed in return
vector& kdir, // value changed in return
const fvMesh& mesh,
const label faci
)
{
idir = mesh.Sf()[faci];
idir /= mag(idir);
# ifndef SPHERICAL_GEOMETRY
if (mesh.nGeometricD() <= 2) // find the normal direcion
{
if (mesh.directions()[0] == -1)
{
kdir = vector(1, 0, 0);
}
else if (mesh.directions()[1] == -1)
{
kdir = vector(0, 1, 0);
}
else
{
kdir = vector(0, 0, 1);
}
}
else // 3D so find a direction in the place of the face
{
const face& f = mesh.faces()[faci];
kdir = mesh.points()[f[0]] - mesh.points()[f[1]];
}
# else
// Spherical geometry so kdir is the radial direction
kdir = mesh.Cf()[faci];
# endif
if (mesh.nGeometricD() == 3)
{
// Remove the idir component from kdir and normalise
kdir -= (idir & kdir)*idir;
scalar magk = mag(kdir);
if (magk < SMALL)
{
FatalErrorIn("findFaceDirs") << " calculated kdir = zero"
<< exit(FatalError);
}
else
{
kdir /= magk;
}
}
jdir = kdir ^ idir;
}
Foam::label Foam::quadraticFitData::calcFit
(
const List<point>& C,
const label faci
)
{
vector idir(1,0,0);
vector jdir(0,1,0);
vector kdir(0,0,1);
findFaceDirs(idir, jdir, kdir, mesh(), faci);
scalarList wts(C.size(), scalar(1));
wts[0] = centralWeight_;
wts[1] = centralWeight_;
point p0 = mesh().faceCentres()[faci];
scalar scale = 0;
// calculate the matrix of the polynomial components
Matrix<scalar> B(C.size(), minSize_, scalar(0));
for(label ip = 0; ip < C.size(); ip++)
{
const point& p = C[ip];
scalar px = (p - p0)&idir;
scalar py = (p - p0)&jdir;
#ifndef SPHERICAL_GEOMETRY
scalar pz = (p - p0)&kdir;
#else
scalar pz = mag(p) - mag(p0);
#endif
if (ip == 0)
{
scale = max(max(mag(px), mag(py)), mag(pz));
}
px /= scale;
py /= scale;
pz /= scale;
label is = 0;
B[ip][is++] = wts[ip];
B[ip][is++] = wts[ip]*px;
B[ip][is++] = wts[ip]*sqr(px);
if (dim_ >= 2)
{
B[ip][is++] = wts[ip]*py;
B[ip][is++] = wts[ip]*px*py;
B[ip][is++] = wts[ip]*sqr(py);
}
if (dim_ == 3)
{
B[ip][is++] = wts[ip]*pz;
B[ip][is++] = wts[ip]*px*pz;
//B[ip][is++] = wts[ip]*py*pz;
B[ip][is++] = wts[ip]*sqr(pz);
}
}
// Set the fit
label stencilSize = C.size();
fit_[faci].setSize(stencilSize);
scalarList singVals(minSize_);
label nSVDzeros = 0;
bool goodFit = false;
for(scalar tol = SMALL; tol < 0.1 && !goodFit; tol *= 10)
{
SVD svd(B, tol);
scalar fit0 = wts[0]*svd.VSinvUt()[0][0];
scalar fit1 = wts[1]*svd.VSinvUt()[0][1];
goodFit = sign(fit0) == sign(fit1);
if (goodFit)
{
fit_[faci][0] = fit0;
fit_[faci][1] = fit1;
for(label i = 2; i < stencilSize; i++)
{
fit_[faci][i] = wts[i]*svd.VSinvUt()[0][i];
}
singVals = svd.S();
nSVDzeros = svd.nZeros();
}
}
if (!goodFit)
{
FatalErrorIn
(
"quadraticFitData::calcFit(const pointField&, const label)"
) << "For face " << faci << endl
<< "Fit not good even once tol >= 0.1"
<< exit(FatalError);
}
const GeometricField<scalar, fvsPatchField, surfaceMesh>& w =
mesh().surfaceInterpolation::weights();
// remove the uncorrected linear coefficients
fit_[faci][0] -= w[faci];
fit_[faci][1] -= 1 - w[faci];
return minSize_ - nSVDzeros;
}
bool Foam::quadraticFitData::movePoints()
{
notImplemented("quadraticFitData::movePoints()");
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,140 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
quadraticFitData
Description
Data for the quadratic fit correction interpolation scheme
SourceFiles
quadraticFitData.C
\*---------------------------------------------------------------------------*/
#ifndef quadraticFitData_H
#define quadraticFitData_H
#include "MeshObject.H"
#include "fvMesh.H"
#include "extendedStencil.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class globalIndex;
/*---------------------------------------------------------------------------*\
Class quadraticFitData Declaration
\*---------------------------------------------------------------------------*/
class quadraticFitData
:
public MeshObject<fvMesh, quadraticFitData>
{
// Private data
//- weights for central stencil
const scalar centralWeight_;
//- dimensionality of the geometry
const label dim_;
//- minimum stencil size
const label minSize_;
//- Extended stencil addressing
extendedStencil stencil_;
//- For each cell in the mesh store the values which multiply the
// values of the stencil to obtain the gradient for each direction
List<scalarList> fit_;
// Private member functions
//- Find the normal direction and i, j and k directions for face faci
static void findFaceDirs
(
vector& idir, // value changed in return
vector& jdir, // value changed in return
vector& kdir, // value changed in return
const fvMesh& mesh,
const label faci
);
label calcFit(const List<point>&, const label faci);
public:
TypeName("quadraticFitData");
// Constructors
explicit quadraticFitData
(
const fvMesh& mesh,
scalar cWeightDim
);
// Destructor
virtual ~quadraticFitData()
{}
// Member functions
//- Return reference to the stencil
const extendedStencil& stencil() const
{
return stencil_;
}
//- Return reference to fit coefficients
const List<scalarList>& fit() const
{
return fit_;
}
//- Delete the data when the mesh moves not implemented
virtual bool movePoints();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //