Feature: Comulative release fixes. Author: Hrvoje Jasak. Merge: Hrvoje Jasak.

This commit is contained in:
Hrvoje Jasak 2015-08-24 20:52:54 +01:00
commit 3944983064
41 changed files with 2806 additions and 367 deletions

View file

@ -1,5 +1,5 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lmeshTools \ -lmeshTools

View file

@ -2,4 +2,4 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude -I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lmeshTools \ -lmeshTools

View file

@ -4,4 +4,4 @@ EXE_INC = \
EXE_LIBS = \ EXE_LIBS = \
-lmeshTools \ -lmeshTools \
-ledgeMesh \ -ledgeMesh

View file

@ -1,6 +1,6 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/cfdTools/general/lnInclude \ -I$(LIB_SRC)/cfdTools/general/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lmeshTools \ -lmeshTools

View file

@ -2,4 +2,6 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude -I$(LIB_SRC)/surfMesh/lnInclude
EXE_LIBS = -lmeshTools -lsurfMesh EXE_LIBS = \
-lmeshTools \
-lsurfMesh

View file

@ -2,4 +2,6 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude -I$(LIB_SRC)/surfMesh/lnInclude
EXE_LIBS = -lmeshTools -lsurfMesh EXE_LIBS = \
-lmeshTools \
-lsurfMesh

View file

@ -2,4 +2,6 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude -I$(LIB_SRC)/surfMesh/lnInclude
EXE_LIBS = -lmeshTools -lsurfMesh EXE_LIBS = \
-lmeshTools \
-lsurfMesh

View file

@ -1,6 +1,5 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lmeshTools \ -lmeshTools

View file

@ -2,4 +2,4 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude -I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lmeshTools \ -lmeshTools

View file

@ -2,4 +2,4 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
EXE_LIBS = \ EXE_LIBS = \
-lmeshTools \ -lmeshTools

View file

@ -2,4 +2,4 @@ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude -I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lmeshTools \ -lmeshTools

View file

@ -1,5 +1,5 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lmeshTools \ -lmeshTools

View file

@ -3,4 +3,3 @@ EXE_INC = \
EXE_LIBS = \ EXE_LIBS = \
-lmeshTools -lmeshTools

View file

@ -1,5 +1,5 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lmeshTools \ -lmeshTools

View file

@ -68,8 +68,8 @@ reconstruct
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
inv(surfaceSum(sqr(mesh.Sf())/mesh.magSf())) mesh,
& surfaceSum((mesh.Sf()/mesh.magSf())*ssf), ssf.dimensions()/dimArea,
zeroGradientFvPatchField<GradType>::typeName zeroGradientFvPatchField<GradType>::typeName
) )
); );
@ -87,9 +87,14 @@ reconstruct
GeometricField<GradType, fvPatchField, volMesh> fluxTimesNormal = GeometricField<GradType, fvPatchField, volMesh> fluxTimesNormal =
surfaceSum((mesh.Sf()/mesh.magSf())*ssf); surfaceSum((mesh.Sf()/mesh.magSf())*ssf);
// Note: hinv inverse must be used to stabilise the inverse on bad meshes
// HJ, 19/Aug/2015
reconField.internalField() = reconField.internalField() =
( (
inv(surfaceSum(sqr(mesh.Sf())/mesh.magSf())().internalField()) hinv
(
surfaceSum(sqr(mesh.Sf())/mesh.magSf())().internalField()
)
& fluxTimesNormal.internalField() & fluxTimesNormal.internalField()
); );

View file

@ -689,6 +689,11 @@ matrices/blockLduMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/blockGaussSeidelP
matrices/blockLduMatrix/BlockLduPrecons/BlockCholeskyPrecon/scalarBlockCholeskyPrecon.C matrices/blockLduMatrix/BlockLduPrecons/BlockCholeskyPrecon/scalarBlockCholeskyPrecon.C
matrices/blockLduMatrix/BlockLduPrecons/BlockCholeskyPrecon/tensorBlockCholeskyPrecon.C matrices/blockLduMatrix/BlockLduPrecons/BlockCholeskyPrecon/tensorBlockCholeskyPrecon.C
matrices/blockLduMatrix/BlockLduPrecons/BlockCholeskyPrecon/blockCholeskyPrecons.C matrices/blockLduMatrix/BlockLduPrecons/BlockCholeskyPrecon/blockCholeskyPrecons.C
matrices/blockLduMatrix/BlockLduPrecons/BlockDiagCholeskyPrecon/scalarBlockDiagCholeskyPrecon.C
matrices/blockLduMatrix/BlockLduPrecons/BlockDiagCholeskyPrecon/tensorBlockDiagCholeskyPrecon.C
matrices/blockLduMatrix/BlockLduPrecons/BlockDiagCholeskyPrecon/blockDiagCholeskyPrecons.C
matrices/blockLduMatrix/BlockLduPrecons/BlockAmgPrecon/blockAmgPrecons.C matrices/blockLduMatrix/BlockLduPrecons/BlockAmgPrecon/blockAmgPrecons.C
matrices/blockLduMatrix/BlockLduSmoothers/BlockLduSmoother/blockLduSmoothers.C matrices/blockLduMatrix/BlockLduSmoothers/BlockLduSmoother/blockLduSmoothers.C

View file

@ -143,7 +143,7 @@ void multiply
#define UNARY_OPERATOR(op, opFunc) \ #define UNARY_OPERATOR(op, opFunc) \
\ \
template<class Type> \ template<class Type> \
void opFunc \ void opFunc \
( \ ( \
CoeffField<Type>& f, \ CoeffField<Type>& f, \
const CoeffField<Type>& f1 \ const CoeffField<Type>& f1 \
@ -176,7 +176,7 @@ void opFunc \
} \ } \
\ \
template<class Type> \ template<class Type> \
tmp<CoeffField<Type> > operator op \ tmp<CoeffField<Type> > operator op \
( \ ( \
const CoeffField<Type>& f1 \ const CoeffField<Type>& f1 \
) \ ) \
@ -187,7 +187,7 @@ tmp<CoeffField<Type> > operator op \
} \ } \
\ \
template<class Type> \ template<class Type> \
tmp<CoeffField<Type> > operator op \ tmp<CoeffField<Type> > operator op \
( \ ( \
const tmp<CoeffField<Type> >& tf1 \ const tmp<CoeffField<Type> >& tf1 \
) \ ) \
@ -205,7 +205,7 @@ UNARY_OPERATOR(-, negate)
#define BINARY_OPERATOR_FF(Type1, Type2, op, opFunc) \ #define BINARY_OPERATOR_FF(Type1, Type2, op, opFunc) \
\ \
template<class Type> \ template<class Type> \
tmp<Field<Type> > operator op \ tmp<Field<Type> > operator op \
( \ ( \
const CoeffField<Type1>& f1, \ const CoeffField<Type1>& f1, \
const Type2& f2 \ const Type2& f2 \
@ -218,7 +218,7 @@ tmp<Field<Type> > operator op \
\ \
\ \
template<class Type> \ template<class Type> \
tmp<Field<Type> > operator op \ tmp<Field<Type> > operator op \
( \ ( \
const CoeffField<Type1>& f1, \ const CoeffField<Type1>& f1, \
const Field<Type2>& f2 \ const Field<Type2>& f2 \
@ -231,7 +231,7 @@ tmp<Field<Type> > operator op \
\ \
\ \
template<class Type> \ template<class Type> \
tmp<Field<Type> > operator op \ tmp<Field<Type> > operator op \
( \ ( \
const Field<Type2>& f1, \ const Field<Type2>& f1, \
const CoeffField<Type1>& f2 \ const CoeffField<Type1>& f2 \
@ -244,7 +244,7 @@ tmp<Field<Type> > operator op \
#define BINARY_OPERATOR_FTR(Type1, Type2, op, opFunc) \ #define BINARY_OPERATOR_FTR(Type1, Type2, op, opFunc) \
template<class Type> \ template<class Type> \
tmp<Field<Type> > operator op \ tmp<Field<Type> > operator op \
( \ ( \
const CoeffField<Type1>& f1, \ const CoeffField<Type1>& f1, \
const tmp<Field<Type2> >& tf2 \ const tmp<Field<Type2> >& tf2 \
@ -257,7 +257,7 @@ tmp<Field<Type> > operator op \
#define BINARY_OPERATOR_FT(Type1, Type2, op, opFunc) \ #define BINARY_OPERATOR_FT(Type1, Type2, op, opFunc) \
template<class Type> \ template<class Type> \
tmp<Field<Type> > operator op \ tmp<Field<Type> > operator op \
( \ ( \
const Field<Type1>& f1, \ const Field<Type1>& f1, \
const tmp<CoeffField<Type2> >& tf2 \ const tmp<CoeffField<Type2> >& tf2 \
@ -270,7 +270,7 @@ tmp<Field<Type> > operator op \
#define BINARY_OPERATOR_TRF(Type1, Type2, op, opFunc) \ #define BINARY_OPERATOR_TRF(Type1, Type2, op, opFunc) \
template<class Type> \ template<class Type> \
tmp<Field<Type> > operator op \ tmp<Field<Type> > operator op \
( \ ( \
const tmp<CoeffField<Type1> >& tf1, \ const tmp<CoeffField<Type1> >& tf1, \
const Field<Type2>& f2 \ const Field<Type2>& f2 \
@ -283,7 +283,7 @@ tmp<Field<Type> > operator op \
#define BINARY_OPERATOR_TF(Type1, Type2, op, opFunc) \ #define BINARY_OPERATOR_TF(Type1, Type2, op, opFunc) \
template<class Type> \ template<class Type> \
tmp<Field<Type> > operator op \ tmp<Field<Type> > operator op \
( \ ( \
const tmp<CoeffField<Type1> >& tf1, \ const tmp<CoeffField<Type1> >& tf1, \
const Field<Type2>& f2 \ const Field<Type2>& f2 \
@ -296,7 +296,7 @@ tmp<Field<Type> > operator op \
#define BINARY_OPERATOR_TRT(Type1, Type2, op, opFunc) \ #define BINARY_OPERATOR_TRT(Type1, Type2, op, opFunc) \
template<class Type> \ template<class Type> \
tmp<Field<Type> > operator op \ tmp<Field<Type> > operator op \
( \ ( \
const tmp<CoeffField<Type1> >& tf1, \ const tmp<CoeffField<Type1> >& tf1, \
const tmp<Field<Type2> >& tf2 \ const tmp<Field<Type2> >& tf2 \
@ -310,7 +310,7 @@ tmp<Field<Type> > operator op \
#define BINARY_OPERATOR_TTR(Type1, Type2, op, opFunc) \ #define BINARY_OPERATOR_TTR(Type1, Type2, op, opFunc) \
template<class Type> \ template<class Type> \
tmp<Field<Type> > operator op \ tmp<Field<Type> > operator op \
( \ ( \
const tmp<Field<Type1> >& tf1, \ const tmp<Field<Type1> >& tf1, \
const tmp<CoeffField<Type2> >& tf2 \ const tmp<CoeffField<Type2> >& tf2 \

View file

@ -37,7 +37,10 @@ namespace Foam
/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */
template<class Type> template<class Type>
tmp<DecoupledCoeffField<Type> > inv(const DecoupledCoeffField<Type>& f); tmp<DecoupledCoeffField<Type> > inv
(
const DecoupledCoeffField<Type>& f
);
template<class Type> template<class Type>

View file

@ -181,7 +181,7 @@ void GGIInterpolation<MasterPatch, SlavePatch>::findNeighbours3D
scalar tmpValue = Foam::magSqr(bbSlave.max() - bbSlave.min())/4.0; scalar tmpValue = Foam::magSqr(bbSlave.max() - bbSlave.min())/4.0;
// We will compare squared distances, so save the sqrt() if value > 1.0. // We compare squared distances, so save the sqrt() if value > 1.0.
if (tmpValue < 1.0) if (tmpValue < 1.0)
{ {
// Take the sqrt, otherwise, we underestimate the radius // Take the sqrt, otherwise, we underestimate the radius
@ -566,7 +566,6 @@ void GGIInterpolation<MasterPatch, SlavePatch>::findNeighboursBBOctree
} }
// Projects a list of points onto a plane located at planeOrig, // Projects a list of points onto a plane located at planeOrig,
// oriented along planeNormal. Return the projected points in a // oriented along planeNormal. Return the projected points in a
// pointField, and the normal distance of each points from the // pointField, and the normal distance of each points from the

View file

@ -220,6 +220,9 @@ void Foam::BlockCholeskyPrecon<Type>::calcPreconDiag()
} }
} }
} }
// Invert the diagonal
preconDiag_ = inv(preconDiag_);
} }
@ -250,12 +253,6 @@ void Foam::BlockCholeskyPrecon<Type>::diagMultiply
upper[coeffI] upper[coeffI]
); );
} }
// Invert the diagonal for future use
forAll (dDiag, i)
{
dDiag[i] = mult.inverse(dDiag[i]);
}
} }
@ -286,12 +283,6 @@ void Foam::BlockCholeskyPrecon<Type>::diagMultiplyCoeffT
upper[coeffI] upper[coeffI]
); );
} }
// Invert the diagonal for future use
forAll (dDiag, i)
{
dDiag[i] = mult.inverse(dDiag[i]);
}
} }
@ -323,12 +314,6 @@ void Foam::BlockCholeskyPrecon<Type>::diagMultiply
upper[coeffI] upper[coeffI]
); );
} }
// Invert the diagonal for future use
forAll (dDiag, i)
{
dDiag[i] = mult.inverse(dDiag[i]);
}
} }

