Commit c14ee0ad authored by Henry Weller's avatar Henry Weller
Browse files

MatrixSpace: 2D (i-j) specialization of VectorSpace

Provides '(i, j)' element access and general forms of inner and outer
products, transpose etc. for square and rectangular VectorSpaces.

VectorSpaces default to be column-vectors as before whereas row-vectors
may be represented as 1xn MatrixSpaces.  In the future it may be
preferable to create a specializations of VectorSpace for column- and
maybe row-vectors but it would add complexity to MatrixSpace to handle
all the type combinations.

Tensor is now a 3x3 specialization of MatrixSpace.

Sub-block const and non-const access is provided via the
'.block<SubTensor, RowStart, ColStart>()' member functions.  Consistent
sub-block access is also provide for VectorSpace so that columns of
MatrixSpaces may be accessed and substituted.

These new classes will be used to create a more extensive set of
primitive vector and tensor types over the next few weeks.

Henry G. Weller
CFD Direct
parent e1d67b24
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::MatrixSpace
Description
Templated matrix space.
Template arguments are the Form the matrix space will be used to create,
the type of the elements and the number of rows and columns of the matrix.
SourceFiles
MatrixSpaceI.H
SeeAlso
Foam::VectorSpace
\*---------------------------------------------------------------------------*/
#ifndef MatrixSpace_H
#define MatrixSpace_H
#include "VectorSpace.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class MatrixSpace Declaration
\*---------------------------------------------------------------------------*/
template<class Form, class Cmpt, direction Nrows, direction Ncols>
class MatrixSpace
:
public VectorSpace<Form, Cmpt, Nrows*Ncols>
{
public:
//- MatrixSpace type
typedef MatrixSpace<Form, Cmpt, Nrows, Ncols> msType;
// Member constants
static const direction nRows = Nrows;
static const direction nCols = Ncols;
// Static member functions
//- Return the number of rows
static direction m()
{
return Nrows;
}
//- Return the number of columns
static direction n()
{
return Ncols;
}
//- Return the identity matrix for square matrix spaces
inline static msType identity();
// Sub-Block Classes
//- Const sub-block type
template<class SubTensor, direction BRowStart, direction BColStart>
class ConstBlock
{
//- Reference to parent matrix
const msType& matrix_;
public:
static const direction nRows = SubTensor::nRows;
static const direction nCols = SubTensor::nCols;
//- Return the number of rows in the block
static direction m()
{
return nRows;
}
//- Return the number of columns in the block
static direction n()
{
return nCols;
}
//- Construct for the given matrix
inline ConstBlock(const msType& matrix);
//- (i, j) const element access operator
inline const Cmpt& operator()
(
const direction i,
const direction j
) const;
};
//- Sub-block type
template
<
class SubTensor,
direction BRowStart,
direction BColStart
>
class Block
{
//- Reference to parent matrix
msType& matrix_;
public:
static const direction nRows = SubTensor::nRows;
static const direction nCols = SubTensor::nCols;
//- Return the number of rows in the block
static direction m()
{
return nRows;
}
//- Return the number of columns in the block
static direction n()
{
return nCols;
}
//- Construct for the given matrix
inline Block(msType& matrix);
//- Assignment to a matrix
template<class Form2>
inline void operator=
(
const MatrixSpace
<
Form2,
Cmpt,
SubTensor::nRows,
SubTensor::nCols
>& matrix
);
//- Assignment to a column vector
template<class VSForm>
inline void operator=
(
const VectorSpace<VSForm, Cmpt, SubTensor::nRows>& v
);
//- (i, j) const element access operator
inline const Cmpt& operator()
(
const direction i,
const direction j
) const;
//- (i, j) element access operator
inline Cmpt& operator()(const direction i, const direction j);
};
// Constructors
//- Construct null
inline MatrixSpace();
//- Construct initialized to zero
inline explicit MatrixSpace(const Foam::zero);
//- Construct as copy of a VectorSpace with the same size
template<class Form2, class Cmpt2>
inline explicit MatrixSpace
(
const VectorSpace<Form2, Cmpt2, Nrows*Ncols>&
);
//- Construct from a block of another matrix space
template
<
template<class, direction, direction> class Block2,
direction BRowStart,
direction BColStart
>
inline MatrixSpace
(
const Block2<Form, BRowStart, BColStart>& block
);
//- Construct from Istream
MatrixSpace(Istream&);
// Member Functions
//- Fast const element access using compile-time addressing
template<direction Row, direction Col>
inline const Cmpt& elmt() const;
//- Fast element access using compile-time addressing
template<direction Row, direction Col>
inline Cmpt& elmt();
// Const element access functions for a 3x3
// Compile-time errors are generated for inappropriate use
inline const Cmpt& xx() const;
inline const Cmpt& xy() const;
inline const Cmpt& xz() const;
inline const Cmpt& yx() const;
inline const Cmpt& yy() const;
inline const Cmpt& yz() const;
inline const Cmpt& zx() const;
inline const Cmpt& zy() const;
inline const Cmpt& zz() const;
// Element access functions for a 3x3
// Compile-time errors are generated for inappropriate use
inline Cmpt& xx();
inline Cmpt& xy();
inline Cmpt& xz();
inline Cmpt& yx();
inline Cmpt& yy();
inline Cmpt& yz();
inline Cmpt& zx();
inline Cmpt& zy();
inline Cmpt& zz();
//- Return the transpose of the matrix
inline typename typeOfTranspose<Cmpt, Form>::type T() const;
//- Return a const sub-block corresponding to the specified type
// starting at the specified row and column
template<class SubTensor, direction BRowStart, direction BColStart>
inline ConstBlock<SubTensor, BRowStart, BColStart> block() const;
//- Return a sub-block corresponding to the specified type
// starting at the specified row and column
template<class SubTensor, direction BRowStart, direction BColStart>
inline Block<SubTensor, BRowStart, BColStart> block();
//- (i, j) const element access operator
inline const Cmpt& operator()
(
const direction& row,
const direction& col
) const;
//- (i, j) element access operator
inline Cmpt& operator()(const direction& row, const direction& col);
// Member Operators
//- Assignment to zero
inline void operator=(const Foam::zero);
//- Assignment to a block of another matrix space
template
<
template<class, direction, direction> class Block2,
direction BRowStart,
direction BColStart
>
inline void operator=
(
const Block2<Form, BRowStart, BColStart>& block
);
//- Inner product with a compatible square matrix
template<class Form2>
inline void operator&=
(
const MatrixSpace<Form, Cmpt, Ncols, Ncols>& matrix
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "MatrixSpaceI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "StaticAssert.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::MatrixSpace()
{}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::MatrixSpace
(
const Foam::zero z
)
:
MatrixSpace::vsType(z)
{}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
template<class Form2, class Cmpt2>
inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::MatrixSpace
(
const VectorSpace<Form2, Cmpt2, Nrows*Ncols>& vs
)
:
MatrixSpace::vsType(vs)
{}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
template
<
template<class, Foam::direction, Foam::direction> class Block2,
Foam::direction BRowStart,
Foam::direction BColStart
>
inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::MatrixSpace
(
const Block2<Form, BRowStart, BColStart>& block
)
{
for (direction i=0; i<Nrows; ++i)
{
for (direction j=0; j<Ncols; ++j)
{
operator()(i, j) = block(i, j);
}
}
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::MatrixSpace(Istream& is)
:
MatrixSpace::vsType(is)
{}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::
ConstBlock<SubTensor, BRowStart, BColStart>::
ConstBlock(const msType& matrix)
:
matrix_(matrix)
{
StaticAssert(msType::nRows >= BRowStart + nRows);
StaticAssert(msType::nCols >= BColStart + nCols);
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::
Block<SubTensor, BRowStart, BColStart>::
Block(msType& matrix)
:
matrix_(matrix)
{
StaticAssert(msType::nRows >= BRowStart + nRows);
StaticAssert(msType::nCols >= BColStart + nCols);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
template<Foam::direction Row, Foam::direction Col>
inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::elmt() const
{
StaticAssert(Row < Nrows && Col < Ncols);
return this->v_[Row*Ncols + Col];
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
template<Foam::direction Row, Foam::direction Col>
inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::elmt()
{
StaticAssert(Row < Nrows && Col < Ncols);
return this->v_[Row*Ncols + Col];
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xx() const
{
return elmt<0, 0>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xx()
{
return elmt<0, 0>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xy() const
{
return elmt<0,1>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xy()
{
return elmt<0,1>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xz() const
{
return elmt<0,2>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xz()
{
return elmt<0,2>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yx() const
{
return elmt<1,0>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yx()
{
return elmt<1,0>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yy() const
{
return elmt<1,1>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yy()
{
return elmt<1,1>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yz() const
{
return elmt<1,2>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yz()
{
return elmt<1,2>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zx() const
{
return elmt<2,0>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zx()
{
return elmt<2,0>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zy() const
{
return elmt<2,1>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zy()
{
return elmt<2,1>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zz() const
{
return elmt<2,2>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zz()
{
return elmt<2,2>();
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>
Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::identity()
{
StaticAssert(Nrows == Ncols);
msType result((Foam::zero()));
for (direction i=0; i<Ncols; ++i)
{
result(i, i) = 1;
}
return result;
}
template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
inline typename Foam::typeOfTranspose<Cmpt, Form>::type
Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::T() const
{
typename typeOfTranspose<Cmpt, Form>::type result;
for (direction i=0; i<Nrows; ++i)
{
for (direction j=0; j<Ncols; ++j)