Added missing dirs
This commit is contained in:
parent
5226480f2c
commit
aa1968e89d
11 changed files with 1674 additions and 0 deletions
407
src/OpenFOAM/matrices/Matrix/Matrix.C
Normal file
407
src/OpenFOAM/matrices/Matrix/Matrix.C
Normal file
|
@ -0,0 +1,407 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 "Matrix.H"
|
||||
|
||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
void Foam::Matrix<T>::allocate()
|
||||
{
|
||||
if (n_ && m_)
|
||||
{
|
||||
v_ = new T*[n_];
|
||||
v_[0] = new T[n_*m_];
|
||||
|
||||
for (register label i=1; i<n_; i++)
|
||||
{
|
||||
v_[i] = v_[i-1] + m_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
Foam::Matrix<T>::~Matrix()
|
||||
{
|
||||
if (v_)
|
||||
{
|
||||
delete[] (v_[0]);
|
||||
delete[] v_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
const Foam::Matrix<T>& Foam::Matrix<T>::null()
|
||||
{
|
||||
Matrix<T>* nullPtr = reinterpret_cast<Matrix<T>*>(NULL);
|
||||
return *nullPtr;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::Matrix<T>::Matrix(const label n, const label m)
|
||||
:
|
||||
v_(NULL),
|
||||
n_(n),
|
||||
m_(m)
|
||||
{
|
||||
if (n_ < 0 || m_ < 0)
|
||||
{
|
||||
FatalErrorIn("Matrix<T>::Matrix(const label n, const label m)")
|
||||
<< "bad n, m " << n_ << ", " << m_
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
allocate();
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::Matrix<T>::Matrix(const label n, const label m, const T& a)
|
||||
:
|
||||
v_(NULL),
|
||||
n_(n),
|
||||
m_(m)
|
||||
{
|
||||
if (n_ < 0 || m_ < 0)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"Matrix<T>::Matrix(const label n, const label m, const T&)"
|
||||
) << "bad n, m " << n_ << ", " << m_
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
allocate();
|
||||
|
||||
if (v_)
|
||||
{
|
||||
T* v = v_[0];
|
||||
|
||||
label nm = n_*m_;
|
||||
|
||||
for (register label i=0; i<nm; i++)
|
||||
{
|
||||
v[i] = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::Matrix<T>::Matrix(const Matrix<T>& a)
|
||||
:
|
||||
v_(NULL),
|
||||
n_(a.n_),
|
||||
m_(a.m_)
|
||||
{
|
||||
if (a.v_)
|
||||
{
|
||||
allocate();
|
||||
T* v = v_[0];
|
||||
const T* av = a.v_[0];
|
||||
|
||||
label nm = n_*m_;
|
||||
for (register label i=0; i<nm; i++)
|
||||
{
|
||||
v[i] = av[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Foam::Matrix<T>::clear()
|
||||
{
|
||||
if (v_)
|
||||
{
|
||||
delete[] (v_[0]);
|
||||
delete[] v_;
|
||||
}
|
||||
n_ = 0;
|
||||
m_ = 0;
|
||||
v_ = NULL;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Foam::Matrix<T>::transfer(Matrix<T>& a)
|
||||
{
|
||||
clear();
|
||||
|
||||
n_ = a.n_;
|
||||
a.n_ = 0;
|
||||
|
||||
m_ = a.m_;
|
||||
a.m_ = 0;
|
||||
|
||||
v_ = a.v_;
|
||||
a.v_ = NULL;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
void Foam::Matrix<T>::operator=(const T& t)
|
||||
{
|
||||
if (v_)
|
||||
{
|
||||
T* v = v_[0];
|
||||
|
||||
label nm = n_*m_;
|
||||
for (register label i=0; i<nm; i++)
|
||||
{
|
||||
v[i] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Assignment operator. Takes linear time.
|
||||
template<class T>
|
||||
void Foam::Matrix<T>::operator=(const Matrix<T>& a)
|
||||
{
|
||||
if (this == &a)
|
||||
{
|
||||
FatalErrorIn("Matrix<T>::operator=(const Matrix<T>&)")
|
||||
<< "attempted assignment to self"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (n_ != a.n_ || m_ != a.m_)
|
||||
{
|
||||
clear();
|
||||
n_ = a.n_;
|
||||
m_ = a.m_;
|
||||
allocate();
|
||||
}
|
||||
|
||||
if (v_)
|
||||
{
|
||||
T* v = v_[0];
|
||||
const T* av = a.v_[0];
|
||||
|
||||
label nm = n_*m_;
|
||||
for (register label i=0; i<nm; i++)
|
||||
{
|
||||
v[i] = av[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
const T& Foam::max(const Matrix<T>& a)
|
||||
{
|
||||
label nm = a.n_*a.m_;
|
||||
|
||||
if (nm)
|
||||
{
|
||||
label curMaxI = 0;
|
||||
const T* v = a.v_[0];
|
||||
|
||||
for (register label i=1; i<nm; i++)
|
||||
{
|
||||
if (v[i] > v[curMaxI])
|
||||
{
|
||||
curMaxI = i;
|
||||
}
|
||||
}
|
||||
|
||||
return v[curMaxI];
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn("max(const Matrix<T>&)")
|
||||
<< "matrix is empty"
|
||||
<< abort(FatalError);
|
||||
|
||||
// Return in error to keep compiler happy
|
||||
return a[0][0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
const T& Foam::min(const Matrix<T>& a)
|
||||
{
|
||||
label nm = a.n_*a.m_;
|
||||
|
||||
if (nm)
|
||||
{
|
||||
label curMinI = 0;
|
||||
const T* v = a.v_[0];
|
||||
|
||||
for (register label i=1; i<nm; i++)
|
||||
{
|
||||
if (v[i] < v[curMinI])
|
||||
{
|
||||
curMinI = i;
|
||||
}
|
||||
}
|
||||
|
||||
return v[curMinI];
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn("min(const Matrix<T>&)")
|
||||
<< "matrix is empty"
|
||||
<< abort(FatalError);
|
||||
|
||||
// Return in error to keep compiler happy
|
||||
return a[0][0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
Foam::Matrix<T> Foam::operator-(const Matrix<T>& a)
|
||||
{
|
||||
Matrix<T> na(a.n_, a.m_);
|
||||
|
||||
if (a.n_ && a.m_)
|
||||
{
|
||||
T* nav = na.v_[0];
|
||||
const T* av = a.v_[0];
|
||||
|
||||
label nm = a.n_*a.m_;
|
||||
for (register label i=0; i<nm; i++)
|
||||
{
|
||||
nav[i] = -av[i];
|
||||
}
|
||||
}
|
||||
|
||||
return na;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::Matrix<T> Foam::operator+(const Matrix<T>& a, const Matrix<T>& b)
|
||||
{
|
||||
if (a.n_ != b.n_)
|
||||
{
|
||||
FatalErrorIn("Matrix<T>::operator+(const Matrix<T>&, const Matrix<T>&)")
|
||||
<< "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: "
|
||||
<< a.m_ << ", " << b.m_
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
Matrix<T> ab(a.n_, a.m_);
|
||||
|
||||
T* abv = ab.v_[0];
|
||||
const T* av = a.v_[0];
|
||||
const T* bv = b.v_[0];
|
||||
|
||||
label nm = a.n_*a.m_;;
|
||||
for (register label i=0; i<nm; i++)
|
||||
{
|
||||
abv[i] = av[i] + bv[i];
|
||||
}
|
||||
|
||||
return ab;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::Matrix<T> Foam::operator-(const Matrix<T>& a, const Matrix<T>& b)
|
||||
{
|
||||
if (a.n_ != b.n_)
|
||||
{
|
||||
FatalErrorIn("Matrix<T>::operator-(const Matrix<T>&, const Matrix<T>&)")
|
||||
<< "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: "
|
||||
<< a.m_ << ", " << b.m_
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
Matrix<T> ab(a.n_, a.m_);
|
||||
|
||||
T* abv = ab.v_[0];
|
||||
const T* av = a.v_[0];
|
||||
const T* bv = b.v_[0];
|
||||
|
||||
label nm = a.n_*a.m_;;
|
||||
for (register label i=0; i<nm; i++)
|
||||
{
|
||||
abv[i] = av[i] - bv[i];
|
||||
}
|
||||
|
||||
return ab;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::Matrix<T> Foam::operator*(const scalar s, const Matrix<T>& a)
|
||||
{
|
||||
Matrix<T> sa(a.n_, a.m_);
|
||||
|
||||
if (a.n_ && a.m_)
|
||||
{
|
||||
T* sav = sa.v_[0];
|
||||
const T* av = a.v_[0];
|
||||
|
||||
label nm = a.n_*a.m_;;
|
||||
for (register label i=0; i<nm; i++)
|
||||
{
|
||||
sav[i] = s*av[i];
|
||||
}
|
||||
}
|
||||
|
||||
return sa;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
|
||||
|
||||
#include "MatrixIO.C"
|
||||
|
||||
// ************************************************************************* //
|
211
src/OpenFOAM/matrices/Matrix/Matrix.H
Normal file
211
src/OpenFOAM/matrices/Matrix/Matrix.H
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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::Matrix
|
||||
|
||||
Description
|
||||
A templated 2D matrix of objects of \<T\>, where the n x m matrix
|
||||
dimensions are known and used for subscript bounds checking, etc.
|
||||
|
||||
SourceFiles
|
||||
Matrix.C
|
||||
MatrixI.H
|
||||
MatrixIO.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Matrix_H
|
||||
#define Matrix_H
|
||||
|
||||
#include "List.H"
|
||||
#include "label.H"
|
||||
#include "bool.H"
|
||||
#include "autoPtr.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of friend functions and operators
|
||||
|
||||
template<class T> class Matrix;
|
||||
|
||||
template<class T> const T& max(const Matrix<T>&);
|
||||
template<class T> const T& min(const Matrix<T>&);
|
||||
|
||||
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 T> Istream& operator>>(Istream&, Matrix<T>&);
|
||||
template<class T> Ostream& operator<<(Ostream&, const Matrix<T>&);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Matrix Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class T>
|
||||
class Matrix
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Row pointers
|
||||
T** __restrict__ v_;
|
||||
|
||||
//- Number of rows and columns in Matrix.
|
||||
label n_, m_;
|
||||
|
||||
//- Allocate the storage for the row-pointers and the data
|
||||
// and set the row pointers
|
||||
void allocate();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Null constructor.
|
||||
inline Matrix();
|
||||
|
||||
//- Construct given number of rows and columns.
|
||||
Matrix(const label n, const label m);
|
||||
|
||||
//- Construct with given number of rows and columns
|
||||
// and value for all elements.
|
||||
Matrix(const label n, const label m, const T&);
|
||||
|
||||
//- Copy constructor.
|
||||
Matrix(const Matrix<T>&);
|
||||
|
||||
//- Construct from Istream.
|
||||
Matrix(Istream&);
|
||||
|
||||
//- Clone
|
||||
inline autoPtr<Matrix<T> > clone() const;
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
~Matrix();
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
//- Return a null Matrix
|
||||
static const Matrix<T>& null();
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the number of rows
|
||||
inline label n() const;
|
||||
|
||||
//- Return the number of columns
|
||||
inline label m() const;
|
||||
|
||||
//- Return the number of elements in matrix (n*m)
|
||||
inline label size() const;
|
||||
|
||||
|
||||
// Check
|
||||
|
||||
//- Check index i is within valid range (0 ... n-1).
|
||||
inline void checki(const label i) const;
|
||||
|
||||
//- Check index j is within valid range (0 ... m-1).
|
||||
inline void checkj(const label j) const;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
//- Clear the Matrix, i.e. set sizes to zero.
|
||||
void clear();
|
||||
|
||||
//- Transfer the contents of the argument Matrix into this Matrix
|
||||
// and annull the argument Matrix.
|
||||
void transfer(Matrix<T>&);
|
||||
|
||||
|
||||
// Member operators
|
||||
|
||||
//- Return subscript-checked element of Matrix.
|
||||
inline T* operator[](const label);
|
||||
|
||||
//- Return subscript-checked element of constant Matrix.
|
||||
inline const T* operator[](const label) const;
|
||||
|
||||
//- Assignment operator. Takes linear time.
|
||||
void operator=(const Matrix<T>&);
|
||||
|
||||
//- Assignment of all entries to the given value
|
||||
void operator=(const T&);
|
||||
|
||||
|
||||
// Friend functions
|
||||
|
||||
friend const T& max<T>(const Matrix<T>&);
|
||||
friend const T& min<T>(const Matrix<T>&);
|
||||
|
||||
|
||||
// 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>&);
|
||||
|
||||
|
||||
// IOstream operators
|
||||
|
||||
//- Read Matrix from Istream, discarding contents of existing Matrix.
|
||||
friend Istream& operator>> <T>(Istream&, Matrix<T>&);
|
||||
|
||||
// Write Matrix to Ostream.
|
||||
friend Ostream& operator<< <T>(Ostream&, const Matrix<T>&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
# include "MatrixI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "Matrix.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
133
src/OpenFOAM/matrices/Matrix/MatrixI.H
Normal file
133
src/OpenFOAM/matrices/Matrix/MatrixI.H
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
inline Foam::Matrix<T>::Matrix()
|
||||
:
|
||||
v_(NULL),
|
||||
n_(0),
|
||||
m_(0)
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::autoPtr<Foam::Matrix<T> > Foam::Matrix<T>::clone() const
|
||||
{
|
||||
return autoPtr<Matrix<T> >(new Matrix<T>(*this));
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
//- Return the number of rows
|
||||
template<class T>
|
||||
inline Foam::label Foam::Matrix<T>::n() const
|
||||
{
|
||||
return n_;
|
||||
}
|
||||
|
||||
|
||||
//- Return the number of columns
|
||||
template<class T>
|
||||
inline Foam::label Foam::Matrix<T>::m() const
|
||||
{
|
||||
return m_;
|
||||
}
|
||||
|
||||
|
||||
//- Return the number of columns
|
||||
template<class T>
|
||||
inline Foam::label Foam::Matrix<T>::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
|
||||
{
|
||||
if (!n_)
|
||||
{
|
||||
FatalErrorIn("Matrix<T>::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)")
|
||||
<< "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
|
||||
{
|
||||
if (!m_)
|
||||
{
|
||||
FatalErrorIn("Matrix<T>::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)")
|
||||
<< "index " << j << " out of range 0 ... " << m_-1
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
// Return subscript-checked element access
|
||||
template<class T>
|
||||
inline T* Foam::Matrix<T>::operator[](const label i)
|
||||
{
|
||||
# ifdef FULLDEBUG
|
||||
checki(i);
|
||||
# endif
|
||||
return v_[i];
|
||||
}
|
||||
|
||||
|
||||
// Return subscript-checked const element access
|
||||
template<class T>
|
||||
inline const T* Foam::Matrix<T>::operator[](const label i) const
|
||||
{
|
||||
# ifdef FULLDEBUG
|
||||
checki(i);
|
||||
# endif
|
||||
return v_[i];
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
262
src/OpenFOAM/matrices/Matrix/MatrixIO.C
Normal file
262
src/OpenFOAM/matrices/Matrix/MatrixIO.C
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 "Matrix.H"
|
||||
#include "Istream.H"
|
||||
#include "Ostream.H"
|
||||
#include "token.H"
|
||||
#include "contiguous.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
Foam::Matrix<T>::Matrix(Istream& is)
|
||||
:
|
||||
v_(NULL),
|
||||
n_(0),
|
||||
m_(0)
|
||||
{
|
||||
operator>>(is, *this);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::Istream& Foam::operator>>(Istream& is, Matrix<T>& M)
|
||||
{
|
||||
// Anull matrix
|
||||
M.clear();
|
||||
|
||||
is.fatalCheck("operator>>(Istream&, Matrix<T>&)");
|
||||
|
||||
token firstToken(is);
|
||||
|
||||
is.fatalCheck("operator>>(Istream&, Matrix<T>&) : reading first token");
|
||||
|
||||
if (firstToken.isLabel())
|
||||
{
|
||||
M.n_ = firstToken.labelToken();
|
||||
M.m_ = readLabel(is);
|
||||
|
||||
label nm = M.n_*M.m_;
|
||||
|
||||
// Read list contents depending on data format
|
||||
if (is.format() == IOstream::ASCII || !contiguous<T>())
|
||||
{
|
||||
// Read beginning of contents
|
||||
char listDelimiter = is.readBeginList("Matrix");
|
||||
|
||||
if (nm)
|
||||
{
|
||||
M.allocate();
|
||||
T* v = M.v_[0];
|
||||
|
||||
if (listDelimiter == token::BEGIN_LIST)
|
||||
{
|
||||
label k = 0;
|
||||
|
||||
// loop over rows
|
||||
for (register label i=0; i<M.n(); i++)
|
||||
{
|
||||
listDelimiter = is.readBeginList("MatrixRow");
|
||||
|
||||
for (register label j=0; j<M.m(); j++)
|
||||
{
|
||||
is >> v[k++];
|
||||
|
||||
is.fatalCheck
|
||||
(
|
||||
"operator>>(Istream&, Matrix<T>&) : "
|
||||
"reading entry"
|
||||
);
|
||||
}
|
||||
|
||||
is.readEndList("MatrixRow");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
T element;
|
||||
is >> element;
|
||||
|
||||
is.fatalCheck
|
||||
(
|
||||
"operator>>(Istream&, Matrix<T>&) : "
|
||||
"reading the single entry"
|
||||
);
|
||||
|
||||
for (register label i=0; i<nm; i++)
|
||||
{
|
||||
v[i] = element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read end of contents
|
||||
is.readEndList("Matrix");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nm)
|
||||
{
|
||||
M.allocate();
|
||||
T* v = M.v_[0];
|
||||
|
||||
is.read(reinterpret_cast<char*>(v), nm*sizeof(T));
|
||||
|
||||
is.fatalCheck
|
||||
(
|
||||
"operator>>(Istream&, Matrix<T>&) : "
|
||||
"reading the binary block"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorIn("operator>>(Istream&, Matrix<T>&)", is)
|
||||
<< "incorrect first token, expected <int>, found "
|
||||
<< firstToken.info()
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const Matrix<T>& 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 (nm)
|
||||
{
|
||||
bool uniform = false;
|
||||
|
||||
const T* v = M.v_[0];
|
||||
|
||||
if (nm > 1 && contiguous<T>())
|
||||
{
|
||||
uniform = true;
|
||||
|
||||
for (register label i=0; i< nm; i++)
|
||||
{
|
||||
if (v[i] != v[0])
|
||||
{
|
||||
uniform = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uniform)
|
||||
{
|
||||
// Write size of list and start contents delimiter
|
||||
os << token::BEGIN_BLOCK;
|
||||
|
||||
// Write list contents
|
||||
os << v[0];
|
||||
|
||||
// Write end of contents delimiter
|
||||
os << token::END_BLOCK;
|
||||
}
|
||||
// Fix: matrices smaller than 20x20 will be written square.
|
||||
// HJ, 22/Jan/2009
|
||||
else if (nm < 400 && contiguous<T>())
|
||||
{
|
||||
// Write size of list and start contents delimiter
|
||||
os << token::BEGIN_LIST;
|
||||
|
||||
label k = 0;
|
||||
|
||||
// loop over rows
|
||||
for (register label i=0; i< M.n(); i++)
|
||||
{
|
||||
os << nl << token::BEGIN_LIST;
|
||||
|
||||
// Write row
|
||||
for (register label j=0; j< M.m(); j++)
|
||||
{
|
||||
if (j > 0) os << token::SPACE;
|
||||
os << v[k++];
|
||||
}
|
||||
|
||||
os << token::END_LIST;
|
||||
}
|
||||
|
||||
// Write end of contents delimiter
|
||||
os << token::END_LIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write size of list and start contents delimiter
|
||||
os << nl << token::BEGIN_LIST;
|
||||
|
||||
label k = 0;
|
||||
|
||||
// loop over rows
|
||||
for (register label i=0; i< M.n(); i++)
|
||||
{
|
||||
os << nl << token::BEGIN_LIST;
|
||||
|
||||
// Write row
|
||||
for (register label j=0; j< M.m(); j++)
|
||||
{
|
||||
os << nl << v[k++];
|
||||
}
|
||||
|
||||
os << nl << token::END_LIST;
|
||||
}
|
||||
|
||||
// Write end of contents delimiter
|
||||
os << nl << token::END_LIST << nl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
os << token::BEGIN_LIST << token::END_LIST << nl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nm)
|
||||
{
|
||||
os.write(reinterpret_cast<const char*>(M.v_[0]), nm*sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
// Check state of IOstream
|
||||
os.check("Ostream& operator<<(Ostream&, const Matrix&)");
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
146
src/OpenFOAM/matrices/Matrix/tools/DenseMatrixTools.C
Normal file
146
src/OpenFOAM/matrices/Matrix/tools/DenseMatrixTools.C
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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
|
||||
DenseMatrixTools
|
||||
|
||||
\*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "DenseMatrixTools.H"
|
||||
#include "Swap.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Solve with pivoting. Note: Destroys matrix and b
|
||||
template<class T>
|
||||
static void Foam::DenseMatrixTools::solve
|
||||
(
|
||||
Matrix<T>& A,
|
||||
List<T>& x,
|
||||
List<T>& b
|
||||
)
|
||||
{
|
||||
const label nRows = A.n();
|
||||
|
||||
// Create and initialise permutation array
|
||||
labelList p(nRows);
|
||||
|
||||
forAll (p, i)
|
||||
{
|
||||
p[i] = i;
|
||||
}
|
||||
|
||||
|
||||
// Eliminate equations
|
||||
for (label k = 0; k < nRows - 1; k++)
|
||||
{
|
||||
// Swap rows
|
||||
label m = k;
|
||||
|
||||
for(label i = k + 1; i < nRows; ++i)
|
||||
{
|
||||
if (Foam::mag(A[p[i]][k]) > Foam::mag(A[p[m]][k]))
|
||||
{
|
||||
m = i;
|
||||
}
|
||||
|
||||
Swap(p[k], p[m]);
|
||||
}
|
||||
|
||||
|
||||
for (label i = k + 1; i < nRows; i++)
|
||||
{
|
||||
label pi = p[i];
|
||||
label pk = p[k];
|
||||
|
||||
// T r = A[pi][k]/A[pk][k];
|
||||
T r = cmptDivide(A[pi][k], A[pk][k]);
|
||||
|
||||
for (label j = k + 1; j < nRows; j++)
|
||||
{
|
||||
// A[pi][j] -= A[pk][j]*r;
|
||||
A[pi][j] -= cmptMultiply(A[pk][j], r);
|
||||
}
|
||||
|
||||
// b[pi] -= b[pk]*r;
|
||||
b[pi] -= cmptMultiply(b[pk], r);
|
||||
}
|
||||
}
|
||||
|
||||
// Back substitute
|
||||
for (label i = nRows - 1; i >= 0; i--)
|
||||
{
|
||||
label pi = p[i];
|
||||
|
||||
T sum = b[pi];
|
||||
|
||||
for (label j = i + 1; j < nRows; j++)
|
||||
{
|
||||
// sum -= A[pi][j]*x[j];
|
||||
sum -= cmptMultiply(A[pi][j], x[j]);
|
||||
}
|
||||
|
||||
// x[i] = sum/A[pi][i];
|
||||
x[i] = cmptDivide(sum, A[pi][i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
static void Foam::DenseMatrixTools::qrDecompose
|
||||
(
|
||||
const label nCols,
|
||||
FieldField<Field, T>& A,
|
||||
Matrix<T>& R
|
||||
)
|
||||
{
|
||||
// Note: consider Arnoldi algorithm for speed-up. HJ, 14/Sep/2006
|
||||
|
||||
for (label j = 0; j < nCols; j++)
|
||||
{
|
||||
R[j][j] = Foam::sqrt(gSumSqr(A[j]));
|
||||
|
||||
if (mag(R[j][j]) > SMALL)
|
||||
{
|
||||
A[j] /= R[j][j];
|
||||
}
|
||||
|
||||
for (label k = j + 1; k < nCols; k++)
|
||||
{
|
||||
const Field<T>& Aj = A[j];
|
||||
Field<T>& Ak = A[k];
|
||||
T& Rjk = R[j][k];
|
||||
|
||||
Rjk = gSumProd(Aj, Ak);
|
||||
|
||||
for (label i = 0; i < Ak.size(); i++)
|
||||
{
|
||||
Ak[i] -= Rjk*Aj[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
78
src/OpenFOAM/matrices/Matrix/tools/DenseMatrixTools.H
Normal file
78
src/OpenFOAM/matrices/Matrix/tools/DenseMatrixTools.H
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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
|
||||
|
||||
Namespace
|
||||
DenseMatrixTools
|
||||
|
||||
SourceFiles
|
||||
DenseMatrixTools.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef DenseMatrixTools_H
|
||||
#define DenseMatrixTools_H
|
||||
|
||||
#include "Matrix.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class DenseMatrixTools Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
namespace DenseMatrixTools
|
||||
{
|
||||
//- Solve using Gauss Elimination with pivoting. Destroys matrix and b
|
||||
template<class T>
|
||||
static void solve(Matrix<T>& A, List<T>& x, List<T>& b);
|
||||
|
||||
//- Q-R decomposition
|
||||
template<class T>
|
||||
static void qrDecompose
|
||||
(
|
||||
const label nCols,
|
||||
FieldField<Field, T>& A,
|
||||
Matrix<T>& R
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "DenseMatrixTools.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
297
src/OpenFOAM/matrices/Matrix/tools/EigenSolver/EigenSolver.C
Normal file
297
src/OpenFOAM/matrices/Matrix/tools/EigenSolver/EigenSolver.C
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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
|
||||
EigenSolver
|
||||
|
||||
Description
|
||||
|
||||
\*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "EigenSolver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
void Foam::EigenSolver<T>::checkMatrix(const Matrix<T>& mtx) const
|
||||
{
|
||||
// Check shape
|
||||
if (mtx.m() != mtx.n())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void EigenSolver<T>::checkMatrix(const Matrix<T>& m) const"
|
||||
) << "Matrix is not square, cannot calculate eigen-values. "
|
||||
<< "M = " << mtx.m() << " N = " << mtx.n()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Check symmetry
|
||||
T assymetry = pTraits<T>::zero;
|
||||
|
||||
for (label i = 0; i < mtx.m(); i++)
|
||||
{
|
||||
for (label j = i; j < mtx.n(); j++)
|
||||
{
|
||||
assymetry += mag(mtx[i][j] - mtx[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (assymetry > mtx.m()*SMALL)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void EigenSolver<T>::checkMatrix(const Matrix<T>& m) const"
|
||||
) << "Matrix is not symmetric. Assymetry = " << assymetry
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Foam::EigenSolver<T>::factorise(const Matrix<T>& mtx)
|
||||
{
|
||||
// Copy the original matrix into scratch space
|
||||
Matrix<T> a = mtx;
|
||||
|
||||
label n = a.m();
|
||||
|
||||
// Create and initialise the matrix to hold eigen-vectors in columns
|
||||
Matrix<T> v(n, n, pTraits<T>::zero);
|
||||
|
||||
for (label ip = 0; ip < n; ip++)
|
||||
{
|
||||
v[ip][ip] = pTraits<T>::one;
|
||||
}
|
||||
|
||||
// Create and initialise scratch vectors
|
||||
List<T> b(n);
|
||||
List<T>& d = values_;
|
||||
|
||||
// Initialise b and d to the diagonal of a
|
||||
for (label ip = 0; ip < n; ip++)
|
||||
{
|
||||
b[ip] = a[ip][ip];
|
||||
d[ip] = a[ip][ip];
|
||||
}
|
||||
|
||||
List<T> z(n, pTraits<T>::zero);
|
||||
|
||||
label nRotations = 0;
|
||||
|
||||
// Main iteration loop
|
||||
for (label i = 0; i <= 50; i++)
|
||||
{
|
||||
T sm = pTraits<T>::zero;
|
||||
for (label ip = 0; ip < n - 1; ip++)
|
||||
{
|
||||
for (label iq = ip + 1; iq < n; iq++)
|
||||
{
|
||||
sm += mag(a[ip][iq]);
|
||||
}
|
||||
}
|
||||
|
||||
if (sm < VSMALL)
|
||||
{
|
||||
// Normal return, relying on quadratic convergence
|
||||
|
||||
// Copy eigen-vectors. Note that v stores vectors in columns
|
||||
for (label ip = 0; ip < n; ip++)
|
||||
{
|
||||
for (label iq = 0; iq < n; iq++)
|
||||
{
|
||||
vectors_[iq][ip] = v[ip][iq];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate treshold
|
||||
T treshold = pTraits<T>::zero;
|
||||
|
||||
if (i < 4)
|
||||
{
|
||||
// Operation on first 3 sweeps
|
||||
treshold = 0.2*sm/(n*n);
|
||||
}
|
||||
|
||||
T theta, tau, g, h, t, c, s;
|
||||
|
||||
for (label ip = 0; ip < n - 1; ip++)
|
||||
{
|
||||
for (label iq = ip + 1; iq < n; iq++)
|
||||
{
|
||||
g = 100.0*mag(a[ip][iq]);
|
||||
|
||||
// After four sweeps, skip the rotation if the off-diagonal
|
||||
// element is small
|
||||
if
|
||||
(
|
||||
i > 4
|
||||
&& mag(d[ip] + g) == mag(d[ip])
|
||||
&& mag(d[iq] + g) == mag(d[iq])
|
||||
)
|
||||
{
|
||||
a[ip][iq] = pTraits<T>::zero;
|
||||
}
|
||||
else if (mag(a[ip][iq]) > treshold)
|
||||
{
|
||||
h = d[iq] - d[ip];
|
||||
|
||||
if (mag(h) + g == mag(h))
|
||||
{
|
||||
t = a[ip][iq]/h;
|
||||
}
|
||||
else
|
||||
{
|
||||
theta = 0.5*h/(a[ip][iq]);
|
||||
|
||||
t = 1.0/(mag(theta) + Foam::sqrt(1.0 + sqr(theta)));
|
||||
|
||||
if (theta < 0)
|
||||
{
|
||||
t = -t;
|
||||
}
|
||||
}
|
||||
|
||||
c = 1.0/sqrt(1.0 + sqr(t));
|
||||
s = t*c;
|
||||
tau = s/(1.0 + c);
|
||||
h = t*a[ip][iq];
|
||||
|
||||
z[ip] -= h;
|
||||
z[iq] += h;
|
||||
d[ip] -= h;
|
||||
d[iq] += h;
|
||||
|
||||
a[ip][iq] = pTraits<T>::zero;
|
||||
|
||||
// Rotations 0 <= j < p
|
||||
for (label j = 0; j < ip; j++)
|
||||
{
|
||||
rotate(a, s, tau, j, ip, j, iq);
|
||||
}
|
||||
|
||||
// Rotations p < j < q
|
||||
for (label j = ip + 1; j < iq; j++)
|
||||
{
|
||||
rotate(a, s, tau, ip, j, j, iq);
|
||||
}
|
||||
|
||||
// Rotations q < j < n
|
||||
for (label j = iq + 1; j < n; j++)
|
||||
{
|
||||
rotate(a, s, tau, ip, j, iq, j);
|
||||
}
|
||||
|
||||
for (label j = 0; j < n; j++)
|
||||
{
|
||||
rotate(v, s, tau, j, ip, j, iq);
|
||||
}
|
||||
|
||||
// Increment number of rotations
|
||||
nRotations++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update d with the sum of t a_pq and clear z
|
||||
for (label ip = 0; ip < n; ip++)
|
||||
{
|
||||
b[ip] += z[ip];
|
||||
d[ip] = b[ip];
|
||||
z[ip] = pTraits<T>::zero;
|
||||
}
|
||||
|
||||
} // End of main iteration loop
|
||||
|
||||
FatalErrorIn("void Foam::EigenSolver<T>::factorise(const Matrix<T>& mtx)")
|
||||
<< "Maximum number of iterations exceeded"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::EigenSolver<T>::rotate
|
||||
(
|
||||
Matrix<T>& a,
|
||||
const T s,
|
||||
const T tau,
|
||||
const label i,
|
||||
const label j,
|
||||
const label k,
|
||||
const label l
|
||||
) const
|
||||
{
|
||||
T g = a[i][j];
|
||||
T h = a[k][l];
|
||||
|
||||
a[i][j] = g - s*(h + g*tau);
|
||||
a[k][l] = h + s*(g - h*tau);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
// Construct from components
|
||||
template<class T>
|
||||
Foam::EigenSolver<T>::EigenSolver(const Matrix<T>& mtx)
|
||||
:
|
||||
values_(mtx.m(), pTraits<T>::zero),
|
||||
vectors_(mtx.m())
|
||||
{
|
||||
// Size the eigen vectors
|
||||
forAll (vectors_, rowI)
|
||||
{
|
||||
vectors_[rowI].setSize(mtx.m());
|
||||
vectors_[rowI] = pTraits<T>::zero;
|
||||
}
|
||||
|
||||
this->checkMatrix(mtx);
|
||||
|
||||
factorise(mtx);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
T Foam::EigenSolver<T>::eigenValue(const label n) const
|
||||
{
|
||||
return values_[n];
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
const Foam::List<T>& Foam::EigenSolver<T>::eigenVector(const label n) const
|
||||
{
|
||||
return vectors_[n];
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
131
src/OpenFOAM/matrices/Matrix/tools/EigenSolver/EigenSolver.H
Normal file
131
src/OpenFOAM/matrices/Matrix/tools/EigenSolver/EigenSolver.H
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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
|
||||
EigenSolver
|
||||
|
||||
Description
|
||||
Calculate eigen-values and eigen-vectors of a symmetric dense matrix
|
||||
|
||||
SourceFiles
|
||||
EigenSolver.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef EigenSolver_H
|
||||
#define EigenSolver_H
|
||||
|
||||
#include "Matrix.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Class forward declarations
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class EigenSolver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class T>
|
||||
class EigenSolver
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Eigenvalues
|
||||
List<T> values_;
|
||||
|
||||
//- Eigenvectors
|
||||
List<List<T> > vectors_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
EigenSolver(const EigenSolver&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const EigenSolver&);
|
||||
|
||||
|
||||
//- Check matrix for shape and symmetry
|
||||
void checkMatrix(const Matrix<T>& mtx) const;
|
||||
|
||||
//- Factorise into eigen-values and eigen-vectors
|
||||
void factorise(const Matrix<T>& mtx);
|
||||
|
||||
//- Rotate the matrix
|
||||
inline void rotate
|
||||
(
|
||||
Matrix<T>& a,
|
||||
const T s,
|
||||
const T tau,
|
||||
const label i,
|
||||
const label j,
|
||||
const label k,
|
||||
const label l
|
||||
) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Static data members
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from matrix
|
||||
EigenSolver(const Matrix<T>& mtx);
|
||||
|
||||
|
||||
// Destructor - default
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return nth eigen value
|
||||
T eigenValue(const label n) const;
|
||||
|
||||
// Return nth eigen vector
|
||||
const List<T>& eigenVector(const label n) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "EigenSolver.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
4
src/postProcessing/functionObjects/check/Make/files
Normal file
4
src/postProcessing/functionObjects/check/Make/files
Normal file
|
@ -0,0 +1,4 @@
|
|||
ggiCheck/ggiCheckFunctionObject.C
|
||||
meshCheck/meshCheckFunctionObject.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libcheckFunctionObjects
|
4
src/postProcessing/functionObjects/check/Make/options
Normal file
4
src/postProcessing/functionObjects/check/Make/options
Normal file
|
@ -0,0 +1,4 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
LIB_LIBS = \
|
||||
-lfiniteVolume
|
1
wmake/rules/linuxGcc/mplibSYSTEMOPENMPI
Normal file
1
wmake/rules/linuxGcc/mplibSYSTEMOPENMPI
Normal file
|
@ -0,0 +1 @@
|
|||
PFLAGS = -DOMPI_SKIP_MPICXX
|
Reference in a new issue