View file

@ -126,6 +126,11 @@ void Foam::BlockCholeskyPrecon<Type>::calcDecoupledPreconDiag()
} }
} }
} }
// Invert the diagonal
// Note: since square diag type does not exist, simple inversion
// covers all cases
preconDiag_ = inv(preconDiag_);
} }

View file

@ -0,0 +1,235 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 3.2
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
BlockDiagCholeskyPrecon
Description
Incomplete Cholesky preconditioning with no fill-in,
using the diagonal-of-diagonal for ILU decomposition.
Currently broken
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
BlockDiagCholeskyPrecon.C
BlockDiagCholeskyPreconDecoupled.C
\*---------------------------------------------------------------------------*/
#ifndef BlockDiagCholeskyPrecon_H
#define BlockDiagCholeskyPrecon_H
#include "BlockLduPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockDiagCholeskyPrecon Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockDiagCholeskyPrecon
:
public BlockLduPrecon<Type>
{
// Private Data
//- Preconditioned diagonal
mutable CoeffField<Type> preconDiag_;
//- Off-diag part of diagonal
CoeffField<Type> LUDiag_;
//- Temporary space for updated decoupled source
// Initialised with zero size and resized on first use
mutable Field<Type> bPlusLU_;
// Private Member Functions
//- Disallow default bitwise copy construct
BlockDiagCholeskyPrecon(const BlockDiagCholeskyPrecon&);
//- Disallow default bitwise assignment
void operator=(const BlockDiagCholeskyPrecon&);
//- Precondition the diagonal
void calcPreconDiag();
// Diagonal multiplication, symmetric matrix
template<class DiagType, class ULType>
void diagMultiply
(
Field<DiagType>& dDiag,
const Field<ULType>& upper
);
//- Diagonal multiplication with transpose upper square coeff
// for the symmetric matrix
template<class DiagType, class ULType>
void diagMultiplyCoeffT
(
Field<DiagType>& dDiag,
const Field<ULType>& upper
);
//- Diagonal multiplication, asymmetric matrix
template<class DiagType, class ULType>
void diagMultiply
(
Field<DiagType>& dDiag,
const Field<ULType>& lower,
const Field<ULType>& upper
);
//- ILU multiplication, symmetric matrix
template<class DiagType, class ULType>
void ILUmultiply
(
Field<Type>& x,
const Field<DiagType>& dDiag,
const Field<ULType>& upper,
const Field<Type>& b
) const;
//- ILU multiplication, with transpose upper square coeff
// for a symmetric matrix
template<class DiagType, class ULType>
void ILUmultiplyCoeffT
(
Field<Type>& x,
const Field<DiagType>& dDiag,
const Field<ULType>& upper,
const Field<Type>& b
) const;
//- ILU multiplication, asymmetric matrix
template<class DiagType, class ULType>
void ILUmultiply
(
Field<Type>& x,
const Field<DiagType>& dDiag,
const Field<ULType>& lower,
const Field<ULType>& upper,
const Field<Type>& b
) const;
//- ILU multiplication transposed asymmetric matrix
template<class DiagType, class ULType>
void ILUmultiplyTranspose
(
Field<Type>& x,
const Field<DiagType>& dDiag,
const Field<ULType>& lower,
const Field<ULType>& upper,
const Field<Type>& b
) const;
// Decoupled operations, used in template specialisation
//- Precondition the diagonal, decoupled version
void calcDecoupledPreconDiag();
//- Execute preconditioning, decoupled version
void decoupledPrecondition
(
Field<Type>& x,
const Field<Type>& b
) const;
//- Execute preconditioning with matrix transpose,
// decoupled version
void decoupledPreconditionT
(
Field<Type>& xT,
const Field<Type>& bT
) const;
public:
//- Runtime type information
TypeName("Cholesky");
// Constructors
//- Construct from matrix for smoother use
BlockDiagCholeskyPrecon
(
const BlockLduMatrix<Type>& matrix
);
//- Construct from components
BlockDiagCholeskyPrecon
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
);
// Destructor
virtual ~BlockDiagCholeskyPrecon();
// Member Functions
//- Execute preconditioning
virtual void precondition
(
Field<Type>& x,
const Field<Type>& b
) const;
//- Execute preconditioning with matrix transpose
virtual void preconditionT
(
Field<Type>& xT,
const Field<Type>& bT
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "BlockDiagCholeskyPrecon.C"
# include "BlockDiagCholeskyPreconDecoupled.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,332 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 3.2
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "BlockDiagCholeskyPrecon.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::BlockDiagCholeskyPrecon<Type>::calcDecoupledPreconDiag()
{
typedef CoeffField<Type> TypeCoeffField;
// Note: Assuming lower and upper triangle have the same active type
if (this->matrix_.symmetric())
{
const TypeCoeffField& UpperCoeff = this->matrix_.upper();
if (preconDiag_.activeType() == blockCoeffBase::SCALAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
diagMultiply
(
preconDiag_.asScalar(),
UpperCoeff.asScalar()
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
diagMultiply
(
preconDiag_.asLinear(),
UpperCoeff.asLinear()
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::LINEAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
diagMultiply
(
preconDiag_.asLinear(),
UpperCoeff.asScalar()
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
diagMultiply
(
preconDiag_.asLinear(),
UpperCoeff.asLinear()
);
}
}
}
else // Asymmetric matrix
{
const TypeCoeffField& LowerCoeff = this->matrix_.lower();
const TypeCoeffField& UpperCoeff = this->matrix_.upper();
if (preconDiag_.activeType() == blockCoeffBase::SCALAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
diagMultiply
(
preconDiag_.asScalar(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar()
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
diagMultiply
(
preconDiag_.asLinear(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear()
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::LINEAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
diagMultiply
(
preconDiag_.asLinear(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar()
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
diagMultiply
(
preconDiag_.asLinear(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear()
);
}
}
}
// Invert the diagonal
// Note: since square diag type does not exist, simple inversion
// covers all cases
preconDiag_ = inv(preconDiag_);
}
template<class Type>
void Foam::BlockDiagCholeskyPrecon<Type>::decoupledPrecondition
(
Field<Type>& x,
const Field<Type>& b
) const
{
typedef CoeffField<Type> TypeCoeffField;
// Note: Assuming lower and upper triangle have the same active type
if (this->matrix_.symmetric())
{
const TypeCoeffField& UpperCoeff = this->matrix_.upper();
if (preconDiag_.activeType() == blockCoeffBase::SCALAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
ILUmultiply
(
x,
preconDiag_.asScalar(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
ILUmultiply
(
x,
preconDiag_.asScalar(),
UpperCoeff.asLinear(),
b
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::LINEAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
ILUmultiply
(
x,
preconDiag_.asLinear(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
ILUmultiply
(
x,
preconDiag_.asLinear(),
UpperCoeff.asLinear(),
b
);
}
}
}
else // Asymmetric matrix
{
const TypeCoeffField& LowerCoeff = this->matrix_.lower();
const TypeCoeffField& UpperCoeff = this->matrix_.upper();
if (preconDiag_.activeType() == blockCoeffBase::SCALAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
ILUmultiply
(
x,
preconDiag_.asScalar(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
ILUmultiply
(
x,
preconDiag_.asScalar(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear(),
b
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::LINEAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
ILUmultiply
(
x,
preconDiag_.asLinear(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
ILUmultiply
(
x,
preconDiag_.asLinear(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear(),
b
);
}
}
}
}
template<class Type>
void Foam::BlockDiagCholeskyPrecon<Type>::decoupledPreconditionT
(
Field<Type>& xT,
const Field<Type>& bT
) const
{
typedef CoeffField<Type> TypeCoeffField;
// Note: Assuming lower and upper triangle have the same active type
if (this->matrix_.symmetric())
{
precondition(xT, bT);
}
else // Asymmetric matrix
{
const TypeCoeffField& LowerCoeff = this->matrix_.lower();
const TypeCoeffField& UpperCoeff = this->matrix_.upper();
if (preconDiag_.activeType() == blockCoeffBase::SCALAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
ILUmultiplyTranspose
(
xT,
preconDiag_.asScalar(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
ILUmultiplyTranspose
(
xT,
preconDiag_.asScalar(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear(),
bT
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::LINEAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
ILUmultiplyTranspose
(
xT,
preconDiag_.asLinear(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
ILUmultiplyTranspose
(
xT,
preconDiag_.asLinear(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear(),
bT
);
}
}
}
}
// ************************************************************************* //

View file

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 3.2
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "blockLduMatrices.H"
#include "blockLduPrecons.H"
#include "blockDiagCholeskyPrecons.H"
#include "addToRunTimeSelectionTable.H"
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makeBlockPrecons(blockDiagCholeskyPrecon);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 3.2
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
BlockDiagCholeskyPrecon
Description
Typedefs for Incomplete Cholesky preconditioning with no fill-in,
using the diagonal-of-diagonal for ILU decomposition.
Currently broken
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
blockDiagCholeskyPrecons.C
\*---------------------------------------------------------------------------*/
#ifndef blockDiagCholeskyPrecons_H
#define blockDiagCholeskyPrecons_H
#include "scalarBlockDiagCholeskyPrecon.H"
#include "tensorBlockDiagCholeskyPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockDiagCholeskyPrecon<scalar> blockDiagCholeskyPreconScalar;
typedef BlockDiagCholeskyPrecon<vector> blockDiagCholeskyPreconVector;
typedef BlockDiagCholeskyPrecon<tensor> blockDiagCholeskyPreconTensor;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,199 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 3.2
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockDiagCholeskyPrecon_H
#define scalarBlockDiagCholeskyPrecon_H
#include "BlockDiagCholeskyPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockDiagCholeskyPrecon<scalar>::calcPreconDiag()
{
// Precondition the diagonal
if (matrix_.symmetric())
{
const unallocLabelList& upperAddr = matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = matrix_.lduAddr().lowerAddr();
// Get off-diagonal matrix coefficients
const scalarField& upper = matrix_.upper();
forAll (upper, coeffI)
{
preconDiag_[upperAddr[coeffI]] -=
sqr(upper[coeffI])/preconDiag_[lowerAddr[coeffI]];
}
}
else if (matrix_.asymmetric())
{
const unallocLabelList& upperAddr = matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = matrix_.lduAddr().lowerAddr();
// Get off-diagonal matrix coefficients
const scalarField& upper = matrix_.upper();
const scalarField& lower = matrix_.lower();
forAll (upper, coeffI)
{
preconDiag_[upperAddr[coeffI]] -=
upper[coeffI]*lower[coeffI]/preconDiag_[lowerAddr[coeffI]];
}
}
// Invert the diagonal for future use
forAll (preconDiag_, i)
{
preconDiag_[i] = 1.0/preconDiag_[i];
}
}
template<>
void Foam::BlockDiagCholeskyPrecon<scalar>::precondition
(
scalarField& x,
const scalarField& b
) const
{
forAll(x, i)
{
x[i] = b[i]*preconDiag_[i];
}
if (matrix_.symmetric())
{
const unallocLabelList& upperAddr = matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = matrix_.lduAddr().lowerAddr();
// Get off-diagonal matrix coefficients
const scalarField& upper = matrix_.upper();
forAll (upper, coeffI)
{
x[upperAddr[coeffI]] -=
preconDiag_[upperAddr[coeffI]]*
upper[coeffI]*x[lowerAddr[coeffI]];
}
forAllReverse (upper, coeffI)
{
x[lowerAddr[coeffI]] -=
preconDiag_[lowerAddr[coeffI]]*
upper[coeffI]*x[upperAddr[coeffI]];
}
}
else if (matrix_.asymmetric())
{
const unallocLabelList& upperAddr = matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = matrix_.lduAddr().lowerAddr();
const unallocLabelList& losortAddr = matrix_.lduAddr().losortAddr();
// Get off-diagonal matrix coefficients
const scalarField& upper = matrix_.upper();
const scalarField& lower = matrix_.lower();
label losortCoeff;
forAll (lower, coeffI)
{
losortCoeff = losortAddr[coeffI];
x[upperAddr[losortCoeff]] -=
preconDiag_[upperAddr[losortCoeff]]*
lower[losortCoeff]*x[lowerAddr[losortCoeff]];
}
forAllReverse (upper, coeffI)
{
x[lowerAddr[coeffI]] -=
preconDiag_[lowerAddr[coeffI]]*
upper[coeffI]*x[upperAddr[coeffI]];
}
}
}
template<>
void Foam::BlockDiagCholeskyPrecon<scalar>::preconditionT
(
scalarField& xT,
const scalarField& bT
) const
{
if (matrix_.symmetric())
{
precondition(xT, bT);
}
forAll(xT, i)
{
xT[i] = bT[i]*preconDiag_[i];
}
if (matrix_.asymmetric())
{
const unallocLabelList& upperAddr = matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = matrix_.lduAddr().lowerAddr();
const unallocLabelList& losortAddr = matrix_.lduAddr().losortAddr();
// Get off-diagonal matrix coefficients
const scalarField& upper = matrix_.upper();
const scalarField& lower = matrix_.lower();
label losortCoeff;
forAll (lower, coeffI)
{
xT[upperAddr[coeffI]] -=
preconDiag_[upperAddr[coeffI]]*
upper[coeffI]*xT[lowerAddr[coeffI]];
}
forAllReverse (upper, coeffI)
{
losortCoeff = losortAddr[coeffI];
xT[lowerAddr[losortCoeff]] -=
preconDiag_[lowerAddr[losortCoeff]]*
lower[losortCoeff]*xT[upperAddr[losortCoeff]];
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 3.2
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
BlockDiagCholeskyPrecon
Description
Template specialisation for scalar block Cholesky preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
scalarBlockDiagCholeskyPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockDiagCholeskyPrecon_H
#define scalarBlockDiagCholeskyPrecon_H
#include "BlockDiagCholeskyPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockDiagCholeskyPrecon<scalar>::calcPreconDiag();
template<>
void Foam::BlockDiagCholeskyPrecon<scalar>::precondition
(
scalarField& x,
const scalarField& b
) const;
template<>
void Foam::BlockDiagCholeskyPrecon<scalar>::preconditionT
(
scalarField& xT,
const scalarField& bT
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,76 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 3.2
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef tensorBlockDiagCholeskyPrecon_H
#define tensorBlockDiagCholeskyPrecon_H
#include "BlockDiagCholeskyPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockDiagCholeskyPrecon<tensor>::calcPreconDiag()
{
// Decoupled version
calcDecoupledPreconDiag();
}
template<>
void Foam::BlockDiagCholeskyPrecon<tensor>::precondition
(
tensorField& x,
const tensorField& b
) const
{
// Decoupled version
decoupledPrecondition(x, b);
}
template<>
void Foam::BlockDiagCholeskyPrecon<tensor>::preconditionT
(
tensorField& xT,
const tensorField& bT
) const
{
// Decoupled version
decoupledPreconditionT(xT, bT);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 3.2
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
BlockDiagCholeskyPrecon
Description
Template specialisation for tensor block Cholesky preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
tensorBlockDiagCholeskyPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef tensorBlockDiagCholeskyPrecon_H
#define tensorBlockDiagCholeskyPrecon_H
#include "BlockDiagCholeskyPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockDiagCholeskyPrecon<tensor>::calcPreconDiag();
template<>
void Foam::BlockDiagCholeskyPrecon<tensor>::precondition
(
tensorField& x,
const tensorField& b
) const;
template<>
void Foam::BlockDiagCholeskyPrecon<tensor>::preconditionT
(
tensorField& xT,
const tensorField& bT
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -34,6 +34,79 @@ Author
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::BlockGaussSeidelPrecon<Type>::calcInvDiag()
{
typedef CoeffField<Type> TypeCoeffField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
typedef typename TypeCoeffField::linearType valueType;
typedef typename TypeCoeffField::squareTypeField squareTypeField;
// Note: Cannot use inv since the square coefficient requires
// special treatment. HJ, 20/Aug/2015
// Get reference to diagonal
const TypeCoeffField& d = this->matrix_.diag();
if (d.activeType() == blockCoeffBase::SCALAR)
{
invDiag_.asScalar() = 1/d.asScalar();
}
else if (d.activeType() == blockCoeffBase::LINEAR)
{
invDiag_.asLinear() =
cmptDivide
(
linearTypeField(d.size(), pTraits<valueType>::one),
d.asLinear()
);
}
else if (d.activeType() == blockCoeffBase::SQUARE)
{
// For square diagonal invert diagonal only and store the rest
// info LUDiag coefficient. This avoids full inverse of the
// diagonal matrix. HJ, 20/Aug/2015
Info<< "Square diag inverse" << endl;
// Get reference to active diag
const squareTypeField& activeDiag = d.asSquare();
// Get reference to LU: remove diagonal from active diag
squareTypeField& luDiag = LUDiag_.asSquare();
linearTypeField lf(activeDiag.size());
// Take out the diagonal from the diag as a linear type
contractLinear(lf, activeDiag);
// Expand diagonal only to full square type and store into luDiag
expandLinear(luDiag, lf);
// Keep only off-diagonal in ldDiag.
// Note change of sign to avoid multiplication with -1 when moving
// to the other side. HJ, 20/Aug/2015
luDiag -= activeDiag;
// Inverse is the inverse of diagonal only
invDiag_.asLinear() =
cmptDivide
(
linearTypeField(lf.size(), pTraits<valueType>::one),
lf
);
}
else
{
FatalErrorIn
(
"void BlockGaussSeidelPrecon<Type>::calcInvDiag()"
) << "Problem with coefficient type morphing."
<< abort(FatalError);
}
}
// Block sweep, symmetric matrix // Block sweep, symmetric matrix
template<class Type> template<class Type>
template<class DiagType, class ULType> template<class DiagType, class ULType>
@ -46,7 +119,8 @@ void Foam::BlockGaussSeidelPrecon<Type>::BlockSweep
) const ) const
{ {
const unallocLabelList& u = this->matrix_.lduAddr().upperAddr(); const unallocLabelList& u = this->matrix_.lduAddr().upperAddr();
const unallocLabelList& ownStart = this->matrix_.lduAddr().ownerStartAddr(); const unallocLabelList& ownStart =
this->matrix_.lduAddr().ownerStartAddr();
const label nRows = ownStart.size() - 1; const label nRows = ownStart.size() - 1;
@ -155,7 +229,8 @@ void Foam::BlockGaussSeidelPrecon<Type>::BlockSweep
) const ) const
{ {
const unallocLabelList& u = this->matrix_.lduAddr().upperAddr(); const unallocLabelList& u = this->matrix_.lduAddr().upperAddr();
const unallocLabelList& ownStart = this->matrix_.lduAddr().ownerStartAddr(); const unallocLabelList& ownStart =
this->matrix_.lduAddr().ownerStartAddr();
const label nRows = ownStart.size() - 1; const label nRows = ownStart.size() - 1;
@ -247,6 +322,43 @@ void Foam::BlockGaussSeidelPrecon<Type>::BlockSweep
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::BlockGaussSeidelPrecon<Type>::BlockGaussSeidelPrecon
(
const BlockLduMatrix<Type>& matrix
)
:
BlockLduPrecon<Type>(matrix),
invDiag_(matrix.lduAddr().size()),
LUDiag_(matrix.lduAddr().size()),
bPlusLU_(),
bPrime_(matrix.lduAddr().size()),
nSweeps_(1)
{
calcInvDiag();
}
template<class Type>
Foam::BlockGaussSeidelPrecon<Type>::BlockGaussSeidelPrecon
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
)
:
BlockLduPrecon<Type>(matrix),
invDiag_(matrix.lduAddr().size()),
LUDiag_(matrix.lduAddr().size()),
bPlusLU_(),
bPrime_(matrix.lduAddr().size()),
nSweeps_(readLabel(dict.lookup("nSweeps")))
{
calcInvDiag();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
@ -260,14 +372,11 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
if (this->matrix_.diagonal()) if (this->matrix_.diagonal())
{ {
TypeCoeffField dDCoeff = inv(this->matrix_.diag()); multiply(x, invDiag_, b);
multiply(x, dDCoeff, b);
} }
else if (this->matrix_.symmetric()) else if (this->matrix_.symmetric())
{ {
TypeCoeffField dDCoeff = inv(this->matrix_.diag()); const TypeCoeffField& DiagCoeff = this->matrix_.diag();
const TypeCoeffField& UpperCoeff = this->matrix_.upper(); const TypeCoeffField& UpperCoeff = this->matrix_.upper();
// Note // Note
@ -279,16 +388,16 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
// to be enforced without the per-element if-condition, which // to be enforced without the per-element if-condition, which
// makes for ugly code. HJ, 19/May/2005 // makes for ugly code. HJ, 19/May/2005
//Note: Assuming lower and upper triangle have the same active type // Note: Assuming lower and upper triangle have the same active type
if (dDCoeff.activeType() == blockCoeffBase::SCALAR) if (DiagCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asScalar(), invDiag_.asScalar(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
b b
); );
@ -298,7 +407,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asScalar(), invDiag_.asScalar(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
b b
); );
@ -308,20 +417,20 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asScalar(), invDiag_.asScalar(),
UpperCoeff.asSquare(), UpperCoeff.asSquare(),
b b
); );
} }
} }
else if (dDCoeff.activeType() == blockCoeffBase::LINEAR) else if (DiagCoeff.activeType() == blockCoeffBase::LINEAR)
{ {
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asLinear(), invDiag_.asLinear(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
b b
); );
@ -331,7 +440,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asLinear(), invDiag_.asLinear(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
b b
); );
@ -341,42 +450,57 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asLinear(), invDiag_.asLinear(),
UpperCoeff.asSquare(), UpperCoeff.asSquare(),
b b
); );
} }
} }
else if (dDCoeff.activeType() == blockCoeffBase::SQUARE) else if (DiagCoeff.activeType() == blockCoeffBase::SQUARE)
{ {
// Add diag coupling to b
if (bPlusLU_.empty())
{
bPlusLU_.setSize(b.size(), pTraits<Type>::zero);
}
// Multiply overwrites bPlusLU_: no need to initialise
// Change of sign accounted via change of sign of bPlusLU_
// HJ, 20/Aug/2015
multiply(bPlusLU_, LUDiag_, x);
bPlusLU_ += b;
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
// Note linear diag inversed due to decoupling
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asSquare(), invDiag_.asLinear(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
b bPlusLU_
); );
} }
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR) else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{ {
// Note linear diag inversed due to decoupling
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asSquare(), invDiag_.asLinear(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
b bPlusLU_
); );
} }
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE) else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{ {
// Note linear diag inversed due to decoupling
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asSquare(), invDiag_.asLinear(),
UpperCoeff.asSquare(), UpperCoeff.asSquare(),
b bPlusLU_
); );
} }
} }
@ -395,8 +519,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
} }
else if (this->matrix_.asymmetric()) else if (this->matrix_.asymmetric())
{ {
TypeCoeffField dDCoeff = inv(this->matrix_.diag()); const TypeCoeffField& DiagCoeff = this->matrix_.diag();
const TypeCoeffField& LowerCoeff = this->matrix_.lower(); const TypeCoeffField& LowerCoeff = this->matrix_.lower();
const TypeCoeffField& UpperCoeff = this->matrix_.upper(); const TypeCoeffField& UpperCoeff = this->matrix_.upper();
@ -411,14 +534,14 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
//Note: Assuming lower and upper triangle have the same active type //Note: Assuming lower and upper triangle have the same active type
if (dDCoeff.activeType() == blockCoeffBase::SCALAR) if (DiagCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asScalar(), invDiag_.asScalar(),
LowerCoeff.asScalar(), LowerCoeff.asScalar(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
b b
@ -429,7 +552,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asScalar(), invDiag_.asScalar(),
LowerCoeff.asLinear(), LowerCoeff.asLinear(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
b b
@ -440,21 +563,21 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asScalar(), invDiag_.asScalar(),
LowerCoeff.asSquare(), LowerCoeff.asSquare(),
UpperCoeff.asSquare(), UpperCoeff.asSquare(),
b b
); );
} }
} }
else if (dDCoeff.activeType() == blockCoeffBase::LINEAR) else if (DiagCoeff.activeType() == blockCoeffBase::LINEAR)
{ {
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asLinear(), invDiag_.asLinear(),
LowerCoeff.asScalar(), LowerCoeff.asScalar(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
b b
@ -465,7 +588,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asLinear(), invDiag_.asLinear(),
LowerCoeff.asLinear(), LowerCoeff.asLinear(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
b b
@ -476,46 +599,61 @@ void Foam::BlockGaussSeidelPrecon<Type>::precondition
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asLinear(), invDiag_.asLinear(),
LowerCoeff.asSquare(), LowerCoeff.asSquare(),
UpperCoeff.asSquare(), UpperCoeff.asSquare(),
b b
); );
} }
} }
else if (dDCoeff.activeType() == blockCoeffBase::SQUARE) else if (DiagCoeff.activeType() == blockCoeffBase::SQUARE)
{ {
// Add diag coupling to b
if (bPlusLU_.empty())
{
bPlusLU_.setSize(b.size(), pTraits<Type>::zero);
}
// Multiply overwrites bPlusLU_: no need to initialise
// Change of sign accounted via change of sign of bPlusLU_
// HJ, 20/Aug/2015
multiply(bPlusLU_, LUDiag_, x);
bPlusLU_ += b;
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
// Note linear diag inversed due to decoupling
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asSquare(), invDiag_.asLinear(),
LowerCoeff.asScalar(), LowerCoeff.asScalar(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
b bPlusLU_
); );
} }
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR) else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{ {
// Note linear diag inversed due to decoupling
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asSquare(), invDiag_.asLinear(),
LowerCoeff.asLinear(), LowerCoeff.asLinear(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
b bPlusLU_
); );
} }
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE) else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{ {
// Note linear diag inversed due to decoupling
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asSquare(), invDiag_.asLinear(),
LowerCoeff.asSquare(), LowerCoeff.asSquare(),
UpperCoeff.asSquare(), UpperCoeff.asSquare(),
b bPlusLU_
); );
} }
} }
@ -558,14 +696,11 @@ void Foam::BlockGaussSeidelPrecon<Type>::preconditionT
if (this->matrix_.diagonal()) if (this->matrix_.diagonal())
{ {
TypeCoeffField dDCoeff = inv(this->matrix_.diag()); multiply(xT, invDiag_, bT);
multiply(xT, dDCoeff, bT);
} }
else if (this->matrix_.symmetric() || this->matrix_.asymmetric()) else if (this->matrix_.symmetric() || this->matrix_.asymmetric())
{ {
TypeCoeffField dDCoeff = inv(this->matrix_.diag()); const TypeCoeffField& DiagCoeff = this->matrix_.lower();
const TypeCoeffField& LowerCoeff = this->matrix_.lower(); const TypeCoeffField& LowerCoeff = this->matrix_.lower();
const TypeCoeffField& UpperCoeff = this->matrix_.upper(); const TypeCoeffField& UpperCoeff = this->matrix_.upper();
@ -580,7 +715,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::preconditionT
//Note: Assuming lower and upper triangle have the same active type //Note: Assuming lower and upper triangle have the same active type
if (dDCoeff.activeType() == blockCoeffBase::SCALAR) if (DiagCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
@ -588,7 +723,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::preconditionT
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asScalar(), invDiag_.asScalar(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
LowerCoeff.asScalar(), LowerCoeff.asScalar(),
bT bT
@ -600,7 +735,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::preconditionT
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asScalar(), invDiag_.asScalar(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
LowerCoeff.asLinear(), LowerCoeff.asLinear(),
bT bT
@ -612,14 +747,14 @@ void Foam::BlockGaussSeidelPrecon<Type>::preconditionT
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asScalar(), invDiag_.asScalar(),
UpperCoeff.asSquare(), UpperCoeff.asSquare(),
LowerCoeff.asSquare(), LowerCoeff.asSquare(),
bT bT
); );
} }
} }
else if (dDCoeff.activeType() == blockCoeffBase::LINEAR) else if (DiagCoeff.activeType() == blockCoeffBase::LINEAR)
{ {
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
@ -627,7 +762,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::preconditionT
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asLinear(), invDiag_.asLinear(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
LowerCoeff.asScalar(), LowerCoeff.asScalar(),
bT bT
@ -639,7 +774,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::preconditionT
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asLinear(), invDiag_.asLinear(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
LowerCoeff.asLinear(), LowerCoeff.asLinear(),
bT bT
@ -651,49 +786,64 @@ void Foam::BlockGaussSeidelPrecon<Type>::preconditionT
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asLinear(), invDiag_.asLinear(),
UpperCoeff.asSquare(), UpperCoeff.asSquare(),
LowerCoeff.asSquare(), LowerCoeff.asSquare(),
bT bT
); );
} }
} }
else if (dDCoeff.activeType() == blockCoeffBase::SQUARE) else if (DiagCoeff.activeType() == blockCoeffBase::SQUARE)
{ {
// Add diag coupling to b
if (bPlusLU_.empty())
{
bPlusLU_.setSize(bT.size(), pTraits<Type>::zero);
}
// Multiply overwrites bPlusLU_: no need to initialise
// Change of sign accounted via change of sign of bPlusLU_
// HJ, 20/Aug/2015
multiply(bPlusLU_, LUDiag_, xT);
bPlusLU_ += bT;
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
// Transpose multiplication - swap lower and upper coeff arrays // Transpose multiplication - swap lower and upper coeff arrays
// Note linear diag inversed due to decoupling
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asSquare(), invDiag_.asLinear(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
LowerCoeff.asScalar(), LowerCoeff.asScalar(),
bT bPlusLU_
); );
} }
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR) else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{ {
// Transpose multiplication - swap lower and upper coeff arrays // Transpose multiplication - swap lower and upper coeff arrays
// Note linear diag inversed due to decoupling
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asSquare(), invDiag_.asLinear(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
LowerCoeff.asLinear(), LowerCoeff.asLinear(),
bT bPlusLU_
); );
} }
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE) else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{ {
// Transpose multiplication - swap lower and upper coeff arrays // Transpose multiplication - swap lower and upper coeff arrays
// Note linear diag inversed due to decoupling
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asSquare(), invDiag_.asLinear(),
UpperCoeff.asSquare(), UpperCoeff.asSquare(),
LowerCoeff.asSquare(), LowerCoeff.asSquare(),
bT bPlusLU_
); );
} }
} }

