mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
the type it will become as a template argument. Brought everything into line with this change.
434 lines
9.1 KiB
C
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"
|
|
|
|
// ************************************************************************* //
|