Files
openfoam/src/OpenFOAM/matrices/Matrix/Matrix.C
henry 318b71e206 Made Matrix generic base-class for SquareMatrix and RectangularMatrix by introducing
the type it will become as a template argument.

Brought everything into line with this change.
2008-09-28 22:50:57 +01:00

434 lines
9.1 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 "Matrix.H"
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
template<class Form, class Type>
void Foam::Matrix<Form, Type>::allocate()
{
if (n_ && m_)
{
v_ = new Type*[n_];
v_[0] = new Type[n_*m_];
for (register label i=1; i<n_; i++)
{
v_[i] = v_[i-1] + m_;
}
}
}
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
template<class Form, class Type>
Foam::Matrix<Form, Type>::~Matrix()
{
if (v_)
{
delete[] (v_[0]);
delete[] v_;
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Form, class Type>
const Foam::Matrix<Form, Type>& Foam::Matrix<Form, Type>::null()
{
Matrix<Form, Type>* nullPtr = reinterpret_cast<Matrix<Form, Type>*>(NULL);
return *nullPtr;
}
template<class Form, class Type>
Foam::Matrix<Form, Type>::Matrix(const label n, const label m)
:
n_(n),
m_(m),
v_(NULL)
{
if (n_ < 0 || m_ < 0)
{
FatalErrorIn("Matrix<Form, Type>::Matrix(const label n, const label m)")
<< "bad n, m " << n_ << ", " << m_
<< abort(FatalError);
}
allocate();
}
template<class Form, class Type>
Foam::Matrix<Form, Type>::Matrix(const label n, const label m, const Type& a)
:
n_(n),
m_(m),
v_(NULL)
{
if (n_ < 0 || m_ < 0)
{
FatalErrorIn
(
"Matrix<Form, Type>::Matrix(const label n, const label m, const T&)"
) << "bad n, m " << n_ << ", " << m_
<< abort(FatalError);
}
allocate();
if (v_)
{
Type* v = v_[0];
label nm = n_*m_;
for (register label i=0; i<nm; i++)
{
v[i] = a;
}
}
}
template<class Form, class Type>
Foam::Matrix<Form, Type>::Matrix(const Matrix<Form, Type>& a)
:
n_(a.n_),
m_(a.m_),
v_(NULL)
{
if (a.v_)
{
allocate();
Type* v = v_[0];
const Type* av = a.v_[0];
label nm = n_*m_;
for (register label i=0; i<nm; i++)
{
v[i] = av[i];
}
}
}
template<class Form, class Type>
void Foam::Matrix<Form, Type>::clear()
{
if (v_)
{
delete[] (v_[0]);
delete[] v_;
}
n_ = 0;
m_ = 0;
v_ = NULL;
}
template<class Form, class Type>
void Foam::Matrix<Form, Type>::transfer(Matrix<Form, Type>& a)
{
clear();
n_ = a.n_;
a.n_ = 0;
m_ = a.m_;
a.m_ = 0;
v_ = a.v_;
a.v_ = NULL;
}
template<class Form, class Type>
Form Foam::Matrix<Form, Type>::T() const
{
const Matrix<Form, Type>& A = *this;
Form 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;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Form, class Type>
void Foam::Matrix<Form, Type>::operator=(const Type& t)
{
if (v_)
{
Type* 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 Form, class Type>
void Foam::Matrix<Form, Type>::operator=(const Matrix<Form, Type>& a)
{
if (this == &a)
{
FatalErrorIn("Matrix<Form, Type>::operator=(const Matrix<Form, Type>&)")
<< "attempted assignment to self"
<< abort(FatalError);
}
if (n_ != a.n_ || m_ != a.m_)
{
clear();
n_ = a.n_;
m_ = a.m_;
allocate();
}
if (v_)
{
Type* v = v_[0];
const Type* av = a.v_[0];
label nm = n_*m_;
for (register label i=0; i<nm; i++)
{
v[i] = av[i];
}
}
}
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class Form, class Type>
const Type& Foam::max(const Matrix<Form, Type>& a)
{
label nm = a.n_*a.m_;
if (nm)
{
label curMaxI = 0;
const Type* 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<Form, Type>&)")
<< "matrix is empty"
<< abort(FatalError);
// Return in error to keep compiler happy
return a[0][0];
}
}
template<class Form, class Type>
const Type& Foam::min(const Matrix<Form, Type>& a)
{
label nm = a.n_*a.m_;
if (nm)
{
label curMinI = 0;
const Type* 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<Form, Type>&)")
<< "matrix is empty"
<< abort(FatalError);
// Return in error to keep compiler happy
return a[0][0];
}
}
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
template<class Form, class Type>
Form Foam::operator-(const Matrix<Form, Type>& a)
{
Form na(a.n_, a.m_);
if (a.n_ && a.m_)
{
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++)
{
nav[i] = -av[i];
}
}
return na;
}
template<class Form, class Type>
Form Foam::operator+(const Matrix<Form, Type>& a, const Matrix<Form, Type>& b)
{
if (a.n_ != b.n_)
{
FatalErrorIn
(
"Matrix<Form, Type>::operator+(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
) << "attempted add matrices with different number of rows: "
<< a.n_ << ", " << b.n_
<< abort(FatalError);
}
if (a.m_ != b.m_)
{
FatalErrorIn
(
"Matrix<Form, Type>::operator+(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
) << "attempted add matrices with different number of columns: "
<< a.m_ << ", " << b.m_
<< abort(FatalError);
}
Form ab(a.n_, a.m_);
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++)
{
abv[i] = av[i] + bv[i];
}
return ab;
}
template<class Form, class Type>
Form Foam::operator-(const Matrix<Form, Type>& a, const Matrix<Form, Type>& b)
{
if (a.n_ != b.n_)
{
FatalErrorIn
(
"Matrix<Form, Type>::operator-(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
) << "attempted add matrices with different number of rows: "
<< a.n_ << ", " << b.n_
<< abort(FatalError);
}
if (a.m_ != b.m_)
{
FatalErrorIn
(
"Matrix<Form, Type>::operator-(const Matrix<Form, Type>&, const Matrix<Form, Type>&)"
) << "attempted add matrices with different number of columns: "
<< a.m_ << ", " << b.m_
<< abort(FatalError);
}
Form ab(a.n_, a.m_);
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++)
{
abv[i] = av[i] - bv[i];
}
return ab;
}
template<class Form, class Type>
Form Foam::operator*(const scalar s, const Matrix<Form, Type>& a)
{
Form sa(a.n_, a.m_);
if (a.n_ && a.m_)
{
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++)
{
sav[i] = s*av[i];
}
}
return sa;
}
// * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
#include "MatrixIO.C"
// ************************************************************************* //