View file

@ -58,6 +58,16 @@ class BlockGaussSeidelPrecon
{ {
// Private Data // Private Data
//- Inverse of diagonal diagonal
CoeffField<Type> invDiag_;
//- Off-diag part of diagonal
CoeffField<Type> LUDiag_;
//- Temporary space for updated decoupled source
// Initialised with zero size and resized on first use
mutable Field<Type> bPlusLU_;
//- Temporary space for solution intermediate //- Temporary space for solution intermediate
mutable Field<Type> bPrime_; mutable Field<Type> bPrime_;
@ -74,6 +84,9 @@ class BlockGaussSeidelPrecon
void operator=(const BlockGaussSeidelPrecon&); void operator=(const BlockGaussSeidelPrecon&);
//- Calculate inverse diagonal
void calcInvDiag();
// Block Gauss-Seidel sweep, symetric matrix // Block Gauss-Seidel sweep, symetric matrix
template<class DiagType, class ULType> template<class DiagType, class ULType>
void BlockSweep void BlockSweep
@ -98,6 +111,9 @@ class BlockGaussSeidelPrecon
// Decoupled operations, used in template specialisation // Decoupled operations, used in template specialisation
//- Calculate inverse diagonal, decoupled version
void calcDecoupledInvDiag();
//- Execute preconditioning, decoupled version //- Execute preconditioning, decoupled version
void decoupledPrecondition void decoupledPrecondition
( (
@ -126,24 +142,14 @@ public:
BlockGaussSeidelPrecon BlockGaussSeidelPrecon
( (
const BlockLduMatrix<Type>& matrix const BlockLduMatrix<Type>& matrix
) );
:
BlockLduPrecon<Type>(matrix),
bPrime_(matrix.lduAddr().size()),
nSweeps_(1)
{}
//- Construct from components //- Construct from components
BlockGaussSeidelPrecon BlockGaussSeidelPrecon
( (
const BlockLduMatrix<Type>& matrix, const BlockLduMatrix<Type>& matrix,
const dictionary& dict const dictionary& dict
) );
:
BlockLduPrecon<Type>(matrix),
bPrime_(matrix.lduAddr().size()),
nSweeps_(readLabel(dict.lookup("nSweeps")))
{}
// Destructor // Destructor

View file

@ -34,6 +34,19 @@ Author
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::BlockGaussSeidelPrecon<Type>::calcDecoupledInvDiag()
{
// Get reference to diagonal and obtain inverse by casting
typedef CoeffField<Type> TypeCoeffField;
const TypeCoeffField& d = this->matrix_.diag();
const DecoupledCoeffField<Type>& dd = d;
invDiag_ = CoeffField<Type>(inv(dd)());
}
template<class Type> template<class Type>
void Foam::BlockGaussSeidelPrecon<Type>::decoupledPrecondition void Foam::BlockGaussSeidelPrecon<Type>::decoupledPrecondition
( (
@ -45,14 +58,17 @@ void Foam::BlockGaussSeidelPrecon<Type>::decoupledPrecondition
if (this->matrix_.diagonal()) if (this->matrix_.diagonal())
{ {
TypeCoeffField dDCoeff = inv(this->matrix_.diag()); if (invDiag_.activeType() == blockCoeffBase::SCALAR)
{
multiply(x, dDCoeff, b); x = invDiag_.asScalar()*b;
}
else if (invDiag_.activeType() == blockCoeffBase::LINEAR)
{
x = cmptMultiply(invDiag_.asLinear(), b);
}
} }
else if (this->matrix_.symmetric() || this->matrix_.asymmetric()) else if (this->matrix_.symmetric() || this->matrix_.asymmetric())
{ {
TypeCoeffField dDCoeff = inv(this->matrix_.diag());
const TypeCoeffField& LowerCoeff = this->matrix_.lower(); const TypeCoeffField& LowerCoeff = this->matrix_.lower();
const TypeCoeffField& UpperCoeff = this->matrix_.upper(); const TypeCoeffField& UpperCoeff = this->matrix_.upper();
@ -65,16 +81,16 @@ void Foam::BlockGaussSeidelPrecon<Type>::decoupledPrecondition
// to be enforced without the per-element if-condition, which // to be enforced without the per-element if-condition, which
// makes for ugly code. HJ, 19/May/2005 // makes for ugly code. HJ, 19/May/2005
//Note: Assuming lower and upper triangle have the same active type // Note: Assuming lower and upper triangle have the same active type
if (dDCoeff.activeType() == blockCoeffBase::SCALAR) if (invDiag_.activeType() == blockCoeffBase::SCALAR)
{ {
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asScalar(), invDiag_.asScalar(),
LowerCoeff.asScalar(), LowerCoeff.asScalar(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
b b
@ -85,21 +101,21 @@ void Foam::BlockGaussSeidelPrecon<Type>::decoupledPrecondition
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asScalar(), invDiag_.asScalar(),
LowerCoeff.asLinear(), LowerCoeff.asLinear(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
b b
); );
} }
} }
else if (dDCoeff.activeType() == blockCoeffBase::LINEAR) else if (invDiag_.activeType() == blockCoeffBase::LINEAR)
{ {
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asLinear(), invDiag_.asLinear(),
LowerCoeff.asScalar(), LowerCoeff.asScalar(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
b b
@ -110,7 +126,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::decoupledPrecondition
BlockSweep BlockSweep
( (
x, x,
dDCoeff.asLinear(), invDiag_.asLinear(),
LowerCoeff.asLinear(), LowerCoeff.asLinear(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
b b
@ -156,14 +172,17 @@ void Foam::BlockGaussSeidelPrecon<Type>::decoupledPreconditionT
if (this->matrix_.diagonal()) if (this->matrix_.diagonal())
{ {
TypeCoeffField dDCoeff = inv(this->matrix_.diag()); if (invDiag_.activeType() == blockCoeffBase::SCALAR)
{
multiply(xT, dDCoeff, bT); xT = invDiag_.asScalar()*bT;
}
else if (invDiag_.activeType() == blockCoeffBase::LINEAR)
{
xT = cmptMultiply(invDiag_.asLinear(), bT);
}
} }
else if (this->matrix_.symmetric() || this->matrix_.asymmetric()) else if (this->matrix_.symmetric() || this->matrix_.asymmetric())
{ {
TypeCoeffField dDCoeff = inv(this->matrix_.diag());
const TypeCoeffField& LowerCoeff = this->matrix_.lower(); const TypeCoeffField& LowerCoeff = this->matrix_.lower();
const TypeCoeffField& UpperCoeff = this->matrix_.upper(); const TypeCoeffField& UpperCoeff = this->matrix_.upper();
@ -176,9 +195,9 @@ void Foam::BlockGaussSeidelPrecon<Type>::decoupledPreconditionT
// to be enforced without the per-element if-condition, which // to be enforced without the per-element if-condition, which
// makes for ugly code. HJ, 19/May/2005 // makes for ugly code. HJ, 19/May/2005
//Note: Assuming lower and upper triangle have the same active type // Note: Assuming lower and upper triangle have the same active type
if (dDCoeff.activeType() == blockCoeffBase::SCALAR) if (invDiag_.activeType() == blockCoeffBase::SCALAR)
{ {
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
@ -186,7 +205,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::decoupledPreconditionT
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asScalar(), invDiag_.asScalar(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
LowerCoeff.asScalar(), LowerCoeff.asScalar(),
bT bT
@ -198,14 +217,14 @@ void Foam::BlockGaussSeidelPrecon<Type>::decoupledPreconditionT
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asScalar(), invDiag_.asScalar(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
LowerCoeff.asLinear(), LowerCoeff.asLinear(),
bT bT
); );
} }
} }
else if (dDCoeff.activeType() == blockCoeffBase::LINEAR) else if (invDiag_.activeType() == blockCoeffBase::LINEAR)
{ {
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR) if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{ {
@ -213,7 +232,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::decoupledPreconditionT
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asLinear(), invDiag_.asLinear(),
UpperCoeff.asScalar(), UpperCoeff.asScalar(),
LowerCoeff.asScalar(), LowerCoeff.asScalar(),
bT bT
@ -225,7 +244,7 @@ void Foam::BlockGaussSeidelPrecon<Type>::decoupledPreconditionT
BlockSweep BlockSweep
( (
xT, xT,
dDCoeff.asLinear(), invDiag_.asLinear(),
UpperCoeff.asLinear(), UpperCoeff.asLinear(),
LowerCoeff.asLinear(), LowerCoeff.asLinear(),
bT bT

View file

@ -44,38 +44,11 @@ namespace Foam
{ {
template<> template<>
template<> void BlockGaussSeidelPrecon<scalar>::calcInvDiag()
void BlockGaussSeidelPrecon<scalar>::BlockSweep
(
Field<scalar>& x,
const Field<scalar>& dD,
const Field<scalar>& upper,
const Field<scalar>& b
) const
{ {
FatalErrorIn // Direct inversion of diagonal is sufficient, as the diagonal
( // is linear. HJ, 20/Aug/2015
"BlockGaussSeidelPrecon<scalar>::BlockSweep(...)" invDiag_ = inv(this->matrix_.diag());
) << "Function not implemented for Type=scalar. " << endl
<< abort(FatalError);
}
template<>
template<>
void BlockGaussSeidelPrecon<scalar>::BlockSweep
(
Field<scalar>& x,
const Field<scalar>& dD,
const Field<scalar>& upper,
const Field<scalar>& lower,
const Field<scalar>& b
) const
{
FatalErrorIn
(
"BlockGaussSeidelPrecon<scalar>::BlockSweep(...)"
) << "Function not implemented for Type=scalar. " << endl
<< abort(FatalError);
} }

View file

@ -43,25 +43,7 @@ namespace Foam
{ {
template<> template<>
template<> void BlockGaussSeidelPrecon<scalar>::calcInvDiag();
void BlockGaussSeidelPrecon<scalar>::BlockSweep
(
scalarField& x,
const scalarField& dD,
const scalarField& upper,
const scalarField& b
) const;
template<>
template<>
void BlockGaussSeidelPrecon<scalar>::BlockSweep
(
scalarField& x,
const scalarField& dD,
const scalarField& upper,
const scalarField& lower,
const scalarField& b
) const;
template<> template<>

View file

@ -47,39 +47,9 @@ namespace Foam
{ {
template<> template<>
template<> void BlockGaussSeidelPrecon<tensor>::calcInvDiag()
void BlockGaussSeidelPrecon<tensor>::BlockSweep
(
Field<tensor>& x,
const Field<tensor>& dD,
const Field<tensor>& upper,
const Field<tensor>& b
) const
{ {
FatalErrorIn calcDecoupledInvDiag();
(
"Foam::BlockGaussSeidelPrecon<tensor>::BlockSweep(...)"
) << "Function not implemented for Type=tensor. " << endl
<< abort(FatalError);
}
template<>
template<>
void BlockGaussSeidelPrecon<tensor>::BlockSweep
(
Field<tensor>& x,
const Field<tensor>& dD,
const Field<tensor>& upper,
const Field<tensor>& lower,
const Field<tensor>& b
) const
{
FatalErrorIn
(
"Foam::BlockGaussSeidelPrecon<tensor>::BlockSweep(...)"
) << "Function not implemented for Type=tensor. " << endl
<< abort(FatalError);
} }
@ -91,7 +61,7 @@ void BlockGaussSeidelPrecon<tensor>::precondition
) const ) const
{ {
// Decoupled version // Decoupled version
// decoupledPrecondition(x, b); decoupledPrecondition(x, b);
} }
@ -103,7 +73,7 @@ void BlockGaussSeidelPrecon<tensor>::preconditionT
) const ) const
{ {
// Decoupled version // Decoupled version
// decoupledPreconditionT(xT, bT); decoupledPreconditionT(xT, bT);
} }

View file

@ -43,26 +43,7 @@ namespace Foam
{ {
template<> template<>
template<> void BlockGaussSeidelPrecon<tensor>::calcInvDiag();
void BlockGaussSeidelPrecon<tensor>::BlockSweep
(
Field<tensor>& x,
const Field<tensor>& dD,
const Field<tensor>& upper,
const Field<tensor>& b
) const;
template<>
template<>
void BlockGaussSeidelPrecon<tensor>::BlockSweep
(
Field<tensor>& x,
const Field<tensor>& dD,
const Field<tensor>& upper,
const Field<tensor>& lower,
const Field<tensor>& b
) const;
template<> template<>

View file

@ -40,6 +40,7 @@ const DiagTensorN<Cmpt, length> DiagTensorN<Cmpt, length>::zero(0);
template <class Cmpt, int length> template <class Cmpt, int length>
const DiagTensorN<Cmpt, length> DiagTensorN<Cmpt, length>::one(1); const DiagTensorN<Cmpt, length> DiagTensorN<Cmpt, length>::one(1);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct null // Construct null
@ -63,7 +64,12 @@ inline DiagTensorN<Cmpt, length>::DiagTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline DiagTensorN<Cmpt, length>::DiagTensorN(const Cmpt& tx) inline DiagTensorN<Cmpt, length>::DiagTensorN(const Cmpt& tx)
{ {
VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::eqOpS(*this, tx, eqOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::eqOpS
(
*this,
tx,
eqOp<Cmpt>()
);
} }
@ -94,80 +100,154 @@ inline DiagTensorN<Cmpt, length> DiagTensorN<Cmpt, length>::T() const
//- Assign to a SphericalTensorN //- Assign to a SphericalTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline void DiagTensorN<Cmpt, length>::operator=(const SphericalTensorN<Cmpt, length>& st) inline void DiagTensorN<Cmpt, length>::operator=
(
const SphericalTensorN<Cmpt, length>& st
)
{ {
const Cmpt& s = st.v_[0]; const Cmpt& s = st.v_[0];
VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::eqOpS(*this, s, eqOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::eqOpS
(
*this,
s,
eqOp<Cmpt>()
);
} }
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
//- Addition of DiagTensorN and DiagTensorN //- Addition of DiagTensorN and DiagTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline DiagTensorN<Cmpt,length> inline DiagTensorN<Cmpt, length>
operator+(const DiagTensorN<Cmpt,length>& dt1, const DiagTensorN<Cmpt,length>& dt2) operator+
(
const DiagTensorN<Cmpt, length>& dt1,
const DiagTensorN<Cmpt, length>& dt2
)
{ {
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<DiagTensorN<Cmpt,length>::nComponents,0>::op(res, dt1, dt2, plusOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::op
(
res,
dt1,
dt2,
plusOp<Cmpt>()
);
return res; return res;
} }
//- Addition of DiagTensorN and SphericalTensorN //- Addition of DiagTensorN and SphericalTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline DiagTensorN<Cmpt,length> inline DiagTensorN<Cmpt, length>
operator+(const DiagTensorN<Cmpt,length>& dt1, const SphericalTensorN<Cmpt,length>& st2) operator+
(
const DiagTensorN<Cmpt, length>& dt1,
const SphericalTensorN<Cmpt, length>& st2
)
{ {
const Cmpt& s = st2.v_[0]; const Cmpt& s = st2.v_[0];
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<DiagTensorN<Cmpt,length>::nComponents,0>::opVS(res, dt1, s, plusOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opVS
(
res,
dt1,
s,
plusOp<Cmpt>()
);
return res; return res;
} }
//- Addition of SphericalTensorN and DiagTensorN //- Addition of SphericalTensorN and DiagTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline DiagTensorN<Cmpt,length> inline DiagTensorN<Cmpt, length>
operator+(const SphericalTensorN<Cmpt,length>& st1, const DiagTensorN<Cmpt,length>& dt2) operator+
(
const SphericalTensorN<Cmpt, length>& st1,
const DiagTensorN<Cmpt, length>& dt2
)
{ {
const Cmpt& s = st1.v_[0]; const Cmpt& s = st1.v_[0];
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<DiagTensorN<Cmpt,length>::nComponents,0>::opSV(res, s, dt2, plusOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opSV
(
res,
s,
dt2,
plusOp<Cmpt>()
);
return res; return res;
} }
//- Subtraction of DiagTensorN and DiagTensorN //- Subtraction of DiagTensorN and DiagTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline DiagTensorN<Cmpt,length> inline DiagTensorN<Cmpt, length>
operator-(const DiagTensorN<Cmpt,length>& dt1, const DiagTensorN<Cmpt,length>& dt2) operator-
(
const DiagTensorN<Cmpt, length>& dt1,
const DiagTensorN<Cmpt, length>& dt2
)
{ {
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<DiagTensorN<Cmpt,length>::nComponents,0>::op(res, dt1, dt2, minusOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::op
(
res,
dt1,
dt2,
minusOp<Cmpt>()
);
return res; return res;
} }
//- Subtraction of DiagTensorN and SphericalTensorN //- Subtraction of DiagTensorN and SphericalTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline DiagTensorN<Cmpt,length> inline DiagTensorN<Cmpt, length>
operator-(const DiagTensorN<Cmpt,length>& dt1, const SphericalTensorN<Cmpt,length>& st2) operator-
(
const DiagTensorN<Cmpt, length>& dt1,
const SphericalTensorN<Cmpt, length>& st2
)
{ {
const Cmpt& s = st2.v_[0]; const Cmpt& s = st2.v_[0];
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<DiagTensorN<Cmpt,length>::nComponents,0>::opVS(res, dt1, s, minusOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opVS
(
res,
dt1,
s,
minusOp<Cmpt>()
);
return res; return res;
} }
//- Subtraction of SphericalTensorN and DiagTensorN //- Subtraction of SphericalTensorN and DiagTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline DiagTensorN<Cmpt,length> inline DiagTensorN<Cmpt, length>
operator-(const SphericalTensorN<Cmpt,length>& st1, const DiagTensorN<Cmpt,length>& dt2) operator-
(
const SphericalTensorN<Cmpt, length>& st1,
const DiagTensorN<Cmpt, length>& dt2
)
{ {
const Cmpt& s = st1.v_[0]; const Cmpt& s = st1.v_[0];
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<DiagTensorN<Cmpt,length>::nComponents,0>::opSV(res, s, dt2, minusOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opSV
(
res,
s,
dt2,
minusOp<Cmpt>()
);
return res; return res;
} }
@ -176,10 +256,21 @@ operator-(const SphericalTensorN<Cmpt,length>& st1, const DiagTensorN<Cmpt,lengt
template <class Cmpt, int length> template <class Cmpt, int length>
inline typename inline typename
innerProduct<DiagTensorN<Cmpt, length>, DiagTensorN<Cmpt, length> >::type innerProduct<DiagTensorN<Cmpt, length>, DiagTensorN<Cmpt, length> >::type
operator&(const DiagTensorN<Cmpt, length>& dt1, const DiagTensorN<Cmpt, length>& dt2) operator&
(
const DiagTensorN<Cmpt, length>& dt1,
const DiagTensorN<Cmpt, length>& dt2
)
{ {
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::op(res, dt1, dt2, multiplyOp<Cmpt>()); VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::op
(
res,
dt1,
dt2,
multiplyOp<Cmpt>()
);
return res; return res;
} }
@ -188,11 +279,22 @@ operator&(const DiagTensorN<Cmpt, length>& dt1, const DiagTensorN<Cmpt, length>&
template <class Cmpt, int length> template <class Cmpt, int length>
inline typename inline typename
innerProduct<SphericalTensorN<Cmpt, length>, DiagTensorN<Cmpt, length> >::type innerProduct<SphericalTensorN<Cmpt, length>, DiagTensorN<Cmpt, length> >::type
operator&(const SphericalTensorN<Cmpt, length>& st1, const DiagTensorN<Cmpt, length>& dt2) operator&
(
const SphericalTensorN<Cmpt, length>& st1,
const DiagTensorN<Cmpt, length>& dt2
)
{ {
const Cmpt& s = st1.v_[0]; const Cmpt& s = st1.v_[0];
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opSV(res, s, dt2, multiplyOp<Cmpt>()); VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opSV
(
res,
s,
dt2,
multiplyOp<Cmpt>()
);
return res; return res;
} }
@ -201,11 +303,22 @@ operator&(const SphericalTensorN<Cmpt, length>& st1, const DiagTensorN<Cmpt, len
template <class Cmpt, int length> template <class Cmpt, int length>
inline typename inline typename
innerProduct<DiagTensorN<Cmpt, length>, SphericalTensorN<Cmpt, length> >::type innerProduct<DiagTensorN<Cmpt, length>, SphericalTensorN<Cmpt, length> >::type
operator&(const DiagTensorN<Cmpt, length>& dt1, const SphericalTensorN<Cmpt, length>& st2) operator&
(
const DiagTensorN<Cmpt, length>& dt1,
const SphericalTensorN<Cmpt, length>& st2
)
{ {
const Cmpt& s = st2.v_[0]; const Cmpt& s = st2.v_[0];
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opVS(res, dt1, s, multiplyOp<Cmpt>()); VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opVS
(
res,
dt1,
s,
multiplyOp<Cmpt>()
);
return res; return res;
} }
@ -214,10 +327,21 @@ operator&(const DiagTensorN<Cmpt, length>& dt1, const SphericalTensorN<Cmpt, len
template <class Cmpt, int length> template <class Cmpt, int length>
inline typename inline typename
innerProduct<DiagTensorN<Cmpt, length>, VectorN<Cmpt, length> >::type innerProduct<DiagTensorN<Cmpt, length>, VectorN<Cmpt, length> >::type
operator&(const DiagTensorN<Cmpt, length>& dt, const VectorN<Cmpt, length>& v) operator&
(
const DiagTensorN<Cmpt, length>& dt,
const VectorN<Cmpt, length>& v
)
{ {
VectorN<Cmpt, length> res; VectorN<Cmpt, length> res;
VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opVV(res, dt, v, multiplyOp<Cmpt>()); VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opVV
(
res,
dt,
v,
multiplyOp<Cmpt>()
);
return res; return res;
} }
@ -227,10 +351,21 @@ operator&(const DiagTensorN<Cmpt, length>& dt, const VectorN<Cmpt, length>& v)
template <class Cmpt, int length> template <class Cmpt, int length>
inline typename inline typename
innerProduct<VectorN<Cmpt, length>, DiagTensorN<Cmpt, length> >::type innerProduct<VectorN<Cmpt, length>, DiagTensorN<Cmpt, length> >::type
operator&(const VectorN<Cmpt, length>& v, const DiagTensorN<Cmpt, length>& dt) operator&
(
const VectorN<Cmpt, length>& v,
const DiagTensorN<Cmpt, length>& dt
)
{ {
VectorN<Cmpt, length> res; VectorN<Cmpt, length> res;
VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opVV(res, v, dt, multiplyOp<Cmpt>()); VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opVV
(
res,
v,
dt,
multiplyOp<Cmpt>()
);
return res; return res;
} }
@ -241,53 +376,99 @@ inline DiagTensorN<Cmpt, length>
operator/(const scalar s, const DiagTensorN<Cmpt, length>& dt) operator/(const scalar s, const DiagTensorN<Cmpt, length>& dt)
{ {
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opSV(res, s, dt, divideOp3<Cmpt, scalar, Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opSV
(
res,
s,
dt,
divideOp3<Cmpt, scalar, Cmpt>()
);
return res; return res;
} }
//- Inner Product of a VectorN by an inverse diagonalTensor //- Inner Product of a VectorN by an inverse diagonalTensor
template <class Cmpt, int length> template <class Cmpt, int length>
inline VectorN<Cmpt,length> inline VectorN<Cmpt, length>
operator/(const VectorN<Cmpt,length>& v, const DiagTensorN<Cmpt,length>& dt) operator/(const VectorN<Cmpt, length>& v, const DiagTensorN<Cmpt, length>& dt)
{ {
VectorN<Cmpt, length> res(v); VectorN<Cmpt, length> res(v);
VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::eqOp(res, dt, divideEqOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::eqOp
(
res,
dt,
divideEqOp<Cmpt>()
);
return res; return res;
} }
//- Inner Product of a DiagTensorN and an inverse DiagTensorN //- Inner Product of a DiagTensorN and an inverse DiagTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline DiagTensorN<Cmpt,length> inline DiagTensorN<Cmpt, length>
operator/(const DiagTensorN<Cmpt,length>& dt1, const DiagTensorN<Cmpt,length>& dt2) operator/
(
const DiagTensorN<Cmpt, length>& dt1,
const DiagTensorN<Cmpt, length>& dt2
)
{ {
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::op(res, dt1, dt2, divideOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::op
(
res,
dt1,
dt2,
divideOp<Cmpt>()
);
return res; return res;
} }
//- Inner Product of a SphericalTensorN and an inverse DiagTensorN //- Inner Product of a SphericalTensorN and an inverse DiagTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline DiagTensorN<Cmpt,length> inline DiagTensorN<Cmpt, length>
operator/(const SphericalTensorN<Cmpt,length>& st1, const DiagTensorN<Cmpt,length>& dt2) operator/
(
const SphericalTensorN<Cmpt, length>& st1,
const DiagTensorN<Cmpt, length>& dt2
)
{ {
const Cmpt& s = st1.v_[0]; const Cmpt& s = st1.v_[0];
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opSV(res, s, dt2, divideOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opSV
(
res,
s,
dt2,
divideOp<Cmpt>()
);
return res; return res;
} }
//- Inner Product of a DiagTensorN and an inverse SphericalTensorN //- Inner Product of a DiagTensorN and an inverse SphericalTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline DiagTensorN<Cmpt,length> inline DiagTensorN<Cmpt, length>
operator/(const DiagTensorN<Cmpt,length>& dt1, const SphericalTensorN<Cmpt,length>& st2) operator/
(
const DiagTensorN<Cmpt, length>& dt1,
const SphericalTensorN<Cmpt, length>& st2
)
{ {
const Cmpt& s = st2.v_[0]; const Cmpt& s = st2.v_[0];
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opVS(res, dt1, s, divideOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opVS
(
res,
dt1,
s,
divideOp<Cmpt>()
);
return res; return res;
} }
@ -297,7 +478,14 @@ template <class Cmpt, int length>
inline DiagTensorN<Cmpt, length> inv(const DiagTensorN<Cmpt, length>& dt) inline DiagTensorN<Cmpt, length> inv(const DiagTensorN<Cmpt, length>& dt)
{ {
DiagTensorN<Cmpt, length> res; DiagTensorN<Cmpt, length> res;
VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opSV(res, 1.0, dt, divideOp<Cmpt>()); VectorSpaceOps<DiagTensorN<Cmpt, length>::nComponents,0>::opSV
(
res,
1.0,
dt,
divideOp<Cmpt>()
);
return res; return res;
} }

View file

@ -79,14 +79,16 @@ inline SphericalTensorN<Cmpt, length>::SphericalTensorN(Istream& is)
//- Return diagonal tensor diagonal //- Return diagonal tensor diagonal
template <class Cmpt, int length> template <class Cmpt, int length>
inline SphericalTensorN<Cmpt, length> SphericalTensorN<Cmpt, length>::diag() const inline SphericalTensorN<Cmpt, length>
SphericalTensorN<Cmpt, length>::diag() const
{ {
return *this; return *this;
} }
//- Return spherical tensor transpose //- Return spherical tensor transpose
template <class Cmpt, int length> template <class Cmpt, int length>
inline SphericalTensorN<Cmpt, length> SphericalTensorN<Cmpt, length>::T() const inline SphericalTensorN<Cmpt, length>
SphericalTensorN<Cmpt, length>::T() const
{ {
return *this; return *this;
} }
@ -111,8 +113,12 @@ inline SphericalTensorN<Cmpt, length> transform
//- Addition of SphericalTensorN and SphericalTensorN //- Addition of SphericalTensorN and SphericalTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline SphericalTensorN<Cmpt,length> inline SphericalTensorN<Cmpt, length>
operator+(const SphericalTensorN<Cmpt,length>& st1, const SphericalTensorN<Cmpt,length>& st2) operator+
(
const SphericalTensorN<Cmpt, length>& st1,
const SphericalTensorN<Cmpt, length>& st2
)
{ {
return SphericalTensorN<Cmpt, length>(st1.v_[0] + st2.v_[0]); return SphericalTensorN<Cmpt, length>(st1.v_[0] + st2.v_[0]);
} }
@ -120,8 +126,12 @@ operator+(const SphericalTensorN<Cmpt,length>& st1, const SphericalTensorN<Cmpt,
//- Subtraction of SphericalTensorN and SphericalTensorN //- Subtraction of SphericalTensorN and SphericalTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline SphericalTensorN<Cmpt,length> inline SphericalTensorN<Cmpt, length>
operator-(const SphericalTensorN<Cmpt,length>& st1, const SphericalTensorN<Cmpt,length>& st2) operator-
(
const SphericalTensorN<Cmpt, length>& st1,
const SphericalTensorN<Cmpt, length>& st2
)
{ {
return SphericalTensorN<Cmpt, length>(st1.v_[0] - st2.v_[0]); return SphericalTensorN<Cmpt, length>(st1.v_[0] - st2.v_[0]);
} }
@ -130,8 +140,16 @@ operator-(const SphericalTensorN<Cmpt,length>& st1, const SphericalTensorN<Cmpt,
//- Inner-product between spherical tensor and spherical tensor //- Inner-product between spherical tensor and spherical tensor
template <class Cmpt, int length> template <class Cmpt, int length>
inline typename inline typename
innerProduct<SphericalTensorN<Cmpt, length>, SphericalTensorN<Cmpt, length> >::type innerProduct
operator&(const SphericalTensorN<Cmpt, length>& st1, const SphericalTensorN<Cmpt, length>& st2) <
SphericalTensorN<Cmpt, length>,
SphericalTensorN<Cmpt, length>
>::type
operator&
(
const SphericalTensorN<Cmpt, length>& st1,
const SphericalTensorN<Cmpt, length>& st2
)
{ {
return SphericalTensorN<Cmpt, length>(st1.v_[0]*st2.v_[0]); return SphericalTensorN<Cmpt, length>(st1.v_[0]*st2.v_[0]);
} }
@ -141,11 +159,22 @@ operator&(const SphericalTensorN<Cmpt, length>& st1, const SphericalTensorN<Cmpt
template <class Cmpt, int length> template <class Cmpt, int length>
inline typename inline typename
innerProduct<SphericalTensorN<Cmpt, length>, VectorN<Cmpt, length> >::type innerProduct<SphericalTensorN<Cmpt, length>, VectorN<Cmpt, length> >::type
operator&(const SphericalTensorN<Cmpt, length>& st, const VectorN<Cmpt, length>& v) operator&
(
const SphericalTensorN<Cmpt, length>& st,
const VectorN<Cmpt, length>& v
)
{ {
const Cmpt& s = st.v_[0]; const Cmpt& s = st.v_[0];
VectorN<Cmpt, length> res; VectorN<Cmpt, length> res;
VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opSV(res, s, v, multiplyOp<Cmpt>()); VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opSV
(
res,
s,
v,
multiplyOp<Cmpt>()
);
return res; return res;
} }
@ -154,11 +183,22 @@ operator&(const SphericalTensorN<Cmpt, length>& st, const VectorN<Cmpt, length>&
template <class Cmpt, int length> template <class Cmpt, int length>
inline typename inline typename
innerProduct<VectorN<Cmpt, length>, SphericalTensorN<Cmpt, length> >::type innerProduct<VectorN<Cmpt, length>, SphericalTensorN<Cmpt, length> >::type
operator&(const VectorN<Cmpt, length>& v, const SphericalTensorN<Cmpt, length>& st) operator&
(
const VectorN<Cmpt, length>& v,
const SphericalTensorN<Cmpt, length>& st
)
{ {
const Cmpt& s = st.v_[0]; const Cmpt& s = st.v_[0];
VectorN<Cmpt, length> res; VectorN<Cmpt, length> res;
VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opVS(res, v, s, multiplyOp<Cmpt>()); VectorSpaceOps<VectorN<Cmpt, length>::nComponents,0>::opVS
(
res,
v,
s,
multiplyOp<Cmpt>()
);
return res; return res;
} }
@ -183,8 +223,12 @@ operator/(const scalar s, const SphericalTensorN<Cmpt, length>& st)
//- Inner Product of a VectorN by an inverse SphericalTensorN //- Inner Product of a VectorN by an inverse SphericalTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline VectorN<Cmpt,length> inline VectorN<Cmpt, length>
operator/(const VectorN<Cmpt,length>& v, const SphericalTensorN<Cmpt,length>& st) operator/
(
const VectorN<Cmpt, length>& v,
const SphericalTensorN<Cmpt, length>& st
)
{ {
return v/st.v_[0]; return v/st.v_[0];
} }
@ -192,8 +236,12 @@ operator/(const VectorN<Cmpt,length>& v, const SphericalTensorN<Cmpt,length>& st
//- Inner Product of a SphericalTensorN and an inverse SphericalTensorN //- Inner Product of a SphericalTensorN and an inverse SphericalTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline SphericalTensorN<Cmpt,length> inline SphericalTensorN<Cmpt, length>
operator/(const SphericalTensorN<Cmpt,length>& st1, const SphericalTensorN<Cmpt,length>& st2) operator/
(
const SphericalTensorN<Cmpt, length>& st1,
const SphericalTensorN<Cmpt, length>& st2
)
{ {
return SphericalTensorN<Cmpt, length>(st1.v_[0]/st2.v_[0]); return SphericalTensorN<Cmpt, length>(st1.v_[0]/st2.v_[0]);
} }
@ -201,7 +249,10 @@ operator/(const SphericalTensorN<Cmpt,length>& st1, const SphericalTensorN<Cmpt,
//- Return the inverse of a spherical tensor //- Return the inverse of a spherical tensor
template <class Cmpt, int length> template <class Cmpt, int length>
inline SphericalTensorN<Cmpt, length> inv(const SphericalTensorN<Cmpt, length>& st) inline SphericalTensorN<Cmpt, length> inv
(
const SphericalTensorN<Cmpt, length>& st
)
{ {
return SphericalTensorN<Cmpt, length>(pTraits<Cmpt>::one/st.v_[0]); return SphericalTensorN<Cmpt, length>(pTraits<Cmpt>::one/st.v_[0]);
} }
@ -209,7 +260,10 @@ inline SphericalTensorN<Cmpt, length> inv(const SphericalTensorN<Cmpt, length>&
//- Return tensor diagonal //- Return tensor diagonal
template <class Cmpt, int length> template <class Cmpt, int length>
inline SphericalTensorN<Cmpt, length> diag(const SphericalTensorN<Cmpt, length>& st) inline SphericalTensorN<Cmpt, length> diag
(
const SphericalTensorN<Cmpt, length>& st
)
{ {
return st; return st;
} }
@ -258,7 +312,11 @@ public:
}; };
template<class Cmpt, int length> template<class Cmpt, int length>
class innerProduct<SphericalTensorN<Cmpt, length>, SphericalTensorN<Cmpt, length> > class innerProduct
<
SphericalTensorN<Cmpt, length>,
SphericalTensorN<Cmpt, length>
>
{ {
public: public:

View file

@ -483,11 +483,11 @@ operator*(const VectorN<Cmpt, length>& v1, const VectorN<Cmpt, length>& v2)
//- Addition of TensorN and TensorN //- Addition of TensorN and TensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator+(const TensorN<Cmpt,length>& t1, const TensorN<Cmpt,length>& t2) operator+(const TensorN<Cmpt, length>& t1, const TensorN<Cmpt, length>& t2)
{ {
TensorN<Cmpt,length> res; TensorN<Cmpt, length> res;
VectorSpaceOps<TensorN<Cmpt,length>::nComponents,0>::op VectorSpaceOps<TensorN<Cmpt, length>::nComponents,0>::op
( (
res, res,
t1, t1,
@ -501,8 +501,8 @@ operator+(const TensorN<Cmpt,length>& t1, const TensorN<Cmpt,length>& t2)
//- Addition of TensorN and DiagTensorN //- Addition of TensorN and DiagTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator+(const TensorN<Cmpt,length>& t1, const DiagTensorN<Cmpt,length>& dt2) operator+(const TensorN<Cmpt, length>& t1, const DiagTensorN<Cmpt, length>& dt2)
{ {
TensorN<Cmpt, length> result(t1); TensorN<Cmpt, length> result(t1);
@ -519,8 +519,8 @@ operator+(const TensorN<Cmpt,length>& t1, const DiagTensorN<Cmpt,length>& dt2)
//- Addition of DiagTensorN and TensorN //- Addition of DiagTensorN and TensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator+(const DiagTensorN<Cmpt,length>& dt1, const TensorN<Cmpt,length>& t2) operator+(const DiagTensorN<Cmpt, length>& dt1, const TensorN<Cmpt, length>& t2)
{ {
TensorN<Cmpt, length> result(t2); TensorN<Cmpt, length> result(t2);
@ -537,11 +537,11 @@ operator+(const DiagTensorN<Cmpt,length>& dt1, const TensorN<Cmpt,length>& t2)
//- Addition of TensorN and SphericalTensorN //- Addition of TensorN and SphericalTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator+ operator+
( (
const TensorN<Cmpt,length>& t1, const TensorN<Cmpt, length>& t1,
const SphericalTensorN<Cmpt,length>& st2 const SphericalTensorN<Cmpt, length>& st2
) )
{ {
TensorN<Cmpt, length> result(t1); TensorN<Cmpt, length> result(t1);
@ -560,11 +560,11 @@ operator+
//- Addition of SphericalTensorN and TensorN //- Addition of SphericalTensorN and TensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator+ operator+
( (
const SphericalTensorN<Cmpt,length>& st1, const SphericalTensorN<Cmpt, length>& st1,
const TensorN<Cmpt,length>& t2 const TensorN<Cmpt, length>& t2
) )
{ {
TensorN<Cmpt, length> result(t2); TensorN<Cmpt, length> result(t2);
@ -583,11 +583,11 @@ operator+
//- Subtraction of TensorN and TensorN //- Subtraction of TensorN and TensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator-(const TensorN<Cmpt,length>& t1, const TensorN<Cmpt,length>& t2) operator-(const TensorN<Cmpt, length>& t1, const TensorN<Cmpt, length>& t2)
{ {
TensorN<Cmpt,length> res; TensorN<Cmpt, length> res;
VectorSpaceOps<TensorN<Cmpt,length>::nComponents,0>::op VectorSpaceOps<TensorN<Cmpt, length>::nComponents,0>::op
( (
res, res,
t1, t1,
@ -601,8 +601,8 @@ operator-(const TensorN<Cmpt,length>& t1, const TensorN<Cmpt,length>& t2)
//- Subtraction of TensorN and DiagTensorN //- Subtraction of TensorN and DiagTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator-(const TensorN<Cmpt,length>& t1, const DiagTensorN<Cmpt,length>& dt2) operator-(const TensorN<Cmpt, length>& t1, const DiagTensorN<Cmpt, length>& dt2)
{ {
TensorN<Cmpt, length> result(t1); TensorN<Cmpt, length> result(t1);
@ -619,8 +619,8 @@ operator-(const TensorN<Cmpt,length>& t1, const DiagTensorN<Cmpt,length>& dt2)
//- Subtraction of DiagTensorN and TensorN //- Subtraction of DiagTensorN and TensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator-(const DiagTensorN<Cmpt,length>& dt1, const TensorN<Cmpt,length>& t2) operator-(const DiagTensorN<Cmpt, length>& dt1, const TensorN<Cmpt, length>& t2)
{ {
TensorN<Cmpt, length> result(-t2); TensorN<Cmpt, length> result(-t2);
@ -637,11 +637,11 @@ operator-(const DiagTensorN<Cmpt,length>& dt1, const TensorN<Cmpt,length>& t2)
//- Subtraction of TensorN and SphericalTensorN //- Subtraction of TensorN and SphericalTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator- operator-
( (
const TensorN<Cmpt,length>& t1, const TensorN<Cmpt, length>& t1,
const SphericalTensorN<Cmpt,length>& st2 const SphericalTensorN<Cmpt, length>& st2
) )
{ {
TensorN<Cmpt, length> result(t1); TensorN<Cmpt, length> result(t1);
@ -660,11 +660,11 @@ operator-
//- Subtraction of SphericalTensorN and TensorN //- Subtraction of SphericalTensorN and TensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator- operator-
( (
const SphericalTensorN<Cmpt,length>& st1, const SphericalTensorN<Cmpt, length>& st1,
const TensorN<Cmpt,length>& t2 const TensorN<Cmpt, length>& t2
) )
{ {
TensorN<Cmpt, length> result(-t2); TensorN<Cmpt, length> result(-t2);
@ -683,24 +683,24 @@ operator-
//- Division of a scalar by a TensorN //- Division of a scalar by a TensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator/(const scalar s, const TensorN<Cmpt,length>& t) operator/(const scalar s, const TensorN<Cmpt, length>& t)
{ {
return s*inv(t); return s*inv(t);
} }
//- Inner Product of a VectorN by an inverse TensorN //- Inner Product of a VectorN by an inverse TensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline VectorN<Cmpt,length> inline VectorN<Cmpt, length>
operator/(const VectorN<Cmpt,length>& v, const TensorN<Cmpt,length>& t) operator/(const VectorN<Cmpt, length>& v, const TensorN<Cmpt, length>& t)
{ {
return v & inv(t); return v & inv(t);
} }
//- Inner Product of a TensorN by an inverse TensorN //- Inner Product of a TensorN by an inverse TensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator/(const TensorN<Cmpt,length>& t1, const TensorN<Cmpt,length>& t2) operator/(const TensorN<Cmpt, length>& t1, const TensorN<Cmpt, length>& t2)
{ {
return t1 & inv(t2); return t1 & inv(t2);
} }
@ -708,8 +708,8 @@ operator/(const TensorN<Cmpt,length>& t1, const TensorN<Cmpt,length>& t2)
//- Inner Product of a DiagTensorN and an inverse TensorN //- Inner Product of a DiagTensorN and an inverse TensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator/(const DiagTensorN<Cmpt,length>& dt1, const TensorN<Cmpt,length>& t2) operator/(const DiagTensorN<Cmpt, length>& dt1, const TensorN<Cmpt, length>& t2)
{ {
return dt1 & inv(t2); return dt1 & inv(t2);
} }
@ -717,8 +717,8 @@ operator/(const DiagTensorN<Cmpt,length>& dt1, const TensorN<Cmpt,length>& t2)
//- Inner Product of a TensorN and an inverse DiagTensorN //- Inner Product of a TensorN and an inverse DiagTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator/(const TensorN<Cmpt,length>& t1, const DiagTensorN<Cmpt,length>& dt2) operator/(const TensorN<Cmpt, length>& t1, const DiagTensorN<Cmpt, length>& dt2)
{ {
return t1 & inv(dt2); return t1 & inv(dt2);
} }
@ -726,11 +726,11 @@ operator/(const TensorN<Cmpt,length>& t1, const DiagTensorN<Cmpt,length>& dt2)
//- Inner Product of a SphericalTensorN and an inverse TensorN //- Inner Product of a SphericalTensorN and an inverse TensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator/ operator/
( (
const SphericalTensorN<Cmpt,length>& st1, const SphericalTensorN<Cmpt, length>& st1,
const TensorN<Cmpt,length>& t2 const TensorN<Cmpt, length>& t2
) )
{ {
return st1.v_[0] * inv(t2); return st1.v_[0] * inv(t2);
@ -739,11 +739,11 @@ operator/
//- Inner Product of a TensorN and an inverse SphericalTensorN //- Inner Product of a TensorN and an inverse SphericalTensorN
template <class Cmpt, int length> template <class Cmpt, int length>
inline TensorN<Cmpt,length> inline TensorN<Cmpt, length>
operator/ operator/
( (
const TensorN<Cmpt,length>& t1, const TensorN<Cmpt, length>& t1,
const SphericalTensorN<Cmpt,length>& st2 const SphericalTensorN<Cmpt, length>& st2
) )
{ {
TensorN<Cmpt, length> result; TensorN<Cmpt, length> result;

View file

@ -40,15 +40,15 @@ Author
#define UNARY_TEMPLATE_FUNCTION(ReturnType, Type, Func) \ #define UNARY_TEMPLATE_FUNCTION(ReturnType, Type, Func) \
template<class Cmpt, int length> \ template<class Cmpt, int length> \
inline void Func(ReturnType<Cmpt,length>&, const Type<Cmpt,length>&); inline void Func(ReturnType<Cmpt, length>&, const Type<Cmpt, length>&);
#define UNARY_TEMPLATE_FUNCTION_VS(ReturnType, Func) \ #define UNARY_TEMPLATE_FUNCTION_VS(ReturnType, Func) \
template<class Cmpt, int length> \ template<class Cmpt, int length> \
inline void Func(ReturnType<Cmpt,length>&, const Cmpt&); inline void Func(ReturnType<Cmpt, length>&, const Cmpt&);
#define UNARY_TEMPLATE_FUNCTION_SV(Type, Func) \ #define UNARY_TEMPLATE_FUNCTION_SV(Type, Func) \
template<class Cmpt, int length> \ template<class Cmpt, int length> \
inline void Func(Cmpt&, const Type<Cmpt,length>&); inline void Func(Cmpt&, const Type<Cmpt, length>&);